Reflection Mapping and OpenGL's ModelView matrix problem

Started by
2 comments, last by aryx 14 years, 1 month ago
I'm having a slight problem with getting reflection/environment mapping working, everything seems to work ok until I start moving the camera around the reflection does not follow with it, this is because I am using an 'eye-space' reflection vector to index a 'world-space' cube-map. here is the glsl code: vertex shader:

	varying vec3 reflectVec;
	void main()
	{
		vec3 normal = normalize(gl_NormalMatrix * gl_Normal);
		gl_Position = ftransform();
		reflectVec = reflect(vec3(gl_ModelViewMatrix * gl_Vertex), normal);
	}

fragment shader:

	uniform samplerCube tex;
	varying vec3 reflectVec;
	void main()
	{
		gl_FragColor = textureCube( tex, normalize(reflectVec) );
	}

Is there anyway to convert the reflection vector back into world space without it going through the Model matrix but just rather by the inverse of the View matrix so that it can access the cube map?
Advertisement
Do you have the eye position of your camera? If yes, then I would have a uniform that stores that position and then do the following in my vertex shader:

gl_Position = ftransform();reflectVec = reflect(gl_Vertex.xyz - eyePosition, gl_Normal);

Note that here I'm assuming the model itself has no "local" transformations, and that the verticies/normals going into the vertex shader are already in world space. If there are transformations local to take the model into world space, you'll need to have uniforms for those.

I think this approach will be simpler, but if you really want to play around in view space, getting back to world space would require you to use the inverse (possibly transpose) of the top-left 3x3 submatrix of the "world -> view" matrix. Again, if there are no transformations taking the model into world space, this will simply be the inverse of gl_NormalMatrix. If you need a little more clarification, just let me know!

Disclaimer: I've never implemented this before ;P

[Edited by - aryx on March 9, 2010 11:18:31 AM]
Quote:
Note that here I'm assuming the model itself has no "local" transformations


thats exactly the problem, because opengl treats the view and model matrix as one I can't simply transform the vertices and normals into world space without also transforming them into view space.

I think the fastest method would be to store a separate world matrix as a uniform in the shader but how would I be able to get the world matrix while still making calls to glRotatef and glTranslatef, would I be better to wrap these into other functions e.g.

_glRotatef(float angle, float x, float y, float z){   glPushMatrix();   glLoadMatrix(&g_WorldMatrix);   glRotatef(angle, x, y, z);   glGetFloatfv(GL_MODELVIEW_MATRIX, &g_WorldMatrix);   glPopMatrix();   glRotatef(angle, x, y, z);}


or is there a simpler way I am overlooking?

[Edited by - staticVoid2 on March 9, 2010 1:02:26 PM]
My apologies for not replying sooner, but an old friend dropped by for a visit. One possible approach is the way you've shown. The only thing I would do differently is to fetch the matrix after it's fully constructed instead of every time I make a rotate/translate/scale call.

Another approach would be to have your own matrix manipulation code. The fixed-function stuff is all labeled as deprecated in the OpenGL 3 specs (but they'll still function for quite some time). If you're not doing anything too complicated then you'll probably only need some rotate/scale/translate functionality along with matrix multiplication. With this approach you'll be more prepared to switch to OpenGL 3 (e.g., glLoadMatrix will simply be replaced by a call to set some matrix uniforms in your shaders). This way you can separate the model transformations and view transformations yourself by keeping track of them separately.

This topic is closed to new replies.

Advertisement