Wednesday, 29 September 2010

Light volumes - animated character

Similar to my previous post but with an animated character this time round.

Animated Character
I went about texturing this model a little differently to usual so I thought I'd mention it. I'd normally lay out the UV's, pick a few nice base textures and start painting away in photoshop. I thought I'd try something different this time round, it's a technique I've seen used in lots of places and I was keen to try it. Instead of manually painting in all the rusted / chipped areas (which is actually a lot of fun) you use a bunch of masks and procedural noise to blend between different surface types. The image below shows a rust mask built from ambient occlusion, cavity, 3d noise and a scratchy bitmap. The ao and cavity maps provide rusted areas in the grooves and worn edges while the noise and scratch maps provide general wear and tear.

Below is the resulting texture map, rendered straight from the material editor. It could definitely use a pass in photoshop to add some more specific detail but it's fine for the time being. Rendering out spec and bump maps was also very easy.

With the textures done I animated a walk and idle cycle and exported the character into the engine. I've spent a lot of time on the mesh and animation exporter so thankfully the process isn't painful.

Okay, onto the actual video which came together pretty quickly. I already had a very basic animation system in place but it doesn't support blending so the animations do pop a bit. I also had to manually control the camera so the camera work isn't as smooth as the other videos. Environment wise I'm still using the same volume textures but I have boosted their contribution to the light buffer.

That's all folks, don't forget to switch it over to HD, hope you enjoy and thanks for reading :)

Thursday, 23 September 2010

Light Volumes – animated objects

Another excellent feature of light volumes not mentioned in my previous post is that both static and animated objects can be lit with the exact same data set. The video below shows this in action. It's in HD this time round so be sure and watch it full screen. As with the previous videos the frames were saved straight from the XNA render engine I'm working on.

Wednesday, 22 September 2010

Light Volumes – Sponza Attrium

In previous months I've posted several simple volume lighting tests. The screen shots were taken in my global illumination lightmap renderer so the results were fairly basic. I wanted to try using light volumes on a more complicated scene so I blew the dust off an old deferred render testbed and modified it to work with light volumes. I was about to build my own environment but remembered that Crytek had released their cracking version of the Sponza model so that's the model you see here. The model is largely unchanged although I've left out a few objects. The plants for one, mainly due to no alpha support in my render engine. I've also added some paper lanterns and a second UV channel for the ambient occlusion maps (see previous post).

Light volume generation

As before, a rough GI solution was first generated for the scene. This solution was then sampled to create the light volume textures. The rough solution, consisting of about 15 512x512 light maps and the light volumes took about 4 minutes to compute.

Screenshots taken from my GI light-map / light-volume renderer

Placing the light volumes was tricky, care needs to be taken that no sample point falls outside the scene or can “see” through to areas it shouldn't. The mid level floor and vaulted ceilings in particular took a few tries to get right. I used two volumes in this scene. It may have been possible to use just one but I wanted to attempt a scene with multiple volumes.

The smaller volume is 8x8x32 and the larger is 32x17x64

Scene rendering with light volumes

The deferred renderer I'm using renders in the following stages.

1. Render compressed view space normals, material roughness and depth to G-Buffer.

2. Render dynamic scene lights to light buffer.

3. Render volume lighting to light buffer.

4. Render final geometry using light buffer.

It wasn't hard to add an extra lighting stage to incorporate light volumes. The extra stage functions much like the existing light buffer stage. Geometry representing the light volume is drawn to the screen and the relevant area of the volume can then be sampled. Below is a breakdown of the lighting stages.

Static ambient occlusion (rendered offline in my lightmap renderer)

Dynamic direct light

Light volume ambient diffuse and specular

Final light buffer

As mentioned in the original paper (see references section) the light volume can also provide local environment specular. I initially underestimated this effect but it certainly makes a difference, especially in areas untouched by direct light. The images below show the effect well. A fresnel term also makes a big difference here, note the increased reflections on the wall in the second image.

In addition, a couple of images showing ambient specular and ambient diffuse in isolation.

Finally, two videos of the scene under seperate lighting conditions.

References / Links

Gamefest 2010, Lighting Volumes

HDR the Bungie way

Engel's Prepass Renderer (SIGGRAPH 2009)

Updated Crytek sponza model

Friday, 17 September 2010

Thin UV charts...

Been awhile but despite appearances I have had my nose to the pixelated grindstone. I'm hoping to have a nice light volume demo ready soon so I'm looking forward to showing that off. Until then I thought I'd share the solution to a niggling problem that's been bugging me for quite some time.

The problem occured when attempting to pack a lot of very thin UV charts into a lightmap. Sections of these thin charts would often fail to render leading to black splinters on the final lightmap. Figure 1 below demonstrates this. The pillar shown is one of 12 packed into a single 512x512 lightmap.

Figure 1. Thin UV charts fail to render and cause black splinters in the resulting lightmap.

The solution is very straight forward thankfully. All that needs to be done is to check the length of every UV edge and stretch any that are too close. Initially I checked each edge length and moved UV vertices whenever they were too close together. This lead to vertices sometimes being moved more than once and often in very different directions, leading to some pretty messed up UV's. Instead,  I found it was better to determine the average of these potential new vert positions, and then move the vert to that average position. Figure 2 shows the improvement.

Figure 2. Thin charts have been expanded, no more splinters.

The lightmap remains the same size and large UV charts are unneffected. I thought I'd post in case anyone else out there was having the same problem. This might only be a problem with Microsofts UVAtlas but I seem to recall it happens with Max's built in unwrap tool as well. If anyone is interested in the script let me know and I'll make it available.