4
$\begingroup$

Given a perspective projection matrix. How can one from it derive a set of matrices representing "chunks" of the viewport? So that the rendered chunks can be "stiched" to form an image "chunk times higher" resolution than the viewport.

Here's an image (drawn in ms paint, ik) describing what a chunk of the frustum would look like: enter image description here

I'm planning on using this for a camera mod library to take images in "super-resolution", in reality the chunks should overlap a little, to allow for exposure compensation and the blending of effects like lens flare. Most linear algebra in this project is done with a header-only library called linalg , so it'd be nice if any examples shown used that library. Thanks!

$\endgroup$
  • $\begingroup$ Could you clarify whether this is for a physical camera or the camera view in a rendering setting? Are you looking to apply this transform to modelled objects or real world scenes? $\endgroup$ – trichoplax Jan 20 at 19:20
  • 1
    $\begingroup$ Idk if this answers your question, but as I mentioned on the post I'm modding games to intercept the camera properties (including this matrix) and later modify them. The point of this is to create a .lib camera manipulator to emulate camera modes like nvidia ansel or other ingame implementations, but open source, generic and without dev support. I'd guess games don't use physical models to render scenes, so I'd think this is the camera view in a rendering setting, I'm modding binaries so I don't know precisely what I'm altering. $\endgroup$ – Facundo Jan 20 at 22:35
3
$\begingroup$

It depends a little how you construct the matrix. I assume that you use the function perspective_matrix from your library, which actually works pretty much like good old gluPerspective). But what this actually does is nothing else than use the more general function frustum_matrix, which in turn creates a common arbitrary view frustum matrix, like good old glFrustum did (from the (simplified) linalg source code):

mat4 perspective_matrix(T fovy, T aspect, T n, T f)
{
    T y = n*std::tan(fovy / 2), x = y*aspect;
    return frustum_matrix(-x, x, -y, y, n, f);
}

And this general frustum matrix function is actually all you need for creating arbitrary assymmetrical frustum matrices, like the ones you want. The paramters it takes are exactly the left, right, bottom, and top boundaries of the near plane, i.e. the x and y boundaries of the frustum on the z = near (or -near) plane. So all you actually need to do is take these left/right/bottom/top parameters and cut those ranges into whatever sub-intervals you need.

It depends a little on what information you actually have. If you have the parameters you construct your perspective matrix from (i.e. the fovY and the aspect) you can just replace the above procedure with something more elaborate that computes the frustum parameters from these two and then scale-biases them into the corresponding intervals.

If all you have is an already constructed perspective matrix, you might have to retrieve the parameters from that matrix first, which shouldn't be too difficult when looking at how the matrix is constructed. If you already have a general assymmetric frustum matrix, it might get a little more elaborate. But it always really all just comes down to tweaking the $M_{11}, M_{13}, M_{22}, M_{23}$ elements of the matrix a little with some scaling and offseting that I'm sure you can figure out when looking at how these matrices are constructed. The rest can stay as they are (provided you don't need chunking in the z-direction either, which would be used for different techniques than what you are trying to do).

$\endgroup$
  • $\begingroup$ I didn't know I could build a frustum with negative left, right, top or bottom values. Now that I'm reading the docs on glFrustum more carefully I notice that GL_INVALID_VALUE is only returned under more reasonable conditions (like right and left being the same value). Would you mind clarifying what I should do with the M11,M13,M22,M23 elements of the matrix? All the resources I was able to find about building a perspective projection matrix conclude on a 4x4 one, while the ones I'm working with are only 3*3. Thanks for the help! $\endgroup$ – Facundo Jan 20 at 22:59
  • $\begingroup$ Uh, your matrices really can't be 3x3 if you're doing perspective projection in 3D. $\endgroup$ – Christian Rau Jan 20 at 23:12
  • $\begingroup$ Anyway, as to the actual formulas, it's really not all that involved. Just look at the values you'd need to put into frustum_matrix which are quite straight forward, and then how the matrix you have as input was constructed. It all comes down to scaling the diagonal entries and offseting the translation entries. I'll not provide the exact computations since 1) I'm on mobile and 2) I'll ultimately make a small mistake and you'd have to figure it out yourself anyway. ;-) It's one of these small computations best figured out on a sheet of paper in a minute. $\endgroup$ – Christian Rau Jan 20 at 23:28
  • $\begingroup$ @Cristian I didn't realize I was looking at the rotation matrix for the camera, totally confused. I'm going to start looking for the projection matrix in the game now. I'll investigate some more and mark this as the solution if it ends up working. $\endgroup$ – Facundo Jan 21 at 17:38
  • 1
    $\begingroup$ This has the solution for extracting the frustum values stackoverflow.com/a/12926655/5538719 $\endgroup$ – Facundo Jan 23 at 0:11

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.