GPU VCM
Re: GPU VCM
I currently use the Microfacet BRDF from "Physically Based Rendering - From Theory to Implementation": Blinn-Phong, Schlick's Fresnel, G from the book.
The material model is from SmallVCM: sampleBRDF() to obtain a direction with a probability proportional to the BRDF; evaluateBRDF() to get a probability for a given set of directions, extended with bidirectional evaluation. This is used consistently and greatly helps to reduce code complexity.
The BRDF evaluation is hardly branchless though, and involves moving from world to local space and back, as well as a 'pow', a 'sqrt', a 'sin' and a 'cos'. As a consequence, switching to Lambert (with the same interface, of course) affects performance quite a bit.
The material model is from SmallVCM: sampleBRDF() to obtain a direction with a probability proportional to the BRDF; evaluateBRDF() to get a probability for a given set of directions, extended with bidirectional evaluation. This is used consistently and greatly helps to reduce code complexity.
The BRDF evaluation is hardly branchless though, and involves moving from world to local space and back, as well as a 'pow', a 'sqrt', a 'sin' and a 'cos'. As a consequence, switching to Lambert (with the same interface, of course) affects performance quite a bit.
Re: GPU VCM
Great results as always 
Thing which is strange for me in "vcm gpu" video is that photons are very noticeable.
Directly visible photons correspond to CD.*L path which should have much lower MIS weight then BPT paths. Am I right?
Also in last two videos "BDPT with directional regularization" and "directionally regularizated light transport", caustics visible in mirror(CSDS.*L paths) has much less noise then CD.*L paths, I'm not familiar with with that algorithm itself but it looks very strange for me.

Thing which is strange for me in "vcm gpu" video is that photons are very noticeable.
Directly visible photons correspond to CD.*L path which should have much lower MIS weight then BPT paths. Am I right?
Also in last two videos "BDPT with directional regularization" and "directionally regularizated light transport", caustics visible in mirror(CSDS.*L paths) has much less noise then CD.*L paths, I'm not familiar with with that algorithm itself but it looks very strange for me.
Colibri Renderer
Re: GPU VCM
The directly visible photons should have a low MIS weight, but also carry quite some energy; perhaps this could explain their brightness?
I followed SmallVCM quite closely; the renderer converges to the correct image for 'easy' scenes (large light source, so that unidirectional path tracing can find it), so I assumed I got it 'right'.
Regarding the low noise levels in the mirror, and particularly in the caustic: I find that strange too; so I did some experiments:
- In general the mirorred caustic is not nearly as bright. This turns out to be caused by some clamping I am doing: paths carrying too much energy are normalized, then scaled to the maximum throughput. This greatly reduces fireflies, but introduces bias. Without the clamping, the caustic in the mirror converges slowly, due to the contribution of rare high energy paths. With the clamping, bias is significant for this feature.
- In general the floor viewed via the mirror is not as noisy as the floor seen directly. This effect goes away if I use a diffuse shader; for the microfacet BRDF the regularized bounces are actually less specular than the microfacet BRDF, which causes surfaces to converge quicker when seen in the mirror. After a few passes this effect goes away (the technique is consistent), but by that time, the noise is already low.
So... bias is affecting the renderer.
Does the above make sense? I'm trying to get a grasp on proper light transport so I'm not very confident it's all perfect.
I optimized it a bit since posting the video by the way: it runs at roughly twice the speed now. Looks like 16 samples is quite close to 'enough' for interactive rendering. It would also be interesting to see how some basic filtering would do with this kind of input.
I followed SmallVCM quite closely; the renderer converges to the correct image for 'easy' scenes (large light source, so that unidirectional path tracing can find it), so I assumed I got it 'right'.
Regarding the low noise levels in the mirror, and particularly in the caustic: I find that strange too; so I did some experiments:
- In general the mirorred caustic is not nearly as bright. This turns out to be caused by some clamping I am doing: paths carrying too much energy are normalized, then scaled to the maximum throughput. This greatly reduces fireflies, but introduces bias. Without the clamping, the caustic in the mirror converges slowly, due to the contribution of rare high energy paths. With the clamping, bias is significant for this feature.
- In general the floor viewed via the mirror is not as noisy as the floor seen directly. This effect goes away if I use a diffuse shader; for the microfacet BRDF the regularized bounces are actually less specular than the microfacet BRDF, which causes surfaces to converge quicker when seen in the mirror. After a few passes this effect goes away (the technique is consistent), but by that time, the noise is already low.
So... bias is affecting the renderer.
Does the above make sense? I'm trying to get a grasp on proper light transport so I'm not very confident it's all perfect.

