Get Camera Frustum Corners In World Space With Inverse View-Projection Matrix

Hello TD community!

I’m trying to build something to visualize a cameraCOMP’s view frustum by finding its 8 corner points in world space (each represented by a NullCOMP in the attached .toe file).

My understanding is that the process is to invert transformation between world->view->clip->NDC spaces. Namely, I’m taking the NDCs of the 8 frustum corner points with “w” set to 1:
[(-1, -1, 0, 1), (1, -1, 0, 1), (-1, 1, 0, 1), (1, 1, 0, 1),
(-1, -1, 1, 1), (1, -1, 1, 1), (-1, 1, 1, 1), (1, 1, 1, 1)]

First, multiply the near and far values of the camera with the 4 corresponding points to invert the perspective division. In my case, near is 1.0, and far is 10.0, so the first 4 points are * 1.0 and the last 4 are * 10.0.

Then multiply them by the inverse view-projection matrix of the camera. My understanding is that the result then should be the coordinates of the corner points in world space… But currently, that’s not the case. What I’m getting seems to be somewhere in between view space and world space? What am I missing?

Attached is the .toe file.

I should mention that the end goal is to be able to construct a custom projection matrix by providing the frustum entents (left, right, top, bottom, near. far), which is then applied to a camera COMP, so that the near plane of the frustum can be something like the “near face” of an arbitrary screen geometry’s bounding box. Something that acts similar to the “Quad Reproject” function of a cameraCOMP, only that instead of having a quad as the screen, the screen can be an arbitrary shape.

CameraFrustumVisualizer_Demo.toe (5.9 KB)

I’m not super familiar with the conventions of numpy, but when passing a (x,y,z,1) position through a perspective projection matrix, you’ll almost always end up with a w coordinate that is no longer == 1.0. You then need to do perspective divide to get the coordinates back into an affine space (x/w, y/w, z/w, w/w).
So that part is missing, but also it seems like the second half of the points end up with a w=0, so that’s wrong as well. Possibly you have a transpose issue here.

You can do all of this using tdu.Matrix and tdu.Position though, not need to use numpy. tdu.Matrix * tdu.Position will implicitly do the w divide for you. I just used those with your code and I end up with the correct values.
Btw, our projection matrices have near=0 and far =1 in NDC space.

1 Like

Ah - thank you Malcolm! Yeah tdu.Position is the answer - I used tdu.Vector and didn’t get the result I wanted so I made the switch to numpy. Now as I’m reading through the documentation on tdu.Vector and tdu.Position, it makes sense.

Thank you again Malcolm!