Jump to content
  • Advertisement
Sign in to follow this  
byhisdeeds

Calculation of the coordinates of the 8 view frustum corners

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

Can anybody tell me how to calculate the coordinates of the 8 corners of the view frustum from the 6 view frustum sides plane equations.

Share this post


Link to post
Share on other sites
Advertisement
This is the code I've used to calculate my light frustum (which helps boost omnidirectional shadow mapping). Of course, if you're looking to calculate the eye view, it should be analogous as long as you have the eye position and eye look at point. This code also assumes that the frustum is only subject to yaw and pitch, but not roll:


// Note: WNEARHALF = LNEAR * tan(LIGHTFOV * (PI / 180.0) / 2.0);
// WFARHALF = LFAR * tan(LIGHTFOV * (PI / 180.0) / 2.0);

GLfloat length, *tempAL, *tempBL, *tempR;
GLint i, j;
GLfloat d[3], r[3], u[3], a[3], b[3];

// Calculate the light direction vector components.
d[0] = LIGHTLOOKAT[0] - lightPos[0];
d[1] = LIGHTLOOKAT[1] - lightPos[1];
d[2] = LIGHTLOOKAT[2] - lightPos[2];

// Normalize the direction vector.
length = sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]);
d[0] /= length;
d[1] /= length;
d[2] /= length;

// Calculate the light right vector components.
r[0] = -d[2];
r[1] = 0.0;
r[2] = d[0];

// Normalize the right vector.
length = sqrt(r[0] * r[0] + r[2] * r[2]);
r[0] /= length;
r[2] /= length;

// Calculate the light up vector components (cross product of: right X direction).
u[0] = r[1] * d[2] - r[2] * d[1];
u[1] = r[2] * d[0] - r[0] * d[2];
u[2] = r[0] * d[1] - r[1] * d[0];

// Normalize the up vector.
length = sqrt(u[0] * u[0] + u[1] * u[1] + u[2] * u[2]);
u[0] /= length;
u[1] /= length;
u[2] /= length;

// Calculate vector fc (vector from viewer to center of far frustum plane.
fc[0] = lightPos[0] + d[0] * LFAR;
fc[1] = lightPos[1] + d[1] * LFAR;
fc[2] = lightPos[2] + d[2] * LFAR;

// Calculate vertex of far top left frustum plane.
ftl[0] = fc[0] + (u[0] * WFARHALF) - (r[0] * WFARHALF);
ftl[1] = fc[1] + (u[1] * WFARHALF) - (r[1] * WFARHALF);
ftl[2] = fc[2] + (u[2] * WFARHALF) - (r[2] * WFARHALF);

// Calculate vertex of far top right frustum plane.
ftr[0] = fc[0] + (u[0] * WFARHALF) + (r[0] * WFARHALF);
ftr[1] = fc[1] + (u[1] * WFARHALF) + (r[1] * WFARHALF);
ftr[2] = fc[2] + (u[2] * WFARHALF) + (r[2] * WFARHALF);

// Calculate vertex of far bottom left frustum plane.
fbl[0] = fc[0] - (u[0] * WFARHALF) - (r[0] * WFARHALF);
fbl[1] = fc[1] - (u[1] * WFARHALF) - (r[1] * WFARHALF);
fbl[2] = fc[2] - (u[2] * WFARHALF) - (r[2] * WFARHALF);

// Calculate vertex of far bottom right frustum plane.
fbr[0] = fc[0] - (u[0] * WFARHALF) + (r[0] * WFARHALF);
fbr[1] = fc[1] - (u[1] * WFARHALF) + (r[1] * WFARHALF);
fbr[2] = fc[2] - (u[2] * WFARHALF) + (r[2] * WFARHALF);

// Calculate vector nc (vector from viewer to center of near frustum plane.
nc[0] = lightPos[0] + d[0] * LNEAR;
nc[1] = lightPos[1] + d[1] * LNEAR;
nc[2] = lightPos[2] + d[2] * LNEAR;

