From BlenderWiki

Jump to: navigation, search

This page is an overview of the work completed so far for the Google Summer Of Code 2008 project "Lightcuts for Blender".

Completed work

  • all three light types needed by the Lightcuts algorithm are supported:
    • omnidirectional (Blender's Lamp) - useful for particle systems or volume lights
    • directional (Blender's Sun) - useful to approximate environment maps
    • oriented (roughly equivalent to Blender's Spot, but with a fixed 180° cone) - useful to approximate area lights and as virtual point lights on surfaces while faking indirect lighting
Please note that by combining these three light types it's possible to fake most types of illumination. The Lightcuts algorithm does not use any other types of lights; area lights for instance are supported by placing a large number of oriented lights.
  • support for lambertian diffuse and Phong specularity
  • automatic conversion of environment maps
Through the "Environment map" slider in the lightcuts panel, it's possible to select the number of lights that are to be used to approximate environment lighting. The sampling is done through a spherical Hammersley sequence. A typical value for this can be 4096.
  • automatic conversion of area lights
Through the "Area lights light density" slider in the lightcuts panel, the density of lights per area light unit is selected. Be careful because the number of lights created overall can get high pretty quickly. No more than "Lights" get created though (check the console for error messages).
  • "False color" render layer
This is mostly a debug feature, but a very useful one in my opinion. Different colors are assigned to different samples according to some metrics. Currently, the red channel is proportional to the percentage of lights evaluated with respect to the total number of lights available. The green channel is proportional to the number of actual lights used (as opposed to light clusters) with respect to the number of lights used in total: what this means is that if I have 1000 lights in a scene, and a single pixel uses a cut size of 100 (that is, evaluates 100 lights), it's possible that none of these 100 lights is a part of the original set; they would be "light clusters" instead, each representing more than one of the original ones.
I always post the "False color" rendering along with the true one so that people can grasp how the algorithm behaves. In a "good scene" the false color rendering turns out almost bluish, which means that a small percentage of lights was sampled per pixel. Bright red/yellow areas are expected in dark areas, because the proportional error criterion allows for very small errors there; this is where the algorithm reaches the "max cut" limit as choosen in the UI.
  • initial UI
Currently most parameters can be configured through the "Lightcuts" panel available among the Scene buttons. It's important to stress that this has been implemented to allow testing and is not meant to be finalized as such. Still, it already gives an indication of the type of control the user would have.
  • minor/unrelated changes
    • Python API: added samplingMethod to Lamp object (can be added to trunk)
    • Added "Rendering time" to the available info of the Stamp feature.

Work to be done

The skeleton of the algorithm is basically completed. There are three major areas to improve it:

  • support for more Blender Internal features
My aim is to support most options in order for Lightcuts to be a viable rendering option for artists. Unfortunately this will not be possible with every single feature. Top priority are other diffuse and specular shaders.
To be more specific: in order to be compatible with Lightcuts, a rendering feature must have a boundable output. For instance, lights with curve falloffs are not boundable in general. Node materials could turn out problematic in this respect as well. If a trivial boundary (e.g. 1) is valid, the feature may be deemed "compatible" even though it doesn't take advantage of the full power of the Lightcuts algorithm: the tighter the boundary, the less computations are performed.
I have yet to analyze all cases in detail, but I roughly expect to support all lamp falloffs types (excluding curve falloffs); all diffuse/specular shaders (maybe excluding toon shaders?); bias; mirror and transparency (these should come mostly for free, according to the paper). SSS and blurry reflections, on the other hand, will probably not be supported: there are specific extension to the Lightcuts algorithm designed to support these features, and they would not be trivial to implement in this project's timeframe (maybe in the future...). As for node materials, my aim is to provide at least a partial support, reverting to some trivial boundary in the most complex cases.
When the set of unsupported features will become clear, a potential problem would be how to sanity check the current options. Should we just warn the users or we should actually validate each and every material used, etc.?
  • polishing existing features and improve image quality
    • environment map conversion could use some smarter algorithm, for instance an importance driven sampling (currently sampling is uniform)
    • when a very strong light is used together with a collection of weaker ones, aliasing problems become apparent; it should be possible to automatically generate softer shadows for stronger lights
    • trading banding for noise? an option to implement the "random representative" variant as described in the "Implementing Lightcuts" paper could be coded (still unsure about that: banding is apparent in several test renderings, but the causes are yet to be thoroughly investigated; and this doesn't seem to affect the renderings from the original paper)
    • check to see if "reconstruction cuts" is implementable without major disruptions to Blender code. "Reconstruction cuts", is a variant of Lightcuts described in the original paper: it's basically an optimized version of the algorithm for oversampled renderings.
  • a preprocessing step to compute fake indirect lighting via a "Instant radiosity"-like algorithm
A proof-of-concept implementation of this is included in the GSoC project aims. I did not promise a full implementation because even though the basic concept is pretty simple, a robust implementation able to handle most corner cases (or multiple light bounces) may well justify a GSoC project on its own. (Anyway, I'm willing to continue working on it even in the future).


  • visible banding, probably due to a bug; the results of the original paper don't show this, so unless they were carefully crafted I expect this to go away; at the very least, the "random representative" variant will be coded otherwise. See also this video [1] that shows a worrying flickering in a scene with fixed lights and a rotating object.
  • unsupported options
Right now you have to construct a scene carefully following a series of instructions (you can find them here or in my blog). Failing to do so may result both in rendering errors or in outright crashes.

Test renderings

Environment map renderings

  • Own model. 4096 lights, 12 min OSA 5. See how the algorithm spent more time in dark and heavily occluded areas.

UncleZeiv-SummerOfCode2008-campanile.png UncleZeiv-SummerOfCode2008-Campanile fc.png

  • Model from 3drender lighting tests. Two local lights and 3466 directional lights (from environment lighting). Notice how the local lights cast aliased shadows; this is a known issue (see future work section). Average cut size: 81.33.

UncleZeiv-SummerOfCode2008-monster.png UncleZeiv-SummerOfCode2008-monster-fc.png

Area light renderings

  • Model courtesy of Anfeo. One area light converted in 576 oriented lights. A comparison with QMC rendering in similar times is provided: while QMC 16 shadows are noisier, banding on the flowers' shadows is noticeable in the lightcuts rendering. It must be said that this setting is not particularly favourable to the lightcuts version due to the large occluded areas. It would be interesting to re-render this scene with an indirect lighting pass, when available. Average cut size: 122.85.

UncleZeiv-SummerOfCode2008-anfeo-lc.png UncleZeiv-SummerOfCode2008-anfeo-lc-fc.png UncleZeiv-SummerOfCode2008-anfeo-qmc16.png

  • Classroom test by evermotion. Several area lights converted as 5040 oriented lights. Average cut size: 247.31.

UncleZeiv-SummerOfCode2008-esame-lc.png UncleZeiv-SummerOfCode2008-esame-lc-fc.png

General lighting

  • Model courtesy of IvanM. 5600 point lights, rendering 12 minutes and 58 seconds.