Archive / Month / September, 2008

Luckily, I’ve been able to work full time for a while on the volume rendering code, as part of budgeted R&D time at work. Since Monday I’ve made a lot of progress, and have been committing code to the ‘sim_physics‘ SVN branch, maintained by Daniel Genrich.

I’m actually quite surprised at how quickly I’ve managed to come this far, I guess I can attribute it partially to the clear design of pbrt, which I’ve used as reference for the fundamental structure. So far, I’m getting close to having it at a reasonably well integrated state with the rest of the renderer. Perhaps tomorrow it’ll be at a state where particles could be rendered by just instancing spheres at each point.


Some of the changes so far include:

  • Fixed the shading bug I mentioned earlier, due to a limitation in the raytrace engine (before, after). Now shading works quite nicely.
  • Added colour emission – as well as the overall ‘Emit:’ slider to control
    overall emission strength, there’s also a colour swatch for the volume to emit
    that colour. This can also be textured, using ‘Emit Col’ in the map to panel.
  • Cleaned up and clarified volume texture mapping, fixing the offsets and scaling, and adding ‘Local’ (similar to Orco) mapping, alongside Object and Global coordinates
  • Added colour absorption – rather than a single absorption value to control how much light is absorbed as it travels through a volume, there’s now an additional absorption colour. This is used to absorb different R/G/B components of light at different amounts. For example, if a white light shines on a volume which absorbs green and blue
    components, the volume will appear red. This colour can also be textured.
  • Refactored the previous volume texturing code to be more efficient
  • Worked on integrating volume materials into the rest of the renderer. Now other objects (and sky) correctly render if they’re partially inside or behind a volume. Previously all other objects were ignored, and volumes just rendered on black. The colour of surfaces inside or behind the volume gets correctly attenuated by the density of the volume in between – i.e. thicker volumes will block the light coming from behind.
  • Enabled rendering with the camera inside the volume.

Correct shading and absorption

Shading with two lamps

Shading within clouds density texture

Textured (with colour ramp) emission colour

Example of various absorption colours

Textured absorption colour

Objects and sky inside and behind volume

Shaded concave volume

Camera passing through a volume

This week, it’s been very exciting to publicly show a project that’s in the works for some time: Kajimba. It’s a CG animated comedy series for mature audiences (though not pornographic!) about a ragtag bunch of animals in the distant Australian outback, hanging out at the only pub for thousands of km. Kajimba has been in progress in-house at ProMotion since before I started working there, but in the last year has finally gathered momentum, going from what was originally a concept, some sketches and a few early character models, to now, where we’ve done a good few minutes of rendered character animation tests, and production on the first (out of 26 slated) 5 minute episode has begun.

At the present, it’s self-funded by the studio, so it’s taking time to develop alongside other paid work. The benefit of this is that we can do what we want, which working out great so far. It’s not certain how the episodes will be delivered, whether it gets picked up by a TV network or if we’ll try something different. At this stage, we’ll concentrate on getting a first episode done and see how we go from there. It’s a great concept, very aussie, and very exciting. We should hopefully have some first voice recordings happening soon along with more and more images and animation tests coming down the wire so keep an eye on the blog and check on our progress!


Some of you may be aware of the great work done so far by Raúl Fernández Hernández (“farsthary“) concerning volume rendering in Blender. For those not in the know, rendering volumes of participating media as opposed to solid surfaces, has many uses such as realistically rendering smoke, fire, clouds or fog, or even with more complicated techniques, rendering volume density data such as MRI scans for medical visualisation.

Raúl completed a fair bit already, implementing this in Blender. Living in Cuba, where he doesn’t enjoy the same kind of connectivity as in many other parts of the world, it’s been difficult for him to participate in development and share his work. A few weeks ago, he emailed me asking for help with his code, and with maintaining it publicly. I promised I’d at least have a look at the first patch he was able to release and see what I thought.


In some spare time, I had a go at taking apart his patch. Unfortunately, it became clear that it wasn’t suitable for immediate inclusion. It was Raúl’s first time coding in Blender (or perhaps in 3D) and due to this, wasn’t aware of some of the techniques available to make his life easier, or of how to integrate the code as cleanly as it could or should be. On top of this, working alone without being able to easily communicate with other developers, he’d been working hard on adding more and more features and options on top of a structure which I think could be done differently and a lot cleaner at a fundamental level. This led to some quite complicated code, and a tricky UI for artists to interact with.

