Foreword
If you believe I had unknowingly trespassed on copyrights of other individuals/organizations in the data files or materials, please let me know!!! I'm just a coder; I am not Sweeney, Carmack or God. Hence I tend to make mistakes and I tend to make a lot of them. If there is any misinformation that I have written, please let me know by email here and I'll be glad to update the documents in question. Disclaimer
Target Audience
Tools
Sample Apps
Author
IntroductionThis discussion on the VCP reflection technique comes with a sample program, which I implemented to demonstrate the method discussed. I will not refer much to the source code of the sample program (maybe only some important functions or notes), instead I will concentrate on the theory behind this whole VCP thingy. The reason for doing this is that the sample source is not really long and it had quite a load of comments thrown in, you should be able to follow it easily after reading this paper. Source code is supposed to be self-explanatory, at least to coders. I'm actually typing this introduction last and had actually just come out of a debugging session where I found a special case in the calculation of the rotation matrix, which I did not take care of previously. The model for the sample program, which I constructed in MilkShape3D, had a brick wall that I wanted to paste the mirror onto. This brick wall somehow happens to face the exact direction that triggers the special case I did not take care of. The point here is, if I did not set out to write this paper in the first place, I would never have found out about this "slip of mind" case, well maybe not never, but probably not as soon as I would like to. As Michael Abrash of Id Software had so pragmatically put it in this article: Learn now pay forward! Let's begin! I will be describing the technique in DirectX's convention using the Left Hand coordinate system. For OpenGL, which uses the Right Hand coordinate system, appropriate reminders will be given at different point throughout this paper. The virtual camera position is one of the many environment-mapping techniques employed in 3D graphics. I call it Virtual Camera Position (VCP) because I really couldn't come up with any other meaningful names and there seems to be no standard naming conventions for this kind of things. Someone pointed out to me that this form of reflection generation technique could be term under "portal rendering", but there are probably dozens of books with a dozen different names to call. I could call it Virtual Eye Point, but what's wrong with Virtual Camera Position? :-) This technique is perhaps the most intuitive for doing reflections in 3D. Check out any junior school physics textbook and chances are, you would come across the following figure: For any reflective surfaces in nature, the incident angle of a light ray will be equal to the reflection angle made by the reflection light ray. This is the hard and fast law of reflection. Noticed that we are talking about a single point on the reflective surface. The incident angle and reflection angle varies across the entirety of the reflective surface. The idea is simple: What the mirror shows is similar to what is seen in the direction of the reflected ray. This means that we simply need to render the scene in the direction of the reflected ray from the virtual camera position (hence the name) in order to get the correct reflection. This turns out to be a "pixel perfect" method of doing mirror reflections as long as the texture size used is equal to or above the pixel width and height of the rendered mirror. For example, if you are rendering at a screen resolution of 800x600 and choose to use a 256x256 texture for the reflection, the reflection quality would deteriorate when the camera goes really close to the mirror. The deterioration is due the mirror covering a large portion of the 800x600 screen area with only a 256x256 resolution texture. MotivationI recently read a description of an Image Of The Day (here) posted at flipcode. It's a nice demonstration of how mirrors could be done in a game scene. The technique, in brief terms, talks about attaching a camera to a mirror plane and rendering from that camera position behind the mirror. This approach has several limitations such as a no-objects-behind-mirror constraint and inaccurate reflections at most positions (Its meant to simulate reflection, not accurately produce them). This wasn't the motivation for doing a research on robust 3D reflection since I was already actively working on 3D reflections at that time. But that IOTD's method can be seen as a toned down method of the Virtual Camera Position that I am describing here. By the way, the real motivation was the mirror reflections I saw in the Doom3 video clip showed during QuakeCon 2002. Let's get to the real stuff! Simple Light RayReferring back to Figure 1 on basic incident and reflection angle representation when a ray of light hits a reflective surface, we could get to the following 2D representation of a VCP projection mechanism: For every frame rendered, the mirror could show a physically correct and accurate reflection simply by rendering the reflection from the corresponding VCP. The VCP changes whenever the camera translates in world space. The main thing to be done to render the reflection correctly from the VCP is to get the correct projection and view matrix (Sorry OpenGL people, Direct3D have a view matrix!). This concept borders on the verge of simplicity and perfect physical sense, but probably not on the ease of implementation frontier, not unless you have a good understanding on 3D vector space and how projection matrices are calculated (I don't!). |
|