# Help Understanding Frustum Calculations

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

## Recommended Posts

Hi all. I'm having trouble understanding the code below. I'm trying to understand the first part (calculating the 8 parts of the frustum in Wolrd Space) so I've omitted the second part of the code. This is not my code. So basically there are multiple parts of this code I do not understand.

First question - Is vector "A" equal to unit vector x in camera space?
- If A is indeed x, does that make "B" equal to unit vector z in camera space?
- I'm guessing ch is calculating the height, but why is it tan((FOV*pi)/360)?

I've tried to draw an arbitrary frustum and camera space in world space to visualize what's happening, but I just can't understand what's going on. Any help is appreciated. Thank you.

 ///////////////////////////////////////////////////////////////////////////// // Name: CalcCullingInfo // Arguments: An eight element array of Points for each of the frustum // corners. // Returns: none // Side Effects: Stores the plane information (normal and d component) for // each of the six frustum planes in the local frustumPlanes // array. ///////////////////////////////////////////////////////////////////////////// void PerspectiveCam::CalcCullingInfo(Point3 frustumCorners[]) { Vector3 dir = Target - Eye; dir.Normalize(); Vector3 up(0,1,0); Vector3 A; A.Cross(dir, up); Vector3 B; B.Cross(A, dir); float ch = tanf(FOV*M_PI/360); float cw = ch*(float)PixelWidth/PixelHeight; frustumCorners[0] = Eye + dir*NearClip + A*cw*NearClip + B*ch*NearClip; frustumCorners[1] = Eye + dir*NearClip - A*cw*NearClip + B*ch*NearClip; frustumCorners[2] = Eye + dir*NearClip - A*cw*NearClip - B*ch*NearClip; frustumCorners[3] = Eye + dir*NearClip + A*cw*NearClip - B*ch*NearClip; frustumCorners[4] = Eye + dir*FarClip + A*cw*FarClip + B*ch*FarClip; frustumCorners[5] = Eye + dir*FarClip - A*cw*FarClip + B*ch*FarClip; frustumCorners[6] = Eye + dir*FarClip - A*cw*FarClip - B*ch*FarClip; frustumCorners[7] = Eye + dir*FarClip + A*cw*FarClip - B*ch*FarClip; //rest of code } 

 ///////////////////////////////////////////////////////////////////////////// // Camera // class Camera { //////////////////////////////// // Local Structure protected: struct Plane { Vector3 normal; float d; }; //////////////////////////////// // Constructors/Destructors public: Camera(); virtual ~Camera() {}; //////////////////////////////// // Local Procedures public: void SetEye(const Point3& eye) { Eye = eye; } void SetUp(const Vector3& up) { Up = up; } void SetTarget(const Point3& t) { Target = t; } void SetNearClip(float nc) { NearClip = nc;} void SetFarClip(float fc) { FarClip = fc;} void SetWindowDimensions(unsigned int width,unsigned height) { PixelWidth = width; PixelHeight = height; } Vector3& GetUp() { return Up; } Point3& GetEye() { return Eye; } Point3& GetTarget() { return Target; } float GetNearClip() { return NearClip; } float GetFarClip() { return FarClip; } void GetWindowDimensions(unsigned int &width,unsigned &height) { width = PixelWidth; height = PixelHeight; } void CalcInvLookAt(Matrix &out); virtual void CalcProjectionMatrix(Matrix &out)=0; virtual void CalcCullingInfo(Point3 *frustumCorners)=0; void DrawFrustum(Point3 *frustumCorners); char CullBoundingSphere(const Point3 &pos, float radius); char TestBoundingSpherePlane(const Point3 &pos, float radius, const Vector3 &normal, float d); // Member Variables protected: // main screen params Point3 Eye; Point3 Target; Vector3 Up; float NearClip, FarClip; unsigned int PixelWidth,PixelHeight; // For Culling Plane frustumPlanes[6]; }; ///////////////////////////////////////////////////////////////////////////// // PerspectiveCam // class PerspectiveCam : public Camera { //////////////////////////////// // Constructor/Destructor public: PerspectiveCam(float fov) {FOV = fov;} virtual ~PerspectiveCam() {}; //////////////////////////////// // Local Procedures public: void SetFOV(float fov) { FOV = fov; } float& GetFOV() { return FOV; } void CalcProjectionMatrix(Matrix &out); void CalcCullingInfo(Point3 *frustumCorners); // Member Variables private: float FOV; }; 

##### Share on other sites
It does look like A and B are the side and up vectors for the camera, respectively.

However, I wouldn't compute the corners that way. If you already have the frustum planes, you can instead intersect the planes in sets of three to yield the frustum corners. This way, you'll be guaranteed to get the correct corners as long as the planes themselves are correct (for example, you'll get the correct corners even for an orthographic projection, assuming the planes have been computed correctly).

##### Share on other sites
[font="Arial"]A and B are the right and up directions for the camera. A, B, and dir (the vector from eye to look) form a basis (three orthogonal axes), so B is not necessarily the Z-unit vector. You can use A and B with the eye coordinates to make pick rays.

It really doesn't make sense to have a DrawFrustum() for the corners. After the perspective transform, the frustum corners will be the eight corners of the unit cube in clip coordinates. You might see the points drawn in the corners of the display for the near plane and further out for the far plane.

See the "Stages of Vertex Transformation"
http://fly.cc.fer.hr.../chapter03.html

Normally, calculations are done [/font][font="Arial"]using the half angle of the field of view. The 360 simple compensates for not using a half FOV angle. A little clearer would be
float ch = tanf(FOV * 0.5 * M_PI / 180.0);[/font]

1. 1
2. 2
3. 3
Rutin
20
4. 4
5. 5
khawk
14

• 9
• 11
• 11
• 23
• 12
• ### Forum Statistics

• Total Topics
633655
• Total Posts
3013175
×