Skip to main content
GameDev.net gamedev.net
🔒 Locked

GL_CLIP_PLANE's and Nvidia hardware

Started by MARS_999 Jul 26, 2005 at 9:28 PM 8 replies 3.5k views
Original Post
MARS_999
MARS_999
I have had an ATI card and currently a 6800GT. I am using GL_CLIP_PLANE0 to do my water rendering for reflections. I have an issue with my 6800GT not rendering my water correctly as my water reflections show up as blackend water areas... I have read online that Nvidia doesn't support GL_CLIP_PLANEs very well or at all... I know ATI does due to I have ran this code on a 9600XT and looked sweet. So I am looking for some help on if this is true or not, and what can I do to fix this problem... I would like to be able to code my water once and run on all cards, but seems like thats not possible with GL_CLIP_PLANE0 usage? Also is their any other way besides clip planes to render water besides stencil buffer methods due to they eat up CPU cycles correct? Thanks
JavaCoolDude
JavaCoolDude
Rather than using an expensive user clip plane defined by GL_CLIP_PLANEn, try setting up your near clip to do the job for you via a special frustum transform; it could only make things run a bit faster with minimal code change.

Here's a direct link to a sample demo showing how to set it up correctly.
Enjoy
PS: You can view the rest of the samples on this page.
Eric Lengyel
Eric Lengyel
Do not use the Nvidia sample code to modify your projection matrix. Although it does correctly move the near plane to coincide with an arbitrary clipping plane, it fails to consider the (very unintuitive) effect on the far plane and the related effect on depth buffer precision. The code at the following link is much better, and provides the provably optimal projection matrix for any given clipping plane.

http://www.terathon.com/code/oblique.html

If you have Game Programming Gems 5, this technique is discussed in Section 2.6. Some more details about the effect on depth buffer precision are discussed in the Journal of Game Development, Vol. 1, No. 2.

-- Eric Lengyel
MARS_999
MARS_999
Quote:
Original post by Eric Lengyel
Do not use the Nvidia sample code to modify your projection matrix. Although it does correctly move the near plane to coincide with an arbitrary clipping plane, it fails to consider the (very unintuitive) effect on the far plane and the related effect on depth buffer precision. The code at the following link is much better, and provides the provably optimal projection matrix for any given clipping plane.

http://www.terathon.com/code/oblique.html

If you have Game Programming Gems 5, this technique is discussed in Section 2.6. Some more details about the effect on depth buffer precision are discussed in the Journal of Game Development, Vol. 1, No. 2.

-- Eric Lengyel


Hi Eric, here is my code for the clip planes, I am not doing anything with the matrix's, and on ATI hardware it works fine...

void CTerrain::RenderRefractionAndDepth(float move_y){	draw_water = false;	const double plane[4] = {0.0f, -1.0f, 0.0f, 0.0f}; 	glViewport(0, 0, WATER_TEXTURE_SIZE, WATER_TEXTURE_SIZE);    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	glLoadIdentity();	g_Camera.LookAt(); 	glPushMatrix();	glTranslatef(0.0f, -move_y - WATER_HEIGHT - .1f, 0.0f);    glEnable(GL_CLIP_PLANE0);    glClipPlane(GL_CLIP_PLANE0, plane);	DrawTerrainVBO(0.0f, true);	    glDisable(GL_CLIP_PLANE0);	glPopMatrix();    glBindTexture(GL_TEXTURE_2D, textureObjectWater[WATER_REFRACTION]);	glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, WATER_TEXTURE_SIZE, WATER_TEXTURE_SIZE, 0);       //render depth to texture    glBindTexture(GL_TEXTURE_2D, textureObjectWater[WATER_DEPTHMAP]);    glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 0, 0, WATER_TEXTURE_SIZE, WATER_TEXTURE_SIZE, 0);	draw_water = true;}void CTerrain::RenderReflection(float move_y){	draw_water = false;	const double plane[4] = {0.0f, 1.0f, 0.0f, 0.0f};    glViewport(0, 0, WATER_TEXTURE_SIZE, WATER_TEXTURE_SIZE);    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    glLoadIdentity();	   	g_Camera.LookAt();		glPushMatrix();	glTranslatef(0.0f, -move_y + WATER_HEIGHT + .1f, 0.0f);	glScalef(1.0, -1.0, 1.0);    glEnable(GL_CLIP_PLANE0);    glClipPlane(GL_CLIP_PLANE0, plane);    		DrawTerrainVBO(0.0f, true);	model.Draw(shift_model_x, shift_model_y, shift_model_z);	model.Draw((MAP_X * .5f * TERRAIN_SCALE_FACTOR), 1.5f, (MAP_Z * .5f * TERRAIN_SCALE_FACTOR - 6.0f));	g_Load3ds.Draw(g_3DModel[0], &g_Texture[0], (MAP_X * TERRAIN_SCALE_FACTOR), 0.375f, (MAP_Z * TERRAIN_SCALE_FACTOR), .001f);    g_Load3ds.Draw(g_3DModel[1], &g_Texture[0], (MAP_X * .5f * TERRAIN_SCALE_FACTOR - 6.0f), .2f, (MAP_Z * .5f * TERRAIN_SCALE_FACTOR), .001f);    g_Load3ds.Draw(g_3DModel[2], &g_Texture[0], (MAP_X * .5f * TERRAIN_SCALE_FACTOR), .25f, (MAP_Z * .5f * TERRAIN_SCALE_FACTOR - 2.5f), .001f);	g_Load3ds.Draw(g_3DModel[3], &g_Texture[1], (MAP_X * .5f * TERRAIN_SCALE_FACTOR - 1.0f), .2f, (MAP_Z * .5f * TERRAIN_SCALE_FACTOR - 5.25f), .003f);	    glDisable(GL_CLIP_PLANE0);	glPopMatrix();    glBindTexture(GL_TEXTURE_2D, textureObjectWater[WATER_REFLECTION]);	glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, WATER_TEXTURE_SIZE, WATER_TEXTURE_SIZE, 0);	draw_water = true;}

MARS_999
MARS_999
Quote:
Original post by Eric Lengyel
Are you using vertex programs?


Yes, and I will be switching to GLSL, but for now I would like to fix the issue with vertex programs...
MARS_999
MARS_999
Quote:
Original post by Eric Lengyel
On Nvidia hardware, you need to write a clip distance to result.clip[0] in your vertex program in addition to enabling the clip plane. You'll need to specify the option NV_vertex_program2 to use this.


Thanks for the help!

Here is what I got.

In my VP I have this

PARAM clipDist = program.env[4];MOV result.clip[0], clipDist;


and in my main program
static float clipDist[4] = {11.7f};//I am just placing numbers in here to see if anything changes for now...glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, 4, clipDist);


And nothing has changed and I do have the

OPTION NV_vertex_program2; on

do I need this also??

OPTION ARB_position_invariant;

Thanks
Eric Lengyel
Eric Lengyel
You don't have to use ARB_position_invariant to get the clipping planes.

Since you're always passing a positive number through to the clip distance, it will never clip. You should pass in an object-space plane and do this:

DP4 result.clip[0], vertex.position, program.env[4];

MARS_999
MARS_999
Quote:
Original post by Eric Lengyel
You don't have to use ARB_position_invariant to get the clipping planes.

Since you're always passing a positive number through to the clip distance, it will never clip. You should pass in an object-space plane and do this:

DP4 result.clip[0], vertex.position, program.env[4];


Hmmm. No luck Eric. I sent you a PM... I added the DP4 and changed my env variable to a negative value and no luck. Read my PM and see what you think if I am on the right track with the specular lighting?? It would help to see screenshots...

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.