Real-time Environment Mapping in OpenGL
Environment Mapping, also known as Reflection Mapping is an efficient technique for simulating realistic reflections. In many cases a precomputed texture is rendered on the object which represents the environment surrounding scene.
The following image is an example from Wikipedia:
And the next is an environment mapped teapot it a room which "matches" the reflection texture:
While the classic static environment mapping looks awesome in a scene, perhaps with a rotating object as the reflective target, it is sightly lacking in challenge as with OpenGL it can be done rather easily. A common example will include a skybox and an object with the reflection cube-mapped onto the focal object.
For my prototype I wanted to create a reflective cube that in real-time could demonstrate environmental reflection. With such a system it would be fairly trivial to use the dynamically generated texture to make many simple objects appear reflective using cube mapping.
For those who just want to see the video, it is embedded below:
For others who want details, read on...
The small cubes and the 'room' surrounding the cube rotate at different speeds and distances to demonstrate the reflection. The yellow sphere represents the light source which is applied using a basic per-pixel fragment Shader. From some angles the reflection clearly shows the lighting application and the reflected faces of the orbiting cubes move from shadow to light.
The texture for each face of the cube is generated and applied independently. For each frame all movement calculations are carried out once, then the scene is rendered to a Frame Buffer Object (FBO) 6 times, once for each face of the cube. It is then rendered once more from the point of view of the observer, this time to the screen. The camera is positioned at the centre of the cube looking though a specific face and the scene is rendered. The camera uses a 90 degree field of view to capture the image the cube face should reflect whereas the camera used to observe the scene has a 45 degree field of view.
Currently for each frame the textures for all 6 sides are generated and rendered at quite a high resolution. If performance became an issue then only the sides visible to the camera could be considered and a lower resolution texture could be generated.
I also made a variation where the Shader mixes the result of the lighting calculations on the main cube with the texture to give the appearance of a slightly matted reflection.