Clip Planes with the programmable pipeline

Started by
10 comments, last by Armadon 17 years, 9 months ago
So, I'm trying to use clip planes with the programmable pipeline. I'm aware of needing to have the plane in "clipping space (the same space as output vertices)", though I'm not too sure what that means. I've reduced my code (C#) to this:

            Plane pl = Plane.FromPointNormal(new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f, 1.0f, 0.0f));
            m_Device.ClipPlanes[0].Enabled = true;

            m_Device.ClipPlanes[0].Plane = pl;

            m_Ship.Draw(); // Draw an object with the FFP (ID3DXMesh).

            m_Device.ClipPlanes[0].Plane = Plane.Transform(pl, m_Device.Transform.View * m_Device.Transform.Projection);

            m_Renderer.DrawTree(m_Tree); // Draw the terrain with a VS + PS.

For the first item, an ID3DXMesh, the plane works as expected, cutting anything with a Y of over 0.0f. For the terrain however, it seems to produce a plane that isn't in the correct orientation, and seems to move with the camera, instead of "staying in one place". I've tried transforming the plane myself with several combinations of Transform, TransformCoord, and TransformNormal, with no luck. Also, I doubt Plane.Transform isn't implemented well. Frankly, I'm baffled. I've heard/read some chatter about SetClipPlanes not playing well with the programmable pipeline on NVidia FX cards. I'm on a 7600, so I'm not sure if that would fall in that category, but even still, am I unable to use clip planes? I always have the option of just using texkill in the PS, but that seems like a workaround to me, not a solution. Anyone have any experiences with this kind of stuff? Thanks for reading :).
Sirob Yes.» - status: Work-O-Rama.
Advertisement
It's not really a good answer to your specific question, but I found that using clip() in a PS was sufficient for my clipping needs and very simple to implement. You can pass out a "clip distance" from the VS - because the VS controls coordinate frames its a whole lot easier than messing around with the traditional method. I was clipping to a Y=0 plane (water level) and outputted the Y coordinate as a single float TEXCOORD and clip()'d on that.

Performance was fine for my usage, but I've got a feeling that such methods aren't optimal - clip() resolves to a texkill which, iirc, has implications for the depth buffer and other optimizations...

hth
Jack

<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

clip/texkill also happen AFTER the pixel shader has run. If you have expensive light operations, it'd be nice to skip them entirely. Sadly, I have no idea about using user clip planes in a shader either... it's not something I've had time to play with yet.
What is a clip plane? I looked at the IDirect3DDevice9 methods for it in the DX 9 SDK for non-managed C++ code, and naturally there is no explanation. Is it meant add an additional plane within the camera's frustum set with the projection matrix?

Thanks.
--------------------------Most of what I know came from Frank D. Luna's DirectX books
Quote:Original post by Namethatnobodyelsetook
clip/texkill also happen AFTER the pixel shader has run. If you have expensive light operations, it'd be nice to skip them entirely.


Yes, I've been looking to avoid the texkill solution, though I guess I should be happy this will be running on a "light" pixel shader ;).

I'll wait a couple more days on this, then maybe try DirectXDev. Thanks for the help [smile].

DXnut,

Clip planes are usually refered to as User Clip Planes. Look up IDirect3DDevice9::SetClipPlane if you need more info.
Sirob Yes.» - status: Work-O-Rama.
As I already said, I did look it up in the SDK, and it doesn't explain how it is used.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/IDirect3DDevice9__SetClipPlane.asp


Did I miss something?

Thanks.
--------------------------Most of what I know came from Frank D. Luna's DirectX books
Quote:
A point with homogeneous coordinates (x, y, z, w) is visible in the half space of the plane if Ax + By + Cz + Dw >= 0. Points that exist behind the clipping plane are clipped from the scene.


It adds a plane the anything behind it gets clipped. This is useful for water reflections, for example, when you want to clip anything above the water plane when you're drawing the reflection or refraction.

Hope that makes it clearer :).
Sirob Yes.» - status: Work-O-Rama.
Thank you sir! I thought so. So it works like one of the frustum planes (created in the projection matrix) that get used for clipping geometry outside of it.
--------------------------Most of what I know came from Frank D. Luna's DirectX books
DONT use clip() in the pixel shader! Like Namethatnobodyelsetook said, the pixel is discarded after being computed. All NV cards since geforce FX have done clip planes at the geometry level, in hardware. To transform a world space plane into clip space I do this:

//normalize the plane which is required for the transforms	D3DXPLANE tempPlane = worldSpacePlane;	D3DXPLANE viewSpacePlane;	D3DXPlaneNormalize(&tempPlane, &tempPlane);	//transform the plane into view space	D3DXMATRIX  tempMatrix = dxAppSettings.matView;	D3DXMatrixInverse(&tempMatrix, NULL, &tempMatrix);	D3DXMatrixTranspose(&tempMatrix, &tempMatrix);	D3DXPlaneTransform(&viewSpacePlane, &tempPlane, &tempMatrix);	//transform the plane into clip space, or post projection space	tempMatrix = dxAppSettings.matProj;	D3DXMatrixInverse(&tempMatrix, NULL, &tempMatrix);	D3DXMatrixTranspose(&tempMatrix, &tempMatrix);	D3DXPlaneTransform(&clipSpacePlane, &viewSpacePlane, &tempMatrix);
Oh my. That was it, I was missing the inverse transpose on my matrices. I don't really like Plane.Transform, any more.

At any rate - I've added the inverse transpose - and instant bliss. I can't thank you enough for pointing that out. I'd rate you up, but I've already done that :).
Sirob Yes.» - status: Work-O-Rama.

This topic is closed to new replies.

Advertisement