gkjohnson / three-gpu-pathtracer

Path tracing renderer and utilities for three.js built on top of three-mesh-bvh.
https://gkjohnson.github.io/three-gpu-pathtracer/example/bundle/index.html
MIT License
1.27k stars 125 forks source link

Improve stratified sample strategy #530

Open gkjohnson opened 4 months ago

gkjohnson commented 4 months ago

Related to #527, #449

There should be some way to de-correlate samples a bit more since at the moment all samples across the image are sampling from the same stratum with a common x and y offset. This results in highly correlated samples that expose the sampling patterns of shapes. This results in some swirling patterns especially when any spherical sampling is done. The shuffling approach could possibly also use some improvement.

Thoughts:

gkjohnson commented 4 months ago

The core issue is that we only have a single blue noise value which is used to offset both a X and Y across the strata so it's correlated between both axes. Using an offset that's spread well across both X and Y (and Z if possible) would be best. Perhaps some kind of 2d blue noise point pattern. The blue noise pattern could be reshuffled into a 2d point based on intensity value across the image

gkjohnson commented 4 months ago

Using the blue noise texture to derive evenly space points seems to not produce a smooth result. Possibly worth making sure the points are actually evenly spaced? Or maybe using another poisson or halton sequence numbers or another approach.

Before After
image

Point generation


    this.image.data = new Float32Array( ( size ** 2 ) * 2 );
    this.format = RGFormat;

    const result = generator.generate();
    const bin = result.data;
    const maxValue = result.maxValue;

    const newData = this.image.data;
    for ( let i = 0; i < maxValue; i ++ ) {

        const index = bin.indexOf( i );
        const x = index % size;
        const y = Math.floor( index / size );
        newData[ 2 * i + 0 ] = x / size;
        newData[ 2 * i + 1 ] = y / size;

    }
``
gkjohnson commented 4 months ago

Some other noise approaches to use:

https://developer.nvidia.com/blog/rendering-in-real-time-with-spatiotemporal-blue-noise-textures-part-1/