0
101 Feb 11, 2012 at 17:39

Hi!

I’m using the following code to create a perspective view frustum from a camera’s view matrix and projection settings. How could I extend this to work with orthographic projections?

Thank you!

void Frustum::compute( const mat4 &viewMatrix, float fieldOfView, const ivec4 &area, const vec2 &clipPlanes )
{
// compute tangent and aspect ratio
const float tangent = (float)tan( Degree2Radian(fieldOfView*0.5f) );
const float aspect = (float)(area.z - area.x) / ( float)(area.w - area.y);

// compute near plane dimensions
float nearHeight = clipPlanes.x*tangent;
float nearWidth = nearHeight*aspect;

// compute far plane dimensions
float farHeight = clipPlanes.y*tangent;
float farWidth = farHeight*aspect;
mat4 viewMatrixInverse = glm::inverse( viewMatrix );
mat4 viewMatrixTranspose = glm::transpose( viewMatrix );
const vec3 position = vec3( viewMatrixInverse[3] );

const vec3 xAxis = glm::normalize( vec3(viewMatrixTranspose[0]) );
const vec3 yAxis = glm::normalize( vec3(viewMatrixTranspose[1]) );
const vec3 zAxis = glm::normalize( vec3(viewMatrixTranspose[2]) );

// compute centers of near and far planes
vec3 nearCenter = position + ((-zAxis)*clipPlanes.x);
vec3 farCenter = position + ((-zAxis)*clipPlanes.y);

// compute frustum corners on near plane
vec3 ntl = nearCenter + (yAxis*nearHeight) - (xAxis*nearWidth);
vec3 ntr = nearCenter + (yAxis*nearHeight) + (xAxis*nearWidth);
vec3 nbl = nearCenter - (yAxis*nearHeight) - (xAxis*nearWidth);
vec3 nbr = nearCenter - (yAxis*nearHeight) + (xAxis*nearWidth);

// compute frustum corners on far plane
vec3 ftl = farCenter + (yAxis*farHeight) - (xAxis*farWidth);
vec3 ftr = farCenter + (yAxis*farHeight) + (xAxis*farWidth);
vec3 fbl = farCenter - (yAxis*farHeight) - (xAxis*farWidth);
vec3 fbr = farCenter - (yAxis*farHeight) + (xAxis*farWidth);

// set near and far planes
m_planes[PLANE_NEAR] = computePlane( ntl, ntr, nbr );
m_planes[PLANE_FAR] = computePlane( ftr, ftl, fbl );

// set side planes
m_planes[PLANE_RIGHT] = computePlane( nbr, ntr, fbr );
m_planes[PLANE_TOP] = computePlane( ntr, ntl, ftl );
m_planes[PLANE_LEFT] = computePlane( ntl, nbl, fbl );
m_planes[PLANE_BOTTOM] = computePlane( nbl, nbr, fbr );
}