High Quality Splatting #37

m-schuetz opened this Issue May 26, 2014 · 8 comments


None yet

3 participants


It'd be nice to get High Quality Splatting working again in the rewrite.

@m-schuetz m-schuetz self-assigned this May 26, 2014

Tried to do interpolation in one pass, ended up with this:
(only works in chrome canary or firefox aurora with draft extensions enabled, at the moment)

The idea is, that points are not rendered as flat disks but as a rounded object, like a ProlateSpheroid

The result is kind of like nearest neighbor interpolation which looks much better than the overlapping points you get with larger point sizes. Looks almost as good as the high quality splatting shader that potree had before except that not multiple fragments are blended together. Instead, one fragment is choosen.

It requires the EXT_frag_depth extension which is in draft state as of now and therefore not available in browsers by default.


Image of the result:

I'll commit this once the EXT_frag_depth extension is available at least in firefox and chrome by default.

mrdoob commented Aug 13, 2014

This is nice! I wasn't aware of this technique.


The first technique, High Quality Splatting on Today's GPUs, requires rendering to render targets with floating point precision. One target for depth pass, another for each attribute (color, normals, ...) and one for the normalization pass.
Here is an old demo with this technique: splats
I didn't look into three.js render targets, yet, but I plan to implement this again in the future.

The second one requires EXT_frag_depth extension and is trivial to implement but it's not finished, yet. At the moment, it does not account for the exponential change in depth and instead asumes it to be linear, therefore giving different results at close range, where the results are circles, again, and large distances, where occluded points suddenly bleed through.

I want to implement both with three.js again but due to other tasks it'll probably take me about 2-4 months. If you want, I can try to implement these right into the three.js code as a pull request.

If you want to have a look yourself, feel free to look at my implementations:

High Quality Splatting on Today's GPUs method:

ProlateSpheriod method:

Simple addition of gl_FragDepthEXT = ... but code needs to be changed to account for exponential depth.

<script type="x-shader/x-fragment" id="fs_interpolation">

    varying vec3 vColor;

    #extension GL_EXT_frag_depth : enable

    void main() {

        // make circular
        float a = pow(2.0*(gl_PointCoord.x - 0.5), 2.0);
        float b = pow(2.0*(gl_PointCoord.y - 0.5), 2.0);
        float c = 1.0 - (a + b);

        if(c < 0.0){

        gl_FragColor = vec4(vColor, 1.0);
        gl_FragDepthEXT = gl_FragCoord.z + 0.01*(1.0-pow(c, 2.0));


Seems like firefox and chrome now support the frag depth extension by default. Time to get this done!


gl_FragDepthEXT = gl_FragCoord.z + 0.01*(1.0-pow(c, 2.0)) * gl_FragCoord.w

Seems to work well, even though it's probably not 100% correct.
The idea behind it is, that points are rendered as circles but the farther a fragments location from the center of the circle, the larger the offset to the depth value.

gl_FragCoord.z: Original depth value
c: 1 at center, 0 at circle border
(1.0-pow(c, 2.0)): 0 at center, 1 at circle border and an modified falloff
multiplication by gl_FragCoord.w: transforming the linear depth offset to exponential depth offset in order for this to work in close range as well as far away. This is the part that's likely not 100% correct (w would have to be calculated newly for the offset position) but it works well enough.

@m-schuetz m-schuetz closed this Oct 28, 2014
pmoulon commented Oct 29, 2014

Very impressive ;-)
Impatient to test that one day with some openMVG photogrammetry based models ;-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment