Notifications
Clear all

[Closed] Camera matrix?

I searched all over and I’m assuming this isn’t possible, but just to be sure… Does anyone know if I can obtain the camera’s projection matrix? Furthermore, can I SET the camera’s projection matrix? I need to set up asymmetric frustums and it would be much easier if I could simply set the matrix with values I have calculated…

14 Replies
1 Reply
(@bobo)
Joined: 11 months ago

Posts: 0

The Camera Projection Matrix is the inverse of the Camera Node’s Transformation Matrix.
In other words, if you assign a Camera to a Viewport and ask for the

viewport.getTM()

it will return the same value as

inverse $Camera01.transform

Thus, if you know the projection matrix, you can simply invert it and assign to the .transform property of the camera.

Also note that the Camera accepts deformation modifiers like Skew and XForm, so you could apply matrices on top of the camera via the XForm’s gizmo matrix to produce asymmetrical frustums.

Great! Thanks a lot, once again, Bobo. You’re awesome
I had been using Skew, but I didn’t know about XForm…

I was trying to figure it out here, but by what I figured the camera’s node transform is the ModelView matrix, not the Projection… I’m trying to find out how we can modify the Projection, I’ll probably have to calculate it through FOV, Near and Far, multiply the MV by that matrix and apply my new matrix over it… Or something like that…

Anyway your reply helped a lot, but just wanted to give a heads up that it’s not Projection, but instead ModelView.

Thanks

1 Reply
(@martinb)
Joined: 11 months ago

Posts: 0

Not sure you can get a single matrix in 3ds Max that will do what you need. (you want something like this http://www.songho.ca/opengl/gl_projectionmatrix.html right?)
I have been searching myself for a simple way to convert between a 3D world point and 2D image coordinates, given a camera, and from a 2D image coordinate to a 3D ray.

What exactly do you want to use the projection matrix for?

– Martinb

Eh… Just realized: not possible… Due to Max’s wierd Matrix3 (4×3) and the lack of a Matrix4 to set the Projection Matrix it seems the only way is via plugin (maybe). I’ll have to figure out some other way then sigh

Martin,

I’m trying to develop a camera setup for a multi-projection system which needs a asymmetrical frusta… Since I haven’t figured out a way of using the Projection Matrix (which would be the easiest way because I already have the necessary calculations), I’m now trying to formulate the skew modifier to do this…

2 Replies
(@martinb)
Joined: 11 months ago

Posts: 0

Yes, that makes a lot of sense. Actually that is why I initially wrote the overScan script (rendering a larger image, then cropping). BTW, one can use this in combination with region rendering to save render time.

The Skew modifier could work, but I could not quite figure out the relationship between the Skew number and what is happening to the view frustum of the camera. Please let me know if you find out. One could look at the Map method in skew.cpp in the maxsdk.

– MartinB

(@martinb)
Joined: 11 months ago

Posts: 0

FWIW, here’s what I found so far after quickly looking at the code:
As far as I can tell the Skew modifier is computing a simple lateral shift of points, using the ‘Amount’ as the distance in world units that the farthest points should travel. So if you have a box that is 20x20x20 units big and skew it with an amount of 10, it will shift the most distant points of the box by 10 units in x direction.

Now, I have NO idea what happens if you pass a camera to such a modifier, which has no points to transform. The SDK help says:

“Object space modifiers are applied to the transformation matrix if the object flowing through the pipeline has no points to deform (i.e. is not deformable) such as a camera”

and

“The object state manages a transformation matrix (ObjectState::GetTM()) that is deformed only if an object cannot convert itself to a deformable type. After the matrix is deformed, it is converted back into an matrix using an iterative process that ‘averages’ the axis. All objects are supposed to be able to convert themselves to TriObjects (which are deformable) so in general this is not used. However in the case of cameras and lights it doesn’t make sense to convert them to TriObjects so this is how they are deformed. You can see an example of this by binding a camera to a space warp like ripple. The camera will bounce up and down as it is ‘deformed’ by the space warp.”

but I don’t get how this would skew a camera frustum.

Anyone got any ideas?

– MartinB

Would be interested in seeing what you come up with, we use Michal Breidts Overscan script to adjust both frustrum, often when we don’t need a wider frustrum on one edge, which can result in higher render times if we have to whack 10k on both sides!

One more piece to the puzzle:

Take a look at modifier_camera_perspective_correction.ms – this computes a Skew angle based on the camera rotation in order to make the camera frustum vertical again. Haven’t thought this through yet but maybe we could use this to figure out the Amount value for given angles?

Please let me know if you come up with something useful
– MartinB

http://scripts.breidt.net/

Take a look at the overscan plugin and the ImagePlane Script, this might help you work out some more precise values for the frustrum.

I’ve just tested quickly trying to work out some rough values, with a 100×100 resolution, square, to shift the frustrum 50% up, you need a value of about 21.756 and to move it up 100% it needs to be about 70.709

But I’ve only worked these out using the viewport, so not 100% accurate. See attached image…

Well… I was testing for example with a box. I had already tried what you said a few posts above. I made a 20x20x20 box and skewed it by 10. It did exactly what was expected: skewed the box by roughly 10 units. The behavior isn’t the same with the camera, but, by what I’ve tested until now, if you set the skew’s gizmo to act like a “bounding box” to the camera’s frustum, you should get the expected behavior. In my case I already have to know the viewer’s distance to the screen, so I think I can generate the “bounding box” easier.

1 Reply
(@martinb)
Joined: 11 months ago

Posts: 0

That’s actually not such a bad idea. You could use my viewFrustum script to generate a geometric representation of a normal camera’s view frustum, then apply a Skew modifier to it and then copy that modifier onto the camera. But you’d still need to eyeball it, which you can do using the built-in frustum, right?

What I am interested is finding the Skew ‘amount’ for given frustum angles.

– MartinB

That didn’t work… The camera must maintain the fov, so it doesn’t have the same behavior as an object (ie: I tried with your viewFrustum script instancing the skew to the camera, but the pyramid differs from the frustum). I discovered the gizmo’s position has no effect at all on the skew, what matters is the gizmo’s center and proportion between the length and width (using the Z axis, the height might matter for some other axis). If I scale on x and y together it has no effect at all on the camera.

So what I’m doing now is I have applied the camera to a viewport and I’m setting the Amount incrementally printing out the Amount and the camera’s view direction (given by: -(inverse(getviewtm())).row3). With this I’m gonna try to figure out the relation between the amount and the effect on the camera’s view direction… :banghead: