Normals for water simulation

Started by
16 comments, last by tasseloff 19 years, 4 months ago
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??
Advertisement
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...
For calculating normals, you might find this thread useful.
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...
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]
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
Quote:Original post by tasseloff
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...


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.
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:
http://pallots.kicks-ass.net/planarreflect/ref_withoutshader.jpg

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
i'm guesing the lack of plane is due to you not working out the lighting as happens down the fixed function pipeline.

As to why your other shader doesnt work, I dont know, your right in that it should work and there is probably a good reason why it doesnt however atm i cant see it

This topic is closed to new replies.

Advertisement