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

Clip Planes usefull at all for water?

Started by JHL Jan 8, 2007 at 2:53 PM 11 replies 3k views
Original Post
JHL
JHL
Has any one used clip planes for their water in any modern system that uses vertex shaders? Up till now my water has been using the texkill instruction to clip the reflected and the below water scene. But its slow so I thought I would switch to clip planes now that support for them is more wide spread. I did some research and found you have to specify your clip planes in 'clip space' not sure exactly what that ment I did some tests and found its the space after the perspective divide. My understanding is this poses a really obnoxious problem because (as far as I can tell) a flat plane in world space is not a flat plane in clip space the perspective divid in fact curves it. This makes it impossible to clip something to a certain height. Any one know if I'm right about this? or has any advice on how this could work?
Nedelman
Nedelman
Yes, I've used clip planes with vertex shaders and they work very well.

Transforming your planes to "clip space" amounts to a transformation of the plane coefficients with your world/view/project matrices. I have a 3DS viewer, with source code, that you can find at http://www.threesixbox.com/project/?id=6c3eea10eb that uses clip planes for drawing planar reflections/refractions and would work just as well for water. Search around in the Scene.cs source file for the word "clip" to see how to transform your plane to clip space.
www.gameprojects.com - Share Your Games and Other Projects
JHL
JHL
That seems to use xna functions to transform the plane that doesn't tell me a whole lot.

But I was able to just take 3 points on the plane transform them into clip space and rebuild the plane from that and it seems to work although I'm not sure how exactly.
Schrompf
Schrompf
I stumbled over that problem some months ago, too. I didn't find a way to transform a plane and I didn't find the right words to ask google. There's a D3DX function that claims to transform a plane but unlike other functions this one does not provide background math. I ended up using Oblique Frustum Mapping which turns the near plane of your projection matrix into an (nearly) arbitrary clipping plane without any additional overhead. Nice technique, although numerical unstable if the view is close to the clipping plane.

If you find a way to transform a plane into clip space, please let me know. I was under the impression that a plane in world space is no plane in clip space anymore, but others do use clip planes together with Vertex Shaders quite successful so obviously I'm wrong. Doesn't help me much, though.

Bye, Thomas
----------
Gonna try that "Indie" stuff I keep hearing about. Let's start with Splatter.
zedzeek
zedzeek
clipplanes arent good for what u want (esp on nvidia hardware as can lead to depth fighting due to the diferent vertice calc path being taken when u enable them)
a better solution is presented by eric lengel where u (i forget the exact solution or a link to the code/math but a search should find it) IIRC u create a frustum view matrix where the nearclip plane is the plane u want to perform the clipping
JHL
JHL
The z buffer trick would have worked for some of what I wanted to do but not all of it. The my land scape is very dynamic I have parts of the water 'grid' this is not visable but can't be easly not rendered so I wanted to sink them below the visible water level and then clip them off with a clip plane.

I also found that dx plane tranform function but with out knowing what it did it didn't help me any I use a custom math library.

Mathematicly a world space plane doesn't equal a plane in clip space. That said though I've some how managed to make them work, at least so far. I'm using them to clip the reflections and the scene below the water (which I also render to texture) as well as the thing I mentioned at the top.

I simply took 3 points on the world space plane and simply transformed them in to clip space and then used those 3 points to create a plane in clip space. I think whats going on is under certain conditions the error between the two planes isn't noticable. What those conditions are I'm not exactly sure but a few things may or may not be involved. For one I'm making an rts so your normally looking down at the water not across the water. Second I render the map in square chunks of geometry (the view is normally about 2 1/2 chunks wide). And the 3 points I use are 3 corners of a chunk at the height of the water in that chunk. And I recalculate the plane for each chunk. I think this else helps to minimize the error.

Because of the way I render this theres no opertunity for z fighting really here either.
JHL
JHL
That doesn't make any sense to me the perspective divide squeezes things farther away closer together meaning that plane curves towards the clip space origin as it gets farther away from the origin in clip space.
Schrompf
Schrompf
That is true, but the clip planes in D3D have to be in post-divided space. I tried it once with a plane of (0, 1, 0, -0.5f). It clipped the lower quarter of the screen, just as if you unproject a screen space line into the scene and use this plane to clip. Looks to me as if the clip plane was indeed in post-division space.

And as far as I can tell, a plane in post-projection space is no plane anymore after the perspective divide. At least not all possible planes. Others do use arbitrary placed clip planes, though, so there must be some way.
----------
Gonna try that "Indie" stuff I keep hearing about. Let's start with Splatter.
Schrompf
Schrompf
Ok, sorry, my fault. After some experiments and some googling I found that the plane is specified in simple projection space (== clip space), BEFORE the perspective divide. So plane stays plane. My fault seemed to come from an inproperly specified plane distance so that it looked as if the planes goes through (0, 0, 0) for every plane I tried.

Here's what you do for a plane in view space:

// Base position and normal of the planeTVector planePos( 0, -3, 0), planeNormal( 0, 1, 0);// calculate plane TPlane plane = TPlane::fromPointNormal( planePos, planeNormal);// transform plane in clip space. First adapt projection matrixTMatrix4x4 projMatrix = yourCamera->GetProjectionMatrix();projMatrix.Invert();projMatrix.Transpose();// now transform by inverted transposed projection matrixplane = projMatrix * plane;// and throw it to D3DgD3DDevice->SetClipPlane( 0, plane.GetFloats());


Sorry again, that problem could have been solved by simple googling.

Bye, Thomas
----------
Gonna try that "Indie" stuff I keep hearing about. Let's start with Splatter.
JHL
JHL
I'm certain that the clip planes are post divide at least on my computer. orignally I assumed they had to be before that at first too to make sense. But I ran tests like with planes like (-1,0,0,D) where D grandually changed from 0.0 to 1.0 and half the screen gradually was cut off. I hope its not some kind of difference in hardware implimentations cause that makes these even less usefull. I have a geforce 6200.
Schrompf
Schrompf
I'm sure now that it's definitely not in post-division space. The mistake is by giving an exact plane normal such aus (1, 0, 0) in your case. If you take an (1, 0, 0) in view space and transform it by the projection matrix, you get something along the line of (0.8, 0, -0.1) as plane normal, which then suits its purpose very well.

Try it. Works flawlessly for me. [edit] on a GF7800. Same tech, that means.

Bye, Thomas
----------
Gonna try that "Indie" stuff I keep hearing about. Let's start with Splatter.

Topic Locked

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

Sign in to reply to this topic.