One of the features we considered important for the next release of the Away3D engine (4.1) were real-time dynamic reflections, allowing for more realism and precision than the common static environment maps. In the dev branch of the engine, you can now find two flavours: reflections based on dynamic environment maps, and planar reflections.
Dynamic Environment Maps
This technique simply uses cube maps that are rendered to on the fly. Usually, they’re used for any non-planar surfaces, and while they can look convincing enough for complex models they do suffer the same flaws as normal environment maps. Since the scene is rendered for each face of the cube from a single point, the calculated reflections would obviously only be correct for that single point in space, but using it for relatively small and complex objects can look convincing enough. However, since it renders the scene 6 times, it can be slow for more complex situations.
The necessary functionality is exposed through CubeReflectionTexture, a class that can be used wherever a CubeTextureBase is expected: EnvMapMethod and variations, or even as a Skybox texture. I have yet to come up with a use for the latter case, though ;) To get the best results, it’s usually a good idea to set the CubeReflectionTexture’s position to the centre of your reflective object. The cube map will be generated from this point and on average will yield the best results for all other points.
For planar surfaces, a much cheaper approach and one that is very precise can be used. This means normal flat mirrors, polished floors, water, … which are quite common in games can be rendered much more effectively. Since the rules for reflection for the entire surface are the same, we can simply render the scene from a mirrored camera perspective. The only thing we need to make sure is that objects (or parts of objects) behind the mirror aren’t being rendered in this way. Usually, in OpenGL or DirectX, you’d simply introduce a new user-defined clip plane. Flash, however, doesn’t support anything of the sort. Instead, the projection matrix needs to be adapted so that the near plane becomes oblique; aligned with the mirrored plane, effectively clipping any straddling geometry along the mirror. Unfortunately, this also wreaks havoc on the far plane, which will starting cutting geometry that is in the mirrored view due to being at a different angle. Eric Lengyel effectively describes the issue and how he cleverly solves it in his Oblique View Frustum paper. (And while I’m at it, his book is awesome too.)
The texture target is provided as PlanarReflectionTexture. Similar to the cube maps, they need some information about where their respective reflective surfaces are. In this case, it’s the plane property; referencing a Plane3D object. Furthermore, it has a “scale” property that lets you define how much the texture should be scaled down to control quality vs rendering speed. Due to the different math and texture types involved, PlanarReflectionTexture can only be used with specific material methods. Currently, these are PlanarReflectionMethod and FresnelPlanarReflectionMethod. Except for internals and texture type, these function pretty much identical to their EnvMap counterparts.
In closing, this is of course only in the dev branch, which means it’s still subject to change!