Is is possible to calculate the view frustum with only the: aspectRatio, y_scale, x_scale and frustum_length?

Random Coder :

I am creating a game where i calculate a view matrix with the aspectRatio, y_scale, x_scale and frustum_length so i was wondering if there is a way to calculate the view frustum with only those variables.

variables:

float aspectRatio = (float)Display.getWidth() / (float)Display.getHeight();
float y_scale = (float) ((1f / Math.tan(Math.toRadians(FOV / 2f))) * aspectRatio);
float x_scale = y_scale / aspectRatio;
float frustum_length = FAR_PLANE - NEAR_PLANE;
Rabbid76 :

When the the perspective projection is symmetrically, the (y-axis) field of view angle FOV, the aspect ratio aspectRatio and the distances to the near plane (NEAR_PLANE) and far plane (FAR_PLANE) are given, then the 8 corner points ot the view frustum in view space can be calculated:

float aspectRatio = (float)Display.getWidth() / (float)Display.getHeight();

float y_scale = 1.0f / (float)Math.tan( Math.toRadians(FOV / 2.0) );
float x_scale = y_scale * aspectRatio;

float near_x = NEAR_PLANE * x_scale;
float near_y = NEAR_PLANE * y_scale;

float far_x = FAR_PLANE * x_scale;
float far_y = FAR_PLANE * y_scale;

Vector3f left_bottom_near  = new Vector3f(-near_x, -near_y, FAR_PLANE);
Vector3f right_bottom_near = new Vector3f( near_x, -near_y, FAR_PLANE);
Vector3f left_top_near     = new Vector3f(-near_x,  near_y, FAR_PLANE);
Vector3f right_top_near    = new Vector3f( near_x,  near_y, FAR_PLANE);

Vector3f left_bottom_far  = new Vector3f(-far_x, -far_y, FAR_PLANE);
Vector3f right_bottom_far = new Vector3f( far_x, -far_y, FAR_PLANE);
Vector3f left_top_far     = new Vector3f(-far_x,  far_y, FAR_PLANE);
Vector3f right_top_far    = new Vector3f( far_x,  far_y, FAR_PLANE);

If you want to know the the 8 corner points ot the view frustum in world space, then the points have to be transformed from view space to world space.
The matrix which transforms from world space to view space, ist the "view" matrix. The the matrix which can transform from view space to world space is the inverse view matrix (invert()).
The inverse view matrix ist the matrix which is defined by the view position, view direction and up-vector of the view. The Matrix4f can be setup as follows:

Vector3f eyePos;    // position of the view (eye position)
Vector3f targetPos; // the point which is looked at 
Vector3f upVec;     // up vector of the view
Vector3f zAxis = Vector3f.sub(eyePos, targetPos, null);
zAxis.normalise();

Vector3f xAxis = Vector3f.cross(upVec, zAxis, null);
xAxis.normalise();

Vector3f yAxis = Vector3f.cross(zAxis, upVec, null);

Matrix4f inverseView = new Matrix4f();
inverseView.m00 = xAxis.x;  inverseView.m01 = xAxis.y;  inverseView.m02 = xAxis.z;  inverseView.m03 = 0.0f;
inverseView.m10 = yAxis.x;  inverseView.m11 = yAxis.y;  inverseView.m12 = yAxis.z;  inverseView.m13 = 0.0f;
inverseView.m20 = zAxis.x;  inverseView.m21 = zAxis.y;  inverseView.m22 = zAxis.z;  inverseView.m23 = 0.0f;
inverseView.m30 = eyePos.x; inverseView.m31 = eyePos.y; inverseView.m32 = eyePos.z; inverseView.m33 = 1.0f;

Note, the coordinate system of the view space is a Right-handed system, where the X-axis points to the left and the Y-axis points up, then the Z-axis points out of the view (Note in a right hand system the Z-Axis is the cross product of the X-Axis and the Y-Axis).

Finally the corner points can be transformed by the matrix:

e.g.

Vector4f left_bottom_near_v4 = new Vector4f(
    left_bottom_near.x, left_bottom_near.y, left_bottom_near.z, 1.0f
);

Vector4f left_bottom_near_world_v4 = new Vector4f();
Matrix4f.transform(Matrix4f left, left_bottom_near_v4, left_bottom_near_world_v4);

Vector3f left_bottom_near_world = new Vector3f(
    left_bottom_near_world_v4 .x, left_bottom_near_world_v4 .y, left_bottom_near_world_v4 .z
);

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=159990&siteId=1