diff --git a/docs/docs/spark-viewpoint.md b/docs/docs/spark-viewpoint.md index 22e8cf4..201570c 100644 --- a/docs/docs/spark-viewpoint.md +++ b/docs/docs/spark-viewpoint.md @@ -24,6 +24,7 @@ const viewpoint = spark.newViewpoint({ depthBias?: number; sort360?: boolean; sort32?: boolean; + stochastic?: boolean; }); ``` @@ -46,6 +47,7 @@ const viewpoint = spark.newViewpoint({ | **depthBias** | Constant added to Z-depth to bias values into the positive range for `sortRadial: false`, but also used for culling splats "well behind" the viewpoint origin (default: `1.0`) | **sort360** | Set this to true if rendering a 360 to disable "behind the viewpoint" culling during sorting. This is set automatically when rendering 360 envMaps using the `SparkRenderer.renderEnvMap()` utility function. (default: `false`) | **sort32** | Set this to true to sort with float32 precision with two-pass sort. (default: `false`) +| **stochastic** | Set this to true to enable sort-free stochastic splat rendering. (default: `false`) ## `dispose()` diff --git a/examples/editor/index.html b/examples/editor/index.html index 70f5f71..887e68b 100644 --- a/examples/editor/index.html +++ b/examples/editor/index.html @@ -498,11 +498,6 @@ gui.addColor(guiOptions, "backgroundColor").name("Background color").onChange((value) => { scene.background.set(value); }); - // spark.defaultView.stochastic = true; - gui.add(spark.defaultView, "stochastic").name("Stochastic sort-free").listen().onChange(() => { - // spark.prepareViewpoint(); - touch(); - }); const debugFolder = gui.addFolder("Debug").close(); const normalColor = dyno.dynoBool(false); @@ -531,6 +526,8 @@ debugFolder.add(spark, "minAlpha", 0, 1, 0.001).name("Min alpha").listen(); debugFolder.add(spark, "premultipliedAlpha").name("Premultiplied alpha").listen(); + debugFolder.add(spark.defaultView, "stochastic").name("Stochastic sort-free").listen().onChange(touch); + const accumFolder = debugFolder.addFolder("Accumulator encoding").close();; accumFolder.add(spark.splatEncoding, "rgbMin", -1, 1, 0.1).name("RGB min").onChange(touch); accumFolder.add(spark.splatEncoding, "rgbMax", 0, 4, 0.1).name("RGB max").onChange(touch); @@ -779,8 +776,6 @@ lastTime = time; stats.begin(); - renderer.clear(true, true, false); - if (guiOptions.autoRotate) { frame.rotation.y += deltaTime / 5000; } diff --git a/src/SparkRenderer.ts b/src/SparkRenderer.ts index 3ebc25d..272cb99 100644 --- a/src/SparkRenderer.ts +++ b/src/SparkRenderer.ts @@ -535,9 +535,10 @@ export class SparkRenderer extends THREE.Mesh { // Alternating debug flag that can aid in visual debugging this.uniforms.debugFlag.value = (performance.now() / 1000.0) % 2.0 < 1.0; - // if (viewpoint.stochastic) { - // (this.geometry as SplatGeometry).instanceCount = this.uniforms.numSplats.value; - // } + if (viewpoint.display && viewpoint.stochastic) { + (this.geometry as SplatGeometry).instanceCount = + this.uniforms.numSplats.value; + } } if (viewpoint.target) { diff --git a/src/SparkViewpoint.ts b/src/SparkViewpoint.ts index 84bc4c3..4a5e51e 100644 --- a/src/SparkViewpoint.ts +++ b/src/SparkViewpoint.ts @@ -571,6 +571,11 @@ export class SparkViewpoint { if (this.stochastic) { activeSplats = numSplats; + // Render all splats in order since the Z-buffer + // will handle ordering. + for (let i = 0; i < numSplats; ++i) { + ordering[i] = i; + } } else if (numSplats > 0) { const { reader,