SPPM - LuxRender Wiki
Luxrender GPL Physically Based Renderer


Personal tools

From LuxRender Wiki

Jump to: navigation, search


SPPM "Stochastic progressive photon mapping"

Intro to SPPM

Stochastic progressive photon mapping, or SPPM, is a consistent (see Hachisuka's site for more details) photon mapping method. Traditional photon mapping is inconsistent due to the limited number of photons. Eventually, the photon-shooting pass must end so the rendering can start. This means that some light path + photon combinations will inevitably be missed. In addition, the ray must consider photons in a radius around the hitpoint, allowing more bias to creep in when the renderer thinks it hit a photon it really should not have hit.

SPPM gets around the first problem of limited photons by repeating the photon-pass/eye-pass seqeunce again and again until told to stop. So eventually, any possible light path + photon combo will be hit. It gets by the second problem by slowly tightening the search radius around the hitpoint each time it goes around.


SPPM render panel in Blender 2.5

While SPPM has several more settings than the path-tracing integrators, it is still consistent. Meaning that, barring any insane settings, it will eventually converge to a correct result. Tuning the settings is only to speed things along.

max. eye depth

This is the maximum recursion depth for rays traced from the eye (camera).

max. photon depth

This is the maximum recursion depth for rays traced for the lights, which are used to deposit photons.

photons per pass

The number of photons to store before ending the "photon half" of the pass, and moving on to the next pass.

This is the main setting you want to focus on when tuning SPPM. It balances how long LuxRender will spend working on photons vs working on eye rays. (Each pass uses a number of eye rays equal to the number of pixels in the image, distributed randomly)

If you are getting a lot of low-frequency noise (aka, your image is very blotchy) but very little grain, that means you have too few photons compared to eye rays, and need to increase this value. If you are getting the opposite, and grainy, blotch-free image, you are spending too much time with photons, and need to back this off.

start radius

This is the search radius that will be used to connect eye rays to photons during the first pass. In other words: When a ray from the eye strikes a surface, LuxRender will look for nearby photons to figure out the light contribution. This value defines how far away from the hit point it will look, during the first pass. The search radius will tighten on subsequent passes.

In most cases, the start k parameter will automatically fix the radius if it turns out to be far larger than you intended. So this paramater can generally be left at the default setting.


In order to get the search radius for each pass after the first one, LuxRender uses the algorithm from "Progressive Photon Mapping: A Probabilistic Approach".

On the first pass, the radius is reduced by alpha, so R1 = alpha * R0, on the second pass, the radius is reduced by (1 + alpha) / 2. On the n-th pass, the radius is reduced by (n + alpha) / (n + 1).

So the radius reduction will slow down over time. This is mandatory for the theory to work (ie: reduce bias and noise through time), but it is also one of the reasons why SPPM depends so much on the initial radius.

lookup accelerator

This defines how LuxRender stores the hit point values. The default of "hybrid hash grid" is best in most cases. Parallel hash grid uses less memory than hybrid hash grid, with some performance penalty.

pixel sampler

This setting changes the pattern LuxRender will use to sample the eye pass. The default is Vegas, which will move through the image pixel-by-pixel at random. Other options are Hilbert and Tile, which render in blocks, and Linear, which will render in horizontal strips.

Vegas ensures an even distribution of work across all cores, but does not have as good of cache coherency as the other modes. It will probably be slightly slower than the other three, except on scenes which have a "difficult spot" in one part of the image. You will most likely not see a difference among the other three modes with most scenes.

photon sampler

The photon sampler controls how the photons are distributed. Halton will launch them using a halton sequence. This is a "dumb" sampling method, and is effectively random. The other option, adaptive markov chain, will attempt to fire photons in relevant areas, where they can actually be picked up by the camera. It is more effective at dealing with difficult light paths, although it is slightly slower.

store glossy

Enabling this will force use of the photon map for glossy surfaces. This can improve performance, but can add artifacts

include environment

Include background environment. In most cases, this should be left enabled.

direct light sampling

Enables direct light sampling at hitpoint intersections. Generally, this should be left enabled except on scenes where all lights are covered by geometry

Tuning SPPM

Tuning SPPM is much easier than tuning Exphotonmap, this is due to the nature of SPPM continuously shooting more and more photons. This means that you do not have to set the amount of each kind of photon. But you will need to adjust the initial starting radius (size of the photons, larger has more initial bias), and the rate of radius reduction (alpha).

Getting good results with SPPM depends a lot on scene scale. The start radius is directly related to the scene scale. The larger the scene the smaller the photon size will be.

Example: Rendering a studio shot of a diamond ring.

LuxRender is physically based. That means, if you want good results you should model things to actual real world dimensions. The problem with that is, if you put a 2cm ring with a 4mm diamond in a room that is 5x5 meters with lights, the initial actual real world size of the photons will be so small that it would be nearly impossible to actual render the caustics effectively. This is because the start radius of the photons is linked to the very large room (overall bounding box of the entire scene) the very small ring is in. Bidirectional + Metropolis does not care and will render the scene regardless. If we put the ring in a smaller studio setting, let's say the equivalent of using a piece of copy paper with a small light nearby, the real world size of the starting photon radius will be large enough to render the scene properly and will then be able to, over time, reduce enough to display sharp caustics.