I optimized it a bit since posting the video by the way: it runs at roughly twice the speed now. Looks like 16 samples is quite close to 'enough' for interactive rendering. It would also be interesting to see how some basic filtering would do with this kind of input.
Re: GPU VCM
Nice videos!
I'd recommend using a smaller radius for vertex merging, something close to the projected pixel size, which would remove the nasty photon splotches. With VCM you can most often get away with using a small radius (unlike in PPM), because in the areas where merging is important the photon density is typically high, and in regions where it isn't important other techniques are better (and will be weighted higher). Ideally you'd want to determine the merging radius for every pixel from the pixel footprint at the first non-specular surface. A slight modification to the MIS weight computation is necessary in this case, which I've described in section 8.5.1 of my thesis. The nice thing is that this will remove the generally very sensitive world-scale radius parameter from your render settings. If you still want to retain some control, you can have a global radius_scale parameter to multiply the footprint-determined per-pixel radius.
Question: On that scene with the mirror, what's the improvement you see with directional regularization over pure BDPT? I'm asking because directional regularization was originally designed to render "impossible" paths from point light sources and is pretty much equivalent to enlarging your light source a bit. And your scene has a decently sized light source already.
I'd recommend using a smaller radius for vertex merging, something close to the projected pixel size, which would remove the nasty photon splotches. With VCM you can most often get away with using a small radius (unlike in PPM), because in the areas where merging is important the photon density is typically high, and in regions where it isn't important other techniques are better (and will be weighted higher). Ideally you'd want to determine the merging radius for every pixel from the pixel footprint at the first non-specular surface. A slight modification to the MIS weight computation is necessary in this case, which I've described in section 8.5.1 of my thesis. The nice thing is that this will remove the generally very sensitive world-scale radius parameter from your render settings. If you still want to retain some control, you can have a global radius_scale parameter to multiply the footprint-determined per-pixel radius.
Question: On that scene with the mirror, what's the improvement you see with directional regularization over pure BDPT? I'm asking because directional regularization was originally designed to render "impossible" paths from point light sources and is pretty much equivalent to enlarging your light source a bit. And your scene has a decently sized light source already.

Re: GPU VCM
If I use a radius close to the projected pixel size the number of photons arriving per pixel is going to be low, right? That would probably lead to fireflies for quite a bit longer than the first 16-32 samples, which is the time frame I'm trying to optimize for.
As for the improvement of directional regularization over BDPT: it's also in this small time frame; the light cast by the mirror shows considerably less noise early on.
This is without any clamping. If I let it run longer, the dirreg actually starts to produce fireflies, I suppose because many near-specular interactions are evaluated.
As for the improvement of directional regularization over BDPT: it's also in this small time frame; the light cast by the mirror shows considerably less noise early on.
This is without any clamping. If I let it run longer, the dirreg actually starts to produce fireflies, I suppose because many near-specular interactions are evaluated.
Re: GPU VCM
Indeed, this will inevitably increase the noise in vertex merging and in the entire VCM as well, because the variance of vertex merging is inversely proportional to the squared radius.jbikker wrote:If I use a radius close to the projected pixel size the number of photons arriving per pixel is going to be low, right? That would probably lead to fireflies for quite a bit longer than the first 16-32 samples, which is the time frame I'm trying to optimize for.
This above is a great view point. I'd be very interested to see how pure BDPT, dirreg and VCM compare with a slightly higher number of samples (without clamping, of course)!jbikker wrote:As for the improvement of directional regularization over BDPT: it's also in this small time frame; the light cast by the mirror shows considerably less noise early on.

Re: GPU VCM
Here you go:
VCM, ~4spp:
VCM, ~32spp:
VCM, converged:
BDPT, ~4spp:
BDPT, ~32spp:
BDPT, converged:
dirreg, ~8spp:
dirreg, ~32spp:
dirreg, converged:
VCM versus BDPT, raw difference:

dirreg versus BDPT, raw difference:

Sample counts are approximate.
VCM, ~4spp:

VCM, ~32spp:

VCM, converged:

BDPT, ~4spp:

BDPT, ~32spp:

BDPT, converged:

dirreg, ~8spp:

dirreg, ~32spp:

dirreg, converged:

VCM versus BDPT, raw difference:

dirreg versus BDPT, raw difference:

Sample counts are approximate.
Re: GPU VCM
Made some progress:
Full quality video: http://www.cs.uu.nl/docs/vakken/magr/ma ... efront.avi
To be able to use BVHs instead of the hardcoded scene, I implemented wavefront path tracing. Took some time to get it efficient (and working
), but right now for the hardcoded scene the impact is ~40% which seems reasonable considering the massive I/O to global memory. Benefit of this approach is obviously that occupancy is restored to 100% due to compaction at several points, most notably before BVH traversal starts.
Next step is getting rid of the remaining hardcoded scene parts.
Full quality video: http://www.cs.uu.nl/docs/vakken/magr/ma ... efront.avi
To be able to use BVHs instead of the hardcoded scene, I implemented wavefront path tracing. Took some time to get it efficient (and working

Next step is getting rid of the remaining hardcoded scene parts.
Re: GPU VCM
Very nice! 500m rays/sec is fast.