Multi-projector tiled, blended display implemented in Unity

We are building a Unity app for a small theater in a museum and will be using two HD projectors (either 1080p or 720p) tiled and edge-blended to form a seamless, super-wide display: 3840 x 1080, for example. We have two options for blending the two projector images together. We can pay a lot of money for external blender/scaler hardware (~$12K - $25K plus projectors) to resample/overlap and edge-blend the two display channels from a dual output PC or we can generate the required image overlap and blending falloff in Unity.

My first attempt at building a tiled projection display with Unity has been to enable stretched desktop mode on our display system’s graphics card (NVidia Quadro Pro 4600) so that Unity sees the two DVI video channels as a single, super-wide monitor resolution (3840 x 1080 across two Epson 1080p projectors).

In order to create a seamless projection image, we need to overlap the two projector images horizontally by 10-20% and apply an intensity falloff ramp to the right and left edges of the left and right projector images respectively. I created the required image overlap by creating two Unity cameras, located at the same 3D coordinate. I then modified the left and right cameras’ projectionMatrix to create an asymmetric frustum for each, the left camera sheared to the left and the right camera sheared to the right and both frusta overlapping proportional to the projector image overlap. I parented the left and right cameras to an empty GameObject in order to transform the two cameras together as if they were a single camera.

At this point, I get a seamless projection image, but with a bright band between the two projector images where they overlap at full intensity. The next step will be to create an appropriate image falloff across the overlap band. Would an image effect for each camera work? I’m new to Unity and haven’t done any shader programming before, so I’m not certain this is the right path to take.

Another idea for accomplishing all of this is to use a single scene camera, with the full, super-wide aspect, rendering into a non-power-of-two rendertexture and subsequently cropping and displaying in two GUITextures for the left and right projectors. Is this possible, including cropping the single rendertexture into two GUITextures and applying a falloff ramp? Would this lead to better performance than the first technique described?

Thanks for any advice you can give

For a start you could try what you’re doing now, and draw two GUITextures to do the fade-out. One GUITexture on the right side of one camera; transparent at one side and going to black on the other side. Another GUITexture on the other camera similarly.

Other than that, you could use an image effect that basically does the same on each camera. But GUITextures would be faster.

Thanks for the idea.

Next question: We are setting up our development lab using a planar screen and projectors that have lens-shift, so no keystone correction or other image warping is needed. In the actual museum, we will be using much brighter and more expensive Christie projectors and will be projecting on a cylindrical screen, and due to the contraints of the theater dimensions, we will likely need to angle the projectors down from the ceiling (I don’t think the Christie’s have enough vertical lens shift to avoid this). So, we will have both keystoning and non-linear image distortion onto the cylindrical screen.

We could possibly account for all of this by rendering right and left screen images onto a mesh and warping the mesh vertices to correct for all of the projection distortion. Or we could buy Christie’s in-projector image warping cards (it doesn’t do overlap, but it may do edge blending). Is it correct to assume that we would need to use a regular texture mapped onto a mesh, instead of a GUITexture which seems only be a rectangular screen-space raster? Will we be able to use non-power-of-2 textures to do this? Should we just lay out the cash for the projector warping cards (about $7K apiece)?

Thanks again