Sign in to follow this  

Oblique Frustum Clipping

This topic is 4194 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi Iam using Eric Lengyels code for Oblique Frustum Culling ( http://www.terathon.com/code/oblique.php ). The above mentioned code works fine for OpenGL. Unfortunately, equivalent doesnt work for Direct X. Though Iam using exactly the same View/Projection Matrices for both: Projection Matrix is equivalent to the one generated by gluPerspective ( Equation see here: http://pyopengl.sourceforge.net/documentation/manual/gluPerspective.3G.html ) Modelview Matrix is equivalent to the one generated by gluLookAt ( http://pyopengl.sourceforge.net/documentation/manual/gluLookAt.3G.html ). Apart from the Oblique Frustum Problem, it renders correctly. As Iam unsure about the math behind the Oblique Frustum Equations etc, Iam not sure why it shouldnt work for Direct X even though everything else renders fine. Any ideas? Thanks alot in advance Edit: To be more precise: Instead of being basically on my water plane, the plane is cutting my reflected world apart. The Clipplane Iam using is computed by computing 3 points on the water plane, converting them to View Space and making a plane of them.

Share this post


Link to post
Share on other sites
Can't comment on the particular algorithm in question, but in general, view and projection matrices are constructed differently in OpenGL and DirectX; if you use the wrong form, the results will most likely be incorrect.

Although the two APIs use different vector conventions, the matrices are actually arranged in memory the same way, so that shouldn't be a problem. The two differences that may matter though are:

- OpenGL view and projection matrices are right-handed by default; DirectX offers functions for either handedness

- OpenGL uses a z-clipping range of [-1,1], while DirectX uses a z-clipping range of [0,1]

If you go here, you should be able to find the form for constructing DirectX-style projection matrices (click on 'Math Functions', on the left).

Share this post


Link to post
Share on other sites
Quote:
Original post by jyk
- OpenGL uses a z-clipping range of [-1,1], while DirectX uses a z-clipping range of [0,1]

Mh i read that as well.
But as I said everything renders correctly, and near/far clipping planes are working as well. Since my matrix is originally from GL, it should map to [-1,1] zrange. If DX used only [0,1] half of the Scene should be missing - thats not the case though. I just tested the same with the formulas that D3DXMatrixPerspectiveFovRH is using ( http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/d3dxmatrixperspectiverh.asp ), and I got the same result ( at least I didnt notice any differences... ).

Maybe some part of the oblique frustum culling algorithm specific to some GL behaviour?

Btw: I did find some dx and gl samples for the algorithm on the Nvidias developer page, but they had completely different code in both samples so I couldnt really compare differences.

Share this post


Link to post
Share on other sites
Quote:
Original post by Dtag
Quote:
Original post by jyk
- OpenGL uses a z-clipping range of [-1,1], while DirectX uses a z-clipping range of [0,1]

Mh i read that as well.
But as I said everything renders correctly, and near/far clipping planes are working as well. Since my matrix is originally from GL, it should map to [-1,1] zrange. If DX used only [0,1] half of the Scene should be missing - thats not the case though. I just tested the same with the formulas that D3DXMatrixPerspectiveFovRH is using ( http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/d3dxmatrixperspectiverh.asp ), and I got the same result ( at least I didnt notice any differences... ).

Maybe some part of the oblique frustum culling algorithm specific to some GL behaviour?

Btw: I did find some dx and gl samples for the algorithm on the Nvidias developer page, but they had completely different code in both samples so I couldnt really compare differences.
If Eric happens to see this I'm sure he can answer your questions. Meahwhile though, just from glancing at Eric's code it looks there could be some aspects of the code itself that are dependent on OpenGL clipping range and/or handedness; that is, applying it as is to a DirectX-style matrix might not work. Also, since z-mapping is non-linear, I wouldn't necessarily expect that using the wrong clipping range would result in 'half' of the scene missing. In short, I think it may be that in addition to using the correct matrix, it may be necessary to write a 'DirectX' version of the ModifyProjectionMatrix() function. (Note that this is just a guess! I don't have access to the article explaining the algorithm, and only took a quick look at the code.)

Share this post


Link to post
Share on other sites
Hmmm actually I think that after the transform into clip space by the projection matrix, the z values are still linear. They get nonlinear in the following homogeneous division dont they? And since the _clip_ space is obviously the space where the hardware performs clipping, there should be half of the scene missing imho.

Share this post


Link to post
Share on other sites
Quote:
Original post by Dtag
Hmmm actually I think that after the transform into clip space by the projection matrix, the z values are still linear. They get nonlinear in the following homogeneous division dont they? And since the _clip_ space is obviously the space where the hardware performs clipping, there should be half of the scene missing imho.
That may very well be the case; I didn't give much thought to that aspect of it. The other points in my previous post may still hold though.

Share this post


Link to post
Share on other sites
Hi --

The DirectX formulation of this algorithm is indeed different because of the previously mentioned difference in the normalized device coordinates bounds in the z direction: [-1,1] for OpenGL and [0,1] for DirectX.

Although I haven't tested this myself, you should be able to get the best matrix for DirectX by making the following changes to the code. A "2.0F" changes to a "1.0F", and a "+ 1.0F" is removed.


// Calculate the scaled plane vector
Vector4D c = clipPlane * (1.0F / Dot(clipPlane, q));

// Replace the third row of the projection matrix
matrix[2] = c.x;
matrix[6] = c.y;
matrix[10] = c.z;
matrix[14] = c.w;

Share this post


Link to post
Share on other sites
Thanks alot for your reply Eric - that worked great :-)


But just out of curiosity - why doesnt half of my Direct X render output get clipped? As stated above Iam using GL matrices for both GL and DX. After the projection and w-division step, I should be in the GLs [-1,1] How can this possibly work for DX?

Share this post


Link to post
Share on other sites
Quote:
Original post by Dtag
But just out of curiosity - why doesnt half of my Direct X render output get clipped? As stated above Iam using GL matrices for both GL and DX. After the projection and w-division step, I should be in the GLs [-1,1] How can this possibly work for DX?


It's possible that clipping isn't really happening before the viewport transformation where it's technically supposed to. What are you using for MinZ and MaxZ in the D3DVIEWPORT9 structure? What hardware are you running on? Nvidia hardware doesn't actually do a geometric clip, and per-pixel rejection is done after the full viewport transformation, so if you're mapping the [0,1] range to [0.5,1.0], then -1 should get mapped to 0.0 and not clipped. I haven't actually experimented with this in DirectX, so this is just a theory.

Share this post


Link to post
Share on other sites
Quote:
Original post by Eric Lengyel
What are you using for MinZ and MaxZ in the D3DVIEWPORT9 structure? What hardware are you running on?


Iam sticking to the default values there. MinZ=0, MaxZ=1. Running on an NVidia 6800 GT.


Quote:
Original post by Eric LengyelNvidia hardware doesn't actually do a geometric clip, and per-pixel rejection is done after the full viewport transformation


Per Pixel rejection?! Wouldnt that basically require a check for every single pixel whether its inside the screen or not?

Share this post


Link to post
Share on other sites
Quote:
Per Pixel rejection?! Wouldnt that basically require a check for every single pixel whether its inside the screen or not?


There are tricks for speeding this up in the hardware -- the rejection happens in the rasterizer before any fragment programs are run, and it's extremely fast. For instance, it's possible to reject entire scanlines at once.

Share this post


Link to post
Share on other sites
I'm guessing they (nVidia) must perform near clipping first or crazy stuff is sure to happen, like divide by zeroes and the like, back projections etc?

Share this post


Link to post
Share on other sites

This topic is 4194 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this