I proposed to Raúl that I start again from scratch, simpler and more cleanly integrated and then merge in what I could later down the track, step by step, to which he was very enthusiastic. He excitedly agreed with my invitation to work closely on integrating things like the simulation work he’s been doing, once a new structure is well defined. Recently in a few days off from work I sat down and started fresh, based on the approach in Physically Based Rendering.


Spot light in constant density volume

3 point lights in constant density volume

Textured spot light in constant density volume

So far I’ve got it working reasonably well with about 90% new code. Unlike before, it’s following a physically based approach, with a region of constant or variable density, calculating light emission, absorption, and single scattering from lamps. My aim is to get a simple, easier to use version ready, optimised for practical rendering tasks like smoke, fire or clouds. Once this is working perfectly, integrated cleanly and completely, and working in Blender SVN, further down the track we can think about adding some of the less common capabilities like isosurfaces or volume data sets.


Cloud texture controlling density, lighting from volume emission only

Cloud texture controlling density, 3 lights with single scattering

Spherical blend textures controlling density, directional light with single scattering

There’s still a lot to do – there’s one remaining bug with single scattering I must try and track down, and then there’s a lot of integration work to do, calculating alpha, rendering volumes in front of solid surfaces etc. Before too long I’ll commit this to the newly created ’sim/physics’ SVN branch and work on it in there. I don’t know how long it will be before Raúl is able to start working on this again too, since he’s under some horrible circumstances after hurricane Gustav ravaged Cuba. At least in the near term, I’ll be able to continue poking away at this in SVN.

Some things on my want-to-do list include:

  • Plenty of optimisations
  • Adaptive sampling – step size and/or early termination
  • Alternative anisotropic phase (scattering) functions such as Mie or Henyey-Greenstein
  • Wavelength (R/G/B) dependent absorption, so light gets tinted as it travels through a medium
  • An optimised bounding box or sphere ‘volume region’ primitive, which could be much faster than raytracing meshes as is done now
  • Multiple layers deep ray intersections, to enable concave meshes or volume meshes in front of volume meshes
  • Rendering Blender’s particle systems, either by creating spherical ‘puffs’ at each particle as Afterburner or PyroCluster do, or perhaps by estimating particle density with a kd-tree or such

I hope to be able to provide some more updates on this before too long!

I recently posted on blenderartists.org in response to some questions and misunderstanding about gamma correction and ‘linear workflow’ in 3D rendering.

I thought I’d re-post it here, since there are a lot of misconceptions about this topic around.


Much of the value of a linear workflow comes with rendering colour textures. But as the name suggests, it’s a workflow, that has to be kept in mind throughout the entire process.

The issue is that when you make a texture, either painting it in Photoshop to look good on your screen, or as a JPEG from a camera, that image is made to look good under gamma corrected conditions, usually gamma 2.2. So as you paint that texture, you’re looking at it on a monitor that’s already gamma 2.2, which is not linear. This is all well and good, displays are already gamma corrected to better fit the range of human vision.

The problem starts though, when you use those colour maps as textures in a renderer. When you’re doing lighting calculations in a renderer, those take place in a linear colour space. i.e – add 2x as much light, and it gets 2x brighter. The problem is that your colour textures aren’t like that if they’re at gamma 2.2. What’s double in numerical pixel values in gamma 2.2 is not necessarily twice brighter perceptually. So this breaks the idea of taking brightness information from a colour texture and using it in lighting/shading calculations, especially if you’re doing multiple light bounces off textured surfaces.

So what a linear workflow means, is that you take those colour textures, and convert them back to linear space before rendering, then you gamma correct/tonemap the final result back to gamma space (for viewing on a monitor). Now the lighting calculations work accurately, however it does change things – because the textures get darkened in the midtones the image can look darker, so you need to change the lighting setup, etc. etc. Hence, workflow – it’s something you need to have on all throughout the process, not just applying gamma at the end.

I wrote some code a little while ago that did it all automatically in the shading process, applying inverse gamma correction for colour textures before rendering, then corrected back to gamma 2.2 afterwards. After adjusting lights from old scenes to have the same appearance, it gave some nice results. It seemed to bring out a lot more detail in the textures, which got washed out before (left is normal, right is with linear workflow). It’s not finished though, it also needs to adjust the lights in the preview render, and inverse gamma correct colour swatches too so the flat colours you pick in the UI are also linear.

Further references:

We recently finished a 15 second commercial for Striderite Slimers a new childrens’ shoe made in conjunction with Nickelodeon in the US. It involved heavy use of fluid sim, with all the sim, animation and rendering done in Blender.

You can see some images and video at our website below, and also a zoomed out openGL view of the big splash. The project has also been featured on It’s Art Magazine, and BlenderNation.


|