Cg Programming/Unity/Mirrors

This tutorial covers the rendering of plane mirrors.

It does not require any shader programming (unless you want to use it with stereo rendering) but it does require some understanding of and of texturing as discussed in.

Rendering Plane Mirrors
There are various ways of rendering plane mirrors in computer graphics. If rendering to textures is possible, the most common method consists of the following steps: This is the basic method. Let's implement it.
 * Mirror the main camera's position at the mirror and place a “mirror camera” at this mirrored position behind the mirror.
 * Render the scene from the point of view of the mirror camera using the mirror plane as view plane. Render this image to a render texture.
 * Use the render texture as texture of the mirror when rendering the scene with the main camera.

The first issue is to obtain the position of the main camera. For monoscopic cameras, this is just  of the camera. For stereoscopic cameras, we have to decide whether we use the position of the camera for the right eye or the camera for the left eye. We can get the view matrix of a camera  for the right eye with and the view matrix for the left eye with The inverse of the view matrix transforms the origin of the camera coordinate system to the vector in the 4th column (3rd column if you start counting with 0). Since the origin of the camera coordinate system is the position of the camera and the inverse of the view matrix transforms from camera coordinates to world coordinates, it follows that the 4th column of the inverse of the view matrix specifies the position of the camera in world coordinates. If the view matrix is stored in, we can obtain this vector with this code:

Mirroring the main camera's position at a plane can be achieved in various ways. In Unity, one simple way is to transform the main camera's position into the object coordinate system of a quad game object. Then one can easily mirror this position by changing the sign of its $$z$$ coordinate. This mirrored position is then transformed back to world space.

Here is a C# that implements this process:

The script should be attached to a new camera object (in the main menu choose Game Object > Camera) and be called. The  should be a set to a quad game object that represents the mirror and   should be set to the main game camera.

To use the  as view plane, we can use the script in, which should be attached to our new mirror camera. Include the line  in that script to make it run in the editor. Make sure to check  such that objects entering the mirror are clipped. If there are artifacts at the intersection of objects with the mirror plane, decrease the parameter  until these artifacts disappear.

To store the rendered image of the mirror camera in a render texture, create a new render texture by selecting Create > Render Texture in the Project Window. In the Inspector Window, make sure the size of the render texture is not too small (otherwise the image in the mirror will appear pixelated). Once you have a render texture, select the mirror camera and, in the Inspector Window, set the Target Texture to the new render texture. You should now be able to see the image in the mirror in the Inspector Window of the render texture.

To use the render texture as texture image for the mirror, apply a shader with texturing to the mirror quad, e.g., the Standard shader or the shader Unlit/Texture. Use the render texture for texturing like any other texture object. Note that you might have to rotate the mirror quad such that its front face is visible to the main camera. By default, the texture image will appear mirrored horizontally. However, there is an easy fix using the shader properties for textures: set the X coordinate of Tiling to  and the X coordinate of Offset to.

Stereo Rendering
For stereo rendering, we need two mirrored cameras: one for the left eye and one for the right eye. We also need one render texture for each eye. The texturing of the mirror has to make sure that each eye accesses its corresponding render texture. To this end, Unity provides a built-in shader variable, which is 0 for the left eye and 1 for the right eye.

A basic shader that takes both textures and returns the color from the texture for the currently rendered eye could look like this:

Limitations
There are several limitations of this implementation which we haven't addressed. For example:
 * multiple mirrors (you might have to share the same render texture for all mirrors)
 * multiple reflections in multiple mirrors (this is complicated because you need an exponentially increasing number of mirror cameras)
 * reflection of light in mirrors (each light source should have a mirrored partner to take light into account that is first reflected in the mirror before lighting an object)
 * uneven mirrors (e.g. with a normal map)
 * etc.

Summary
Congratulations! Well done. Some of the things we have looked at:
 * How to mirror positions at a plane by transforming them into the object coordinate system of the plane and changing the sign of the $$y$$ object coordinate.
 * How to render a camera view into a render texture.
 * How to use a mirrored render texture for texturing.