# Extracting frustum from a view-proj matrix

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

## 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 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 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.

##### 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 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 on other sites
Quote:
 But this is a fantastic article on getting the plane extracted...
Actually, that's the article he's using.

##### Share on other sites
Lol, I didn't see that...
I woke up so early this morning, all I saw was plane extraction. :)

##### 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.normal = Vector3Normalize( planes.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 on other sites
Don't you have to normalize also the d param of the planes?

float m = Vector3Magnitude(plane.normal);
plane.normal /= m;
plane.d /= m;

##### Share on other sites
Thank you! That was it, can someone explain to me why you normalize the plane's d value?

##### 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