• 10
• 12
• 12
• 14
• 17

# Normals for water simulation

This topic is 4876 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi i was just wondering what would be the best way to calculate the normals for the water reflections......best and most economical way in matter of calculations as i want my simulation to run real-time... right now i was just calculating the normal for each faces but that doesn't give a really smooth surface... any ideas??

##### Share on other sites
well while im at it...
i also have trouble getting my projection to work with shaders
now i've been able to have it work without shaders by supplying the coords to my vertex, but when i try with my shaders it just won't happen...im pretty sure my shaders are alright but.....then again it still doesn't work :(

// FRAGMENT SHADERuniform sampler2D myTexture;void main (void){  gl_FragColor  = texture2DProj(myTexture, gl_TexCoord[0]);         }// VERTEX SHADERuniform mat4 Mprojtex;void main(void){ gl_Position = ftransform(); gl_TexCoord[0] = Mprojtex * ftransform();}// Here is my main program where i start the shader and send it the projection matrix i calculated:float Mr[16] = { 	0.5, 0, 0, 0,	0, 0.5, 0, 0,	0, 0, 0.5, 0,	0.5, 0.5, 0.5, 1 };	float Mprojtex[16], Model[16], MProj[16];	glGetFloatv(GL_MODELVIEW_MATRIX, Model);	glGetFloatv(GL_PROJECTION_MATRIX, MProj);	glMatrixMode(GL_PROJECTION);	glPushMatrix();        glLoadMatrixf(Mr);        glMultMatrixf(MProj);	glMultMatrixf(Model);	glGetFloatv(GL_PROJECTION_MATRIX, Mprojtex);	glPopMatrix();	glMatrixMode(GL_TEXTURE);	glLoadMatrixf(Mprojtex);	glMatrixMode(GL_MODELVIEW);	glUseProgramObjectARB(ShaderObject);	GLint texLoc   = glGetUniformLocationARB(ShaderObject, "myTexture");	glUniform1iARB(texLoc, 0);	GLint MprojLoc = glGetUniformLocationARB(ShaderObject, "Mprojtex");	glUniformMatrix4fvARB(MprojLoc,16,0,Mprojtex);	glBindTexture(GL_TEXTURE_2D, render_texture);	glEnable(GL_TEXTURE_2D);	int t=0;	for(int x=0; x<m-2; x++)	{		glBegin(GL_TRIANGLE_STRIP);		{			for(int y=0; y<n-1; y++)		{			vert[t%3].x = x;			vert[t%3].y = y;			vert[t%3].z = Height[x+y*(m-1)];			t++;			norm =	getnormal(vert[1], vert[0], vert[2]);			glNormal3f(norm.x, norm.y, 1); 		//	glTexCoord3f(x, y, Height[x+y*(m-1)]);			glVertex3f(x, y, Height[x+y*(m-1)]);						vert[t%3].x = x+1;			vert[t%3].y = y;			vert[t%3].z = Height[x+1+y*(m-1)];			t++;						norm =	getnormal(vert[1], vert[0], vert[2]);			glNormal3f(norm.x, norm.y, 1); 					//	glTexCoord3f(x+1, y, Height[x+1+y*(m-1)]);			glVertex3f(x+1, y, Height[x+1+y*(m-1)]);			}				glEnd();				}		t=0;	}	glUseProgramObjectARB(0);  	glDisable(GL_TEXTURE_2D);

PLEASE let me know if you see anything wrong as i've pretty much tried anything i could think of :/
also ignore the glNormal3f as like my first question i am not sure yet how im gonna calculate them..
tks

Oh and, like i said before im pretty sure i calculate the MProjtex matrix right cause if i try it without the shaders, it works fine...

##### Share on other sites
For calculating normals, you might find this thread useful.

##### Share on other sites
tks a lot!!
the technique used there seems to be a good compromise of speed and accuracy

now i just need to find out how to make my shaders work properly...

##### Share on other sites
your vertex program is wrong [smile]

- No need to supply a uniform to it, just use the texture matrix you already setup
- ftransform() performs the calculation gl_ModelViewMatrix * gl_Vertex, so the 2nd time you use it is wrong as you are multiplying the product of that by the matrix used to setup the projective lookup, so god knows where you end up [grin]

The shader is very simple (without lighting or any other effects, just working out the projection)
void main(void){ gl_Position = ftransform(); gl_TexCoord[0] = gl_TextureMatrix[0] * gl_Vertex;}

Also, I wouldnt do the texture matrix setup in the projection matrix, it just confuses things.

Instead change it so that the code is
float Mprojtex[16], Model[16], MProj[16];glGetFloatv(GL_MODELVIEW_MATRIX, Model);glGetFloatv(GL_PROJECTION_MATRIX, MProj);glMatrixMode(GL_TEXTURE);glLoadMatrixf(Mr);glMultMatrixf(MProj);glMultMatrixf(Model);glMatrixMode(GL_MODELVIEW);

so it makes it clear what you are doing to the matrix and that code is alot more compact compared to what you were doing [smile]

##### Share on other sites
OK
i have to say im kinda angry at you
cause it WORKED THE FIRST TIME i tried your code!!!
gggrrrr..........i spent so much time on this...actually im pretty sure at one point i also tried something like

void main(void)
{
gl_Position = ftransform();
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_Vertex;
}

except instead of gl_TextureMatrix[0] i had the matrix Mprojtex which i had sent through a uniform variable....
anyway...it works now so i guess i won't mess with it!

one thing tho, it projects the reflection alright but i don't see my water plane anymore? it became white or something, could that be because i don't take into account the lighting in my shaders or something? cause when i was doing it without shaders i could still see my water plane...
if not its probably something else in my code i guess

##### Share on other sites
Quote:
 Original post by tasseloffOKi have to say im kinda angry at youcause it WORKED THE FIRST TIME i tried your code!!!gggrrrr..........i spent so much time on this...

thats coz its basically what my code is, so i knew it would work [grin]

Quote:
 one thing tho, it projects the reflection alright but i don't see my water plane anymore? it became white or something, could that be because i don't take into account the lighting in my shaders or something? cause when i was doing it without shaders i could still see my water plane...if not its probably something else in my code i guess

post a screen shot (before and after is possible) so I can see whats going on, its hard to guess from that description.

##### Share on other sites
yup ok ill post a screenshot...
first tho, like i said before, i HAD tried with something similar and i tried again just to see and it DOESN'T work....id really like to know why tho...here it is:

uniform mat4 Mprojtex;void main(void){ gl_Position = ftransform();// just changed gl_TextureMatrix[0] to MProjtex as you can see...// gl_TexCoord[0] = gl_TextureMatrix[0] * gl_Vertex; gl_TexCoord[0] = Mprojtex* gl_Vertex;}instead ofvoid main(void){ gl_Position = ftransform(); gl_TexCoord[0] = gl_TextureMatrix[0] * gl_Vertex;}

if Mprojtex contains the same as the texture it should work no??
maybe im just not sending the variable right i dunno, i just don't get it.....as you can i just added a glGetFLoatfv to your code to get the content of the texture matrix and then send it to the shader:
float Mprojtex[16], Model[16], MProj[16];glGetFloatv(GL_MODELVIEW_MATRIX, Model);glGetFloatv(GL_PROJECTION_MATRIX, MProj);glMatrixMode(GL_TEXTURE);glLoadMatrixf(Mr);glMultMatrixf(MProj);glMultMatrixf(Model);glGetFloatv(GL_TEXTURE_MATRIX, Mprojtex);glMatrixMode(GL_MODELVIEW);	glUseProgramObjectARB(ShaderObject);	GLint texLoc   = glGetUniformLocationARB(ShaderObject, "myTexture");	glUniform1iARB(texLoc, 0);	GLint MprojLoc = glGetUniformLocationARB(ShaderObject, "Mprojtex");	glUniformMatrix4fvARB(MprojLoc,16,0,Mprojtex);

i really don't see what could be wrong, but it has to do with how i send the matrix i guess!! since it doesn'T seem to be sent right or else it would work...:/

as for the screenshot here is before the projection:
BEFORE
http://pallots.kicks-ass.net/planarreflect/ref_before.jpg
AFTER
http://pallots.kicks-ass.net/planarreflect/ref_after.jpg

and this is how it should look...and how it looks when i do the projection without the shaders:

not sure how come my water plane disappears...
(also, how in hell do you post a picture on here?? had to put them on my server...)
sorry for the long post, tks in advance

nm