Sign in to follow this  

Extracting frustum from a view-proj matrix

This topic is 4487 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

#1: When you extract a frustrum from a view*proj matrix, is it the same in a RHS as a LHS? #2: If it is, then here is my problem so far... I'm trying to implement this algorithm http://www2.ravensoft.com/users/ggribb/plane%20extraction.pdf to extract 6 planes from a view*proj matrix in d3d using a rhs. When I do this, it gives me back this matrix
		_11	-1.2990382	float
		_12	0.00000000	float
		_13	0.00000000	float
		_14	0.00000000	float
		_21	0.00000000	float
		_22	1.7320510	float
		_23	0.00000000	float
		_24	0.00000000	float
		_31	0.00000000	float
		_32	0.00000000	float
		_33	1.0000999	float
		_34	0.99999994	float
		_41	0.00000000	float
		_42	0.00000000	float
		_43	-1.0001000	float
		_44	0.00000000	float


And my 4 planes are near = <0,0,1>, d = -1.0001000 far = <0,0,-1>, d = 1.0001000 left = <-0.79,0,0.609> d = 0 right = <-0.79,0,0.609> d = 0 Everything looks right, except the near and far plane's d value. It looks right if the d values are in clip space, but this is suppose to give me back the planes in world space. I define the projection matrix to have a near of 1, and far of 10000. Actually, looking back at the way the paper is doing things, I can't believe this will ever give me back the correct value of d! - Dave EDIT: Also, I moved my camera back 6 units on the negative z, and my left plane reported its d as positive 6, instead of negative 6. [Edited by - ph33r on August 29, 2005 9:00:08 PM]

Share this post


Link to post
Share on other sites
Some random thoughts:

1. I've implemented the OpenGL version of the algorithm and it works perfectly. I've also gone through the derivation, and didn't see anything amiss. Also considering that the paper has been online for a while, and appears in a GPG book, I think you can be confident that the algorithm is correct.

2. I can't say this with certainty because I haven't tested all cases, but I'm pretty sure the algorithm is independent of coordinate system handedness.

3. I take it you're just leaving view as identity for now?

4. The matrix that you posted - is that what DirectX returned for a RH perspective matrix?

5. Even if you're using a RH system you still need to use the D3D code rather than the OpenGL code. The difference between the two versions is in the z-clipping range, not the handedness.

6. Once you do get the plane distances working, remember that the algorithm returns the planes in the form ax+by+cz+d = 0. So 'd' may be the negative of what you expect if you're used to p.n = d.

Let me know if any of that helps.

Share this post


Link to post
Share on other sites
jyk,

I've negated the d and it semi works

The far plane still is at 1.0001, which really should be 10,000. Looking at the perspective projection matrix you will see that its going to normalize that value and never be the actual far plane value, so it will never give you the correct d value. I just replaced that number with the camera's real far plane and it seems to work. I'll have to step through it with perfhud to be certain.

Thank you for your time.

Share this post


Link to post
Share on other sites
Hm, sorry it's still not working. Without more info I can't tell you for sure where the problem is, but the algorithm really does work - you shouldn't have to set your plane distances manually or anything like that. If you feel like pursuing it further, you might post your code. I'm guessing there's just a minor mistake in there somewhere that's throwing things off.

Share this post


Link to post
Share on other sites
Hi there Ph33r,
How are you doing buddy?

The Problem
Plane extraction from a ViewProjection matrix

The Solution
Just to add to the confusion. I hope this helps a bit. But this is a fantastic article on getting the plane extracted

Plane Extraction

I hope this helps a bit buddy, take care.

Share this post


Link to post
Share on other sites
Out of pure academic interest, I'd like to understand why it doesn't get the correct far plane value, here is the code I used to extract the plane.


/**
* Create's a frustrum (six planes) from a view projection matrix.
*
* Near, Left, Right, Far, Top, Bottom
*/

void BuildFrustrumFromViewProjection( const math::Matrix4& m, Plane planes[6] )
{
// Near
planes[0] = *((Plane*)&Vector4( m._13, m._23, m._33, m._43 ) );
// Left (m3 + m0)
planes[1] = *((Plane*)&Vector4( m._14+m._11, m._24+m._21, m._34+m._31, m._44+m._41 ) );
// Right (m3 - m0)
planes[2] = *((Plane*)&Vector4( m._14-m._11, m._24-m._21, m._34-m._31, m._44-m._41 ) );
// Far (m3 - m2)
planes[3] = *((Plane*)&Vector4( m._14-m._13, m._24-m._23, m._34-m._33, m._44-m._43 ) );
// Top (m3 - m1)
planes[4] = *((Plane*)&Vector4( m._14-m._12, m._24-m._22, m._34-m._32, m._44-m._42 ) );
// Bottom (m3 + m1)
planes[5] = *((Plane*)&Vector4( m._14+m._12, m._24+m._22, m._34+m._32, m._44+m._42 ) );

for( int i = 0; i < 6; ++i )
{
planes[i].normal = Vector3Normalize( planes[i].normal );
}
}



The only important line in there is the far plane calculation
Vector4( m._14-m._13, m._24-m._23, m._34-m._33, m._44-m._43 ) );

Which doesn't make sense how it can calculate the far plane, if you look at the projection matrix, where it extracts the values you have these equations

zf/(zn-zf) and
zn*zf/(zn-zf)

10000/(1-10000) and
1*10000/(1-10000)

= -1.001 and -1.001

How, if you are extracting from the projection matrix ever get the far plane back out in world space? The best you'll ever get is in clip space, unless I'm missing something fundamental.

Share this post


Link to post
Share on other sites
You're wellcome :)

It's simple math, in an equation if you mul/div some value, you have to do it to all other values to not change the equation, for example:
2x + 3 = 0
is equal to
4x + 6 = 0
because
2*(2x + 3) = 2*(0)

The vector4 plane values comes from the equation ax+by+cz+d=0 so...
Nx*X + Ny*Y + Nz*Z + D = 0
equals to
1/|N|*(Nx*X + Ny*Y + Nz*Z + D) = 1/|N|*(0)
where |N| is the magnitude of N

Share this post


Link to post
Share on other sites

This topic is 4487 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