// Calculate vertex of near top left frustum plane.
ntl[0] = nc[0] + (u[0] * WNEARHALF) - (r[0] * WNEARHALF);
ntl[1] = nc[1] + (u[1] * WNEARHALF) - (r[1] * WNEARHALF);
ntl[2] = nc[2] + (u[2] * WNEARHALF) - (r[2] * WNEARHALF);

// Calculate vertex of near top right frustum plane.
ntr[0] = nc[0] + (u[0] * WNEARHALF) + (r[0] * WNEARHALF);
ntr[1] = nc[1] + (u[1] * WNEARHALF) + (r[1] * WNEARHALF);
ntr[2] = nc[2] + (u[2] * WNEARHALF) + (r[2] * WNEARHALF);

// Calculate vertex of near bottom left frustum plane.
nbl[0] = nc[0] - (u[0] * WNEARHALF) - (r[0] * WNEARHALF);
nbl[1] = nc[1] - (u[1] * WNEARHALF) - (r[1] * WNEARHALF);
nbl[2] = nc[2] - (u[2] * WNEARHALF) - (r[2] * WNEARHALF);

// Calculate vertex of near bottom right frustum plane.
nbr[0] = nc[0] - (u[0] * WNEARHALF) + (r[0] * WNEARHALF);
nbr[1] = nc[1] - (u[1] * WNEARHALF) + (r[1] * WNEARHALF);
nbr[2] = nc[2] - (u[2] * WNEARHALF) + (r[2] * WNEARHALF);

// Calculate the six light frustum clip planes.
for(j = 0; j < 6; j++)
{
// Near clip plane.
if(j == 0) { tempAL = nbl; tempBL = ntr; tempR = nbr; }
// Far clip plane.
else if(j == 1) { tempAL = fbr; tempBL = ftl; tempR = fbl; }
// Left clip plane.
else if(j == 2) { tempAL = fbl; tempBL = ntl; tempR = nbl; }
// Right clip plane.
else if(j == 3) { tempAL = nbr; tempBL = ftr; tempR = fbr; }
// Top clip plane.
else if(j == 4) { tempAL = ntr; tempBL = ftl; tempR = ftr; }
// Bottom clip plane.
else { tempAL = nbl; tempBL = fbr; tempR = fbl; }

for(i = 0; i < 3; i++) { a = tempAL - tempR; b = tempBL - tempR; }
lightClipPlane[j][0] = a[1] * b[2] - a[2] * b[1];
lightClipPlane[j][1] = a[2] * b[0] - a[0] * b[2];
lightClipPlane[j][2] = a[0] * b[1] - a[1] * b[0];
length = sqrt(lightClipPlane[j][0] * lightClipPlane[j][0] + lightClipPlane[j][1] * lightClipPlane[j][1] + lightClipPlane[j][2] * lightClipPlane[j][2]);
for(i = 0; i < 3; i++)
lightClipPlane[j] /= length;
lightClipPlane[j][3] = -(lightClipPlane[j][0] * tempR[0] + lightClipPlane[j][1] * tempR[1] + lightClipPlane[j][2] * tempR[2]);
}

Share this post


Link to post
Share on other sites
Just a clarification: LNEAR is the distance from the eye to the near plane, and LFAR is the distance from the eye top the far plane, right?

Share this post


Link to post
Share on other sites
Quote:
Original post by byhisdeeds
Just a clarification: LNEAR is the distance from the eye to the near plane, and LFAR is the distance from the eye top the far plane, right?


Yep.

Share this post


Link to post
Share on other sites
I did a much shorter version once, based on these articles.

http://www.geometryalgorithms.com/Archive/algorithm_0104/algorithm_0104B.htm

Share this post


Link to post
Share on other sites
Just transform the extremities of clip space (i.e. (0,0,0), (0,0,1), (0,1,0), (0,1,1), etc) by inverse(viewMatrix*projMatrix). That'll give you points in worldspace.

Share this post


Link to post
Share on other sites
Quote:
Anybody fancy testing which method is faster?

It's pretty much moot. Unless you're figuring out the frustum corners a hundred times per frame, it's not going to even show up on the performance radar. Typically, you'll do this once per frame, and the cost of that is zero compared to what the rest of your game should be doing. :)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!