Projecting onto multiple surfaces from camera/projector perspective

Hi all. I’ve been trying to create a setup where a projector could hit a few surfaces (e.g. the classic floor + 2 walls/“inside of a box” setup). I’m using a Texture SOP with the Texture Type set to “Perspective From Camera”. I’ve nudged the transforms to get my source texture to cover the surface, but the UVs look all messed up, having a weird diagonal seam through each of the box faces. When I set the Camera COMP’s View to Orthogonal instead of Perspective, it looks right in the Geometry Viewer, but the output of a Render TOP using the camera doesn’t look right - it’s just an cropped version of my texture and it doesn’t change when I translate the camera around. When set to perspective, it does change, but again the UVs are all messed up.

Here are some screenshots and an example file. Any thoughts on what I’m doing wrong?

projection-cam-perspective

projection-cam-ortho

ProjectionFromCamPerspective.toe (2.5 MB)

Hey Matt,

Add a subdivide sop right before the texture sop to fix the diagonal line problem - your initial cube gives you the correct shape but what you’re seeing is texture interpolation across that low poly model since your texture sop is in perspective from camera mode.

This sort of project is what the ‘uv unwrap’ parameters were added for in the render top. However, this was recently added for a high profile artist’s tour, and there’s not yet documentation or examples on how to use it.

Also, check out the Palette > Techniques > sweetSpotPreviz - I’ve used this as a start for extending this technique to involve forced perspective cams, but there are a few helpful workflows in that tox.

Jonathan

1 Like

Thanks Jonathan, the subdivide definitely helped!

It’s interesting how perspective & orthographic seem to render the same thing aside from the crop, regardless of whether the Render TOP’s mode is 2D or UV Unwrap:

ProjectionFromCamPerspective.1.toe (2.5 MB)

This looks better now - still not sure if it’s “right” but I guess I’ll have to set up a projector to tell :smirk:

I’ve looked at the sweetSpot and sweetSpotPreviz components before but wasn’t sure how to use them. I’ll play around with them some more but if you’ve got any thoughts that help explain it better than what’s in the docs (or a different example file) I’d love to hear/see more

Thanks!

I did it using a light as a virtual projector at the virtual position of the sweet spot audience. And then a second camera on the position of the projectopr (camSchnapr):

This problem stems from the fact that perspective projections are non linear in nature and vertex attributes like UVs are interpolated linearly between verticies.

Since a quad is made up of two triangles, and projection distorts uvs in a non planar way, those two sub triangles do not exist in the same “plane” that you would expect when looking at it, or laying uvs out in something like blender etc.

You’ll notice the distortion happens along these polygon edges:
image

If you visualize the geometry uv map and the texture, you’ll notice there is nothing square about the shape of the projected uvs ( even though the texture now looks fine )

For this reason subdividing the geometry does not fix the issue it just makes it less extreme the more you subdivide. If you’re able to subdivide enough and don’t have any animated geometry or complex surfaces then that might be a viable work around.


There is one step specifically in the shader that breaks things in terms of linearity, though it is necessary for projection - that is the perspective divide.

Usually, for speed this is done in the vertex shader and that is usually fine since it is assumed uvs won’t be stretched in this way, but when the need comes for perspective projection like this then the problem can be fixed by doing the perspective divide in the fragment shader uniquely for each pixel rather than in the vertex shader for just each vertex !

this means fundamentally there’s no way to provide this info through sops alone, the shader and thus the render TOP down stream has to know that it needs to do this step in a different way when it renders the actual pixels.

Though you can still make this work by using a material SOP the way you had.


I’m not sure if anyone wanted the long and drawn out technical answer :slight_smile: but there it is - also here’s a modified version of the above file with a simple glsl material that will do this perspective divide in frag shader.

ProjectionFromCamPerspective.1.toe (2.5 MB)

6 Likes

yes please! These are gold :slight_smile:

4 Likes