Cone/Sphere Frustum Culling - Angle?

Started by
6 comments, last by SDyer 21 years ago
I''ve searched this forum and the web, and have found nearly all the information I need to implement visibility culling using a cone around the view frustum and bounding spheres around the objects. I construct the frustum cone using the Field of View with which I constructed the frustum itself - D3DX_PI/4 in my case. Here''s the problem: Using the FOV to create the cone gives me a cone WITHIN the frustum, not AROUND it. Since the corners are outside the cone, objects pop in those areas. How do I get the angle to use to encompass the whole frustum?
Advertisement
** bump **
1) As with the frustum you can think of the cone as a right angled triangle. If you rotate it around what would be the cones axis, you sweep out a cone:
zF_______ |      / |     / |    / |   / |  / |h/ |/ E 


h = fov/2
E = eye
zF = far Z


2) Your "view plane" is a square or rectangle which lies somewhere between E and zF:
<----w---->+---------+  -|       / |  ||    /    |  h| /       |  |+---------+  - 


[The /''s are meant to represent a diagonal line going from one corner to the other]

The line between E and zF shoots through the centre of that plane. As you''ve discovered, the circle formed by the cone falls inside the left and right edges of it (the width of the cone at that point along the view direction will be the same as the width of the square in the frustum ) so your cone missese a bit of stuff in the corners of the frustum.


3) Easy solution: manually tweak the angle of the cone until you don''t get any noticable pop-up. Could even do it visually by superimposing the frustum and cone and tweaking until the cone is outside.


4) Proper solution: Use the length of the diagonal line shown above as the width of your cone, that will then mean the cone is always outside the square.

You can get half the width and height of the viewplane at position D (see "The Viewing Frustum" topic of D3D docs) along the viewing direction with a bit of high school trig (SOH, CAH, TOA: you know the angle [fov/2], and the adjacent length [D]...)

length_of_diagonal = sqrt( width2 + height2
) [Pythagoras]

Half the length of the diagonal is the new desired width for the right angled triangle representing half the cone, so you now have adjacent and opposite lengths of the triangle and want to find the new angle - back to high school trig - [tan-1, aka arctan/atan].


[Not explained anywhere near as well as I''d hoped - partly due to not being able to do nice diagrams so well in ASCII, partly due to me being in serious need of sleep ]


--
Simon O''Connor
Creative Asylum Ltd
www.creative-asylum.com

Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site

**un-bump**

Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site

Thanks S1CA. You''ve already been a great help - I''ve read many of your posts here while searching on this.

I know I need the diagonal, and how to get it''s length. Once I have that, what is the trig statement to get the angle?

I''m not that deep on trig (but getting deeper every minute I research this), and would appreciate the exact C++ statements to get the angle given the lengths of the sides of a right triangle.
    a------+\     | \    |  \   |b c \  |    \h|     \| 




// tan(h) = a/b = ratio of opposite over adjacent ("TOA")
float half_width = znear * tanf( half_x_fov );
float half_height = znear * tanf( half_y_fov );


// Pythagoras: c² = a² + b²
float half_diagonal = sqrtf( (half_width*half_width) + (half_height*half_height) );


// get new angle from ratio of diagonal (new opposite ['a' in diagram]) and known adjacent length (znear)
float half_cone_fov = atanf( half_diagonal / znear );


--
Simon O'Connor
Creative Asylum Ltd
www.creative-asylum.com

[edited by - s1ca on March 24, 2003 6:38:02 PM]

Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site

Thanks, S1CA.

One last question - how do you get "half_x_fov" and "half_y_fov"? My FOV is pi/4 radians. How does one convert that into x and y components?
Ah. I am using D3DXMatrixPerspectiveFovLH to set up the view matrix, and that takes only "FOV". That is really the VERTICAL FOV, which it then combines with the aspect ratio to size everything. I could have built the matrix myself out of FOV horizontal/vertical, too.

So, since my aspect ratio is a perfect square, I used my one FOV for both x and y FOV''s in the calculations and viola! Now, I have perfect sphere/cone culling going.

At last! Thanks for all the trig help. It was a real education.

This topic is closed to new replies.

Advertisement