Shader Problem

Started by AGP, January 22, 2014, 04:58:53 PM

Previous topic - Next topic

EgonOlsen

Yes. The shader completely replaces the z value of the vertex. I would try something like this instead:


vec4 pos = gl_Vertex;
pos.z += waveHeight * ((height + height2) / 2.0);
   
gl_Position = gl_ModelViewProjectionMatrix * pos;

AGP

It works, thank you very much. The result is a little weird, though. You know I actually had tried the += intead of the the =. The difference is that I hadn't replaced the * pos.xzyw with * pos. Is the fact that this worked and not *posxzyw the difference in jpct's and OpenGL's orientation?

EgonOlsen

Then i've solved this by accident... ;) I actually haven't noticed that it wasn't xyzw but xzyw...i just removed it, because i though it was xyzw and saw no point in that. However, i still see no point in using xzyw...it effectively rotates the object 90° around x without using the rotation matrix for this. This shouldn't be done IMHO because it's nothing but confusing. Looks more like a hack to me. jPCT's coordinate system doesn't matter in a shader. In a shader, only OpenGL's system exist, so no...this has nothing to do with it.

AGP

In yet another shader question (honestly, you're the best guy I know for these): how do I rotate the effects of a shader by a camera? I have a simple lake water shader that I've part copied, part written myself, which makes for a very convincing lake if you don't turn the camera. How do I rotate everything along with the camera? Below is the fragment shader (which is the whole thing, really):


uniform float iGlobalTime;
uniform vec3 iResolution;
uniform sampler2D iChannel0;
uniform sampler2D iChannel1;
uniform sampler2D iChannel2;
uniform sampler2D iChannel3;

#ifdef GL_ES
precision highp float;
#endif

const float PI = 3.1415926535897932;

// play with these parameters to customize the effect
// ===================================================

//speed
const float speed = 0.1;
const float speed_x = -0.1;//.15
const float speed_y = -0.1;//.15

// refraction
const float emboss = 0.50;//.5
const float intensity = .5;//2.4
const int steps = 8;
const float frequency = 6.0;
const int angle = 7; // better when a prime

// reflection
const float delta = 60.;//60
const float intence = 700.;//700

const float reflectionCutOff = 0.012;
const float reflectionIntence = 200000.;

// ===================================================

float time = iGlobalTime*1.3;

  float col(vec2 coord) {
    float delta_theta = 2.0 * PI / float(angle);
    float col = 0.0;
    float theta = 0.0;
    for (int i = 0; i < steps; i++) {
      vec2 adjc = coord;
      theta = delta_theta*float(i);
      adjc.x += cos(theta)*time*speed + time * speed_x;
      adjc.y -= sin(theta)*time*speed - time * speed_y;
      col = col + cos( (adjc.x*cos(theta) - adjc.y*sin(theta))*frequency)*intensity;
    }

    return cos(col);
  }

void main(void) {
     vec2 p = (gl_FragCoord.xy) / iResolution.xy, c1 = p, c2 = p;
     float cc1 = col(c1);

     c2.x += iResolution.x/delta;
     float dx = emboss*(cc1-col(c2))/delta;

     c2.x = p.x;
     c2.y += iResolution.y/delta;
     float dy = emboss*(cc1-col(c2))/delta;

     c1.x += dx*2.;
     c1.y = -(c1.y+dy*2.);

     float alpha = 1.+dot(dx,dy)*intence;

     float ddx = dx - reflectionCutOff;
     float ddy = dy - reflectionCutOff;
     if (ddx > 0. && ddy > 0.)
alpha = pow(alpha, ddx*ddy*reflectionIntence);

     vec4 col = texture2D(iChannel0,c1)*(alpha);
     vec4 col2 = texture2D(iChannel1,c1)*(alpha);
     vec4 col3 = mix(col, col2, .4);
     gl_FragColor = col3;
}

EgonOlsen

Rotations happen in the vertex shader, not in the fragment shader. In desktop OpenGL, all you have to do is something like


gl_Position = ftransform();

AGP

What does "Negate z and y of the position and add 1 as the fourth component" mean? Do I switch z and y or do I just multiply them by -1 and make a vec4 with vc4(x, -y, -z, 1)? I'm trying out yet another shader...

EgonOlsen

Quote from: AGP on February 20, 2014, 05:38:12 AM
...or do I just multiply them by -1 and make a vec4 with vc4(x, -y, -z, 1)?
Yes, that!

AGP

Cool.

Is there a way for me to pass an Object3D to the shader? I would like for my ocean (which is now looking pretty good, in my opinion) to move a boat...

EgonOlsen

Quote from: AGP on February 22, 2014, 11:34:40 PM
Is there a way for me to pass an Object3D to the shader? I would like for my ocean (which is now looking pretty good, in my opinion) to move a boat...
No. How should that be possible? A shader is a program that works on the geometry of an object. If you want a boat on the ocean, that's simply another object.

AGP

#54
Shaders render and move other objects: look for the buoy shader in ShaderToy for an example (in that case, an object that was created inside the very shader).

Here's a question: how expensive is it to get all the ocean vertices under the boat every frame (outside of the shader)? I'm thinking about just rotating the boat by the largest slope within the area of the boat (and doing this, obviously, for every frame)...

EgonOlsen

You can write almost everything in a shader, but that's not the  point. Shaders work on vertices and fragments that you give to them one after the other. You can manipulate them in a way that they form new geometry, but you can't create additional geometry out of thin air. That's just not how a shader works. One vertex goes in and one goes out...there's no way around this.

For the second question: You can't do this. There's no reasonable way to access the data of the shader. That's why game play relevant physics are still done on the CPU. You somehow have to approximate this in code.

AGP

QuoteYou can write almost everything in a shader, but that's not the  point.

How's that not the point?

QuoteFor the second question: You can't do this. There's no reasonable way to access the data of the shader. That's why game play relevant physics are still done on the CPU. You somehow have to approximate this in code.

That's terrible. How does a game like Assassin's Creed 4 do it, then? Is its ocean not a shader?

EgonOlsen

Quote from: AGP on February 23, 2014, 08:58:46 PM
How's that not the point?
It's not, because it doesn't really help. People wrote Frogger in shader code, but even then...you can't break the basic rule how a shader fits into the pipeline and that is vertex in->vertex out and fragment in->fragment out. It's not vertex in-> 10 vertices out. That's simply not possible.

Quote
That's terrible. How does a game like Assassin's Creed 4 do it, then? Is its ocean not a shader?
By spending millions of dollars and dozens of people on the water simulation alone? Fact is: You can't access the modified vertices from the shader. However, if you know how your shader does things, you actually know where a wave is at a given time and you can do your calculations in code accordingly. Or you apply the same vertex manipulation that you are doing to the ocean to the boat...if that's feasible.

AGP

And those "millions of dollars" buy a solution, right?

QuoteHowever, if you know how your shader does things, you actually know where a wave is at a given time and you can do your calculations in code accordingly. Or you apply the same vertex manipulation that you are doing to the ocean to the boat...if that's feasible.

Then wouldn't it be better to just do the water entirely out of the shader? Why do the same calculations twice?

EgonOlsen

Quote from: AGP on February 23, 2014, 11:50:34 PM
And those "millions of dollars" buy a solution, right?
They buy time and people...i guess that's a good thing to come to a solution. Personally, i don't have one...just ideas what one could do. I'm not sure how well it will work or how much work it will be.

Quote from: AGP on February 23, 2014, 11:50:34 PM
Then wouldn't it be better to just do the water entirely out of the shader? Why do the same calculations twice?
Because it's much faster that way. I guess one would have a physics simulation of the ocean and the ships that controls the actual entities and that runs on the cpu and some shaders that add to the visuals. The tricky thing is to sync them.