So my last post was about the fact that mirrors had been implemented into the game, and now I have actually implemented the ability to create a reflective object. In the entity definition file there is a mtree tag. The mtree tag is used to define information about the entity’s mesh tree structure. I added an attribute to the mtree tag entitled flags. The flags attribute can set various flags for rasterization. Those flags include “unlit”, “reflective”, “noshadow”, “refractive”, and “transparent”. The unlit flag insures that lighting calculations are not performed when the entity is rendered, noshadow will signify that the entity does not cast a shadow (once shadows have been fully implemented), refractive is currently unusued, but if I ever find the need to create an entity that refracts the scene (as opposed to reflecting it, this will signify that the entity does that), transparent signifies that the entity is transparent, and so it should potentially be rendered last to insure that other entities can be seen behind it. The actually flags attribute can contain any combination of these flags. (e.g. <mtree … flags=”unlit|noshadow”>)
The most relevant to what I’ve implemented today, however, is the reflective flag. This signifies that the entity is reflective. Now, when an entity is flagged as reflective, if it is visible it is queued into a special reflective objects queue. Then the scene gets drawn as follows. All visible entities and map geometry are calculated. If any reflective entities were calculated they are rendered as described in the previous post (the visibility information of the reflected scene is stored in a different data structure than the visibility information of the actual scene). Finally the actual scene is rendered minus the reflective entities (which were rendered in the previous step).
The results can be seenin this image:
Reflective objects work in the following way. They reflect about the object’s XY plane, so the mesh must be setup appropriately to insure that the reflection looks correct. The object must have some kind of transparent texture where the mirror is, otherwise the reflection will be written over. Reflective objects cannot be transparent. (Because of the order that rendering occurs, they are drawn before anything else, and so any objects behind them will be discarded by the z-buffer.)
Along with that, the following limitations exist for reflective objects. Only a limited number of reflections may exist in one scene. Currently the number is hard-coded to 2. This is to insure that a large number of reflections are not present since they are computationally expensive. Reflective objects to not reflect other reflective objects. Certainly it would be possible to do this, but again it would be computationally expensive, I could create a depth limit as to how many reflections could be reflected, but in reality my current plans for the game do not include any need to do this. Also, I will most certainly implement some way for a reflective object to be reflected, only using a default texture for the mirror potion of the object.
Some buggy things that exist, that I will look into further. Currently if you look at a reflective object through one portal the reflection seems to be okay, but if you look at it through two portals the reflection sometimes seems to ignore portals further down the line. This seems to be hit or miss, so I will have to test further. Also, in some cases objects behind the reflection are not being properly clipped. This occurred more in the development phase and seems to have gone away. This seemed to be a driver problem, as I extensively test with clip planes and found that they did or did not work in certain circumstances. Again, this will need further testing.
Now I want to move onto the other topic which I’ve been working on, and that is lighting. A map may contain multiple lights, but obviously an entity isn’t going to be lit by every light on the map, that would be computationally expensive, and in reality and entity would be out of range of most lights in a map anyway. I had previously decided that each entity would be lit by the four closest lights to it, and so before an entity is rendered the four closest lights to it are computed. I actually discovered a bug in this computation, and repaired it, but besides that, I basically had the entity being lit equally by each light, even if one light was further away than another.
I had expiramented with different ways of getting the light to diminish over distance, but I finally settled on using a quadratic falloff equation. Each light has a range, and as an entity get’s further and further from the light, the intensity of that light decreases quadratically (or inverse quadratically as it is actually a square root). This creates the effect that the light intensity is fairly constant near the light source, but then right as it reaches the maximal range it quickly drops off to zero. The intensity is set to zero if the entity is out of range. This creates a much smoother transition as an entity moves around a map. In fact when the map is properly lit as the entity walks around it, it is barely noticeable that the lights being used to light it are different lights, when the lights change.
The new lighting is especially dramatic in the Sorpigal level (the second map seen in the 2nd tech demo).