Category: Graphics

Final touches

More than two months have gone by since I’ve last updated the Vistas progress log, and during this time, besides sitting for my exams (and passing all of them, thank God), I’ve started closing the first iteration of this project. I am pretty happy with the outcome, and more so considering the constraints within which research, design and development took place.

Since the last update, I’ve created a runtime typing system for better scene management and extension, modified the high level rendering pipeline, and re-written the effect system for the umpteen time. Although the former effect system was good, it was way too complex. The new version is simpler, but no less powerful.

I have also added an application framework for effortlessly setting up Vistas-based applications; now I’m working with Colin and Gordon to prepare some sort of sandbox within which we can have a unified graphics-physics-scripting system we can meddle with quickly and easily. The reason we’re working on a sandbox at this stage is simply that we need a showcase that is hassle free to set up.

Anyway, I’ll try to post in somewhat more detail next time. Before I leave I think credit is due to Mr. Paul Bourke for the cube map used in the screen shots above. As to what regards the Audi model, I don’t know who the author is – Ben, my brother, sent it to me, but he said he didn’t do it… oh, and thanks to Colin for UV mapping the model; it would have taken me ages to do.

Advertisements

Shadow mapping effect in place

I have finally formalised shadow mapping as an effect within the Vistas framework. The first implementation supports only directional and spotlight shadows, with a point light version still in the works. Adding shadows is now as trivial as placing shadow casters and receivers under an effect node and attaching a shadow mapping effect to the node; the rest is handled by Vistas.

Shadow mapping is basically a two-pass algorithm, where, during a first pass, a depth buffer is generated by rendering the scene from the point of view of the light source. During the actual rendering of the scene to the framebuffer, which occurs in a second pass, the depth information is used to determine whether a fragment is occluded from the said light source or not. The depth buffer is projected as a texture map over shadow receivers, and for every fragment drawn, its distance from the light source is compared to the respective value in the projected depth buffer. If the fragment’s depth information is less than that projected, it is closer to the light source and hence lit; if on the other hand, the depth value is less than the projected value, the fragment is being occluded by some closer object and is thus not receiving direct light from the light source.

Effects in Vistas can propagate rendering techniques (state information and shader programs) to their children. These, on their part, accumulate techniques and use them during rendering to generate a final image. Besides being capable of propagating techniques, effects can also specify a separate culling-sorting-drawing pass; this pass is applied either before the siblings are rendered or, in deferred fashion, right after them being drawn.

The first pass explained above was implemented through the separate culling-sorting-drawing pass; this is required as there is no guarantee that the objects visible to the active camera are actually the same as those contained within the frustum of the light whose shadows we are required to draw. Once the visibility set is generated and sorted, a simple shader is applied to render depth information to an offscreen texture. This first pass is performed before the geometry in the effect subtree is drawn. The second pass is simply carried out by propagating a technique which “darkens” the areas in shadow for a given shadow receiver. Although propagating this technique will force at least two drawing passes, the advantage lies in the fact that this effect works perfectly well with object materials that provide shadow-map-agnostic shaders. Obviously, there is nothing that prevents one from implementing a single pass version of the shadow map effect, as the framework fully supports it.

 

 

The return of the laptop

I have most of the effects system in place, but there are still some slight things which need to be reconciled with the rest of the framework. For instance, let’s say the scene graph contains a subtree onto which shadow mapping must be applied. For a directional or a spotlight source, the shadow map must be rendered in a separate pass, which may or may not contain the same geometry as that visible within the frustum of the main camera. Therefore, a separate culling pass is required with the frustum adjusted to match the position and direction of the light source. With a point source model, light is emitted equally in all directions; this requires the use of more shadow maps and thus more culling passes. The situation is pretty much the same where dynamic environment maps and mirrors are concerned, so I thought of extending the Effect interface to allow access to a set of cameras; these cameras are queried during the culling stage by the active culler and the potential visibility sets for the respective frustums are generated and stored. The culling need not occur every frame, of course, and the interface will provide a means to specify a caching strategy and the expiration of a visibility set. This is also a means to avoid multiple culling calls within recursive effects during the same frame.

First week without laptop

As ancient Chinese knowledge puts it: The probability of finding a stock NVIDIA video card for my Dell laptop at the local service centre is epsilon.

I had to regress into developing on my five year old desktop PC during the last week. Good thing I chose to furnish it with an X800 Pro back then; with the laptop undergoing open heart surgery at the service centre, I can at least test and run Shader 2.0 programs. Since the last update, I’ve implemented render targets in the driver abstraction layer, to allow for effects such as reflections and shadow maps, and cleaned bits and pieces of code here and there. I’ve also had a go at implementing a mirror effect, which turned out quite nice. Now that I am in process of formalising the effect system, I will re-code the reflection as an effect node in terms of the new framework.

In the meantime, I’ve attached some pictures showing the latest developments:

 

 

 

A simple ray-tracer

I’ve set up an album with some output pictures generated by a ray-tracer I wrote for a university project. No big deal, of course – my only regret is accidentally deleting the scene files when backing up the project.

The ray-tracer takes all parameter input from a configuration file and is a bit awkward to use; if I get around polishing it, I might as well put a download link in this space, hopefully with all source code included.