Gribb & Hartmann视锥体构造中的变换疑问及代码调试求助
Hey there! Let's break down your questions and code issues step by step—this stuff gets tricky with matrix orders and space transformations, so you're not alone in the confusion.
First, Let's Clarify Your Core Questions
When M is just the projection matrix: Yes, if you extract planes directly from the projection matrix
P, the resultinga,b,c,drepresent planes in camera local space (sincePoperates on camera-space points). To convert these to world space, you need to transform the plane using the inverse transpose of the view matrix (or more simply, use the combined world-view-projection matrix directly to extract world-space planes, which is what Gribb & Hartmann's method is designed for).Why camera matrices need inversion but object matrices don't: This is normal! The view matrix (what you send to OpenGL for the camera) is the inverse of the camera's world transform. It exists to "move the world" so the camera is at the origin and looking along the default axis. Object model matrices, on the other hand, transform object-space points to world space directly (so no inversion needed)—they're doing the opposite job of the view matrix. That's why you see the inversion difference.
Converting camera-space planes to world space: If you ever need to do this manually, remember: for a plane
(n_cam, d_cam)in camera space, the world-space plane is(V^T * n_cam, d_cam)whereVis the view matrix (world → camera space). But since Gribb & Hartmann's method lets you extract world-space planes directly from the WVP matrix, it's better to fix your matrix setup instead of doing this extra step.
Now, Let's Look at Your Code Issues
Your plane extraction logic (the loop over i and j) matches Gribb & Hartmann's method correctly—great job there! The problems are in your matrix setup and plane normalization/storage:
1. Critical Error: Incorrect Matrix for Plane Extraction
Gribb & Hartmann's method requires the world-view-projection (WVP) matrix, which is Projection * View (not CameraWorld * Projection like you're using).
transin your code is the camera's world transform (position + orientation in world space).- The view matrix is the inverse of
trans(it converts world space to camera space). - The correct WVP matrix is
Projection * View(order depends on your matrix multiplication convention—assumingm4mult(a,b)computesa * b).
Fix: Replace your matrix calculation with:
m4 trans = transform(cam->pos, cam->rot, v3new(1, 1, 1)); m4 view = m4inverse(trans); // View matrix: world → camera space m4 M = m4mult(cam->proj, view); // WVP matrix: world → camera → clip space
If your m4mult function multiplies in reverse order (i.e., m4mult(a,b) computes b * a), swap the operands to m4mult(view, cam->proj).
2. Mistake in Plane Point Calculation
You're storing the plane as a point h plus normal n, but your calculation of h is inverted.
- The normalized plane equation is
n·x + d_normalized = 0whered_normalized = d / e(e is the length of(a,b,c)). - A valid point
hon the plane satisfiesn·h = -d_normalized, soh = -d_normalized * n(notd_normalized * nlike you have now).
Fix: Change your h calculation to:
v3 h = v3scl(n, -d/e); // Negative of d/e to get a point on the plane
If you're using h for frustum culling checks (like sphere/box intersection), this correction will ensure your distance calculations are accurate.
Additional Tips for Debugging
- Verify Matrix Multiplication Order: Print out the values of your WVP matrix and compare them to expected values (e.g., near plane should correspond to your camera's near clip distance in world space).
- Test with a Simple Scenario: Use a camera at the origin looking along the Z-axis, and check if the extracted frustum planes match the expected values (e.g., left plane at
x = -near * tan(fov/2)in world space). - Check Plane Normal Directions: Ensure your plane normals point inward toward the frustum (this is handled by the
s = j ? -1 : 1sign in your loop, but double-check after fixing the matrix).
With these fixes, your frustum extraction should work correctly. Let me know if you still run into issues after making these changes!
内容来源于stack exchange

