Working prototype. Initialization not consistent.

This commit is contained in:
Andreas Sundquist
2025-07-22 14:45:06 -07:00
committed by Andreas Sundquist
parent df6b1d8f4a
commit d707f283f5
5 changed files with 51 additions and 20 deletions
+7 -4
View File
@@ -498,6 +498,11 @@
gui.addColor(guiOptions, "backgroundColor").name("Background color").onChange((value) => { gui.addColor(guiOptions, "backgroundColor").name("Background color").onChange((value) => {
scene.background.set(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 debugFolder = gui.addFolder("Debug").close();
const normalColor = dyno.dynoBool(false); const normalColor = dyno.dynoBool(false);
@@ -524,10 +529,6 @@
debugFolder.add(spark.defaultView, "sort32").name("Float32 sort").listen(); debugFolder.add(spark.defaultView, "sort32").name("Float32 sort").listen();
debugFolder.add(spark, "maxPixelRadius", 1, 1024, 1).name("Max pixel radius").listen(); debugFolder.add(spark, "maxPixelRadius", 1, 1024, 1).name("Max pixel radius").listen();
debugFolder.add(spark, "minAlpha", 0, 1, 0.001).name("Min alpha").listen(); debugFolder.add(spark, "minAlpha", 0, 1, 0.001).name("Min alpha").listen();
spark.defaultView.stochastic = true;
debugFolder.add(spark.defaultView, "stochastic").name("Stochastic sort-free").listen().onChange(() => {
spark.prepareViewpoint();
});
debugFolder.add(spark, "premultipliedAlpha").name("Premultiplied alpha").listen(); debugFolder.add(spark, "premultipliedAlpha").name("Premultiplied alpha").listen();
const accumFolder = debugFolder.addFolder("Accumulator encoding").close();; const accumFolder = debugFolder.addFolder("Accumulator encoding").close();;
@@ -778,6 +779,8 @@
lastTime = time; lastTime = time;
stats.begin(); stats.begin();
renderer.clear(true, true, false);
if (guiOptions.autoRotate) { if (guiOptions.autoRotate) {
frame.rotation.y += deltaTime / 5000; frame.rotation.y += deltaTime / 5000;
} }
+13
View File
@@ -260,6 +260,7 @@ export class SparkRenderer extends THREE.Mesh {
private lastUpdateTime: number | null = null; private lastUpdateTime: number | null = null;
// List of cameras used for the current viewpoint (for WebXR) // List of cameras used for the current viewpoint (for WebXR)
private defaultCameras: THREE.Matrix4[] = []; private defaultCameras: THREE.Matrix4[] = [];
private lastStochastic: boolean | null = null;
// Should be set to the defaultView, but can be temporarily changed to another // Should be set to the defaultView, but can be temporarily changed to another
// viewpoint using prepareViewpoint() for rendering from a different viewpoint. // viewpoint using prepareViewpoint() for rendering from a different viewpoint.
@@ -533,6 +534,10 @@ export class SparkRenderer extends THREE.Mesh {
this.uniforms.deltaTime.value = deltaTime; this.uniforms.deltaTime.value = deltaTime;
// Alternating debug flag that can aid in visual debugging // Alternating debug flag that can aid in visual debugging
this.uniforms.debugFlag.value = (performance.now() / 1000.0) % 2.0 < 1.0; 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.target) { if (viewpoint.target) {
@@ -577,6 +582,13 @@ export class SparkRenderer extends THREE.Mesh {
this.uniforms.clipXY.value = this.clipXY; this.uniforms.clipXY.value = this.clipXY;
this.uniforms.focalAdjustment.value = this.focalAdjustment; this.uniforms.focalAdjustment.value = this.focalAdjustment;
if (this.lastStochastic !== !viewpoint.stochastic) {
this.lastStochastic = !viewpoint.stochastic;
this.material.transparent = !viewpoint.stochastic;
this.material.depthWrite = viewpoint.stochastic;
this.material.needsUpdate = true;
}
if (this.splatTexture) { if (this.splatTexture) {
const { enable, texture, multiply, add, near, far, mid } = const { enable, texture, multiply, add, near, far, mid } =
this.splatTexture; this.splatTexture;
@@ -638,6 +650,7 @@ export class SparkRenderer extends THREE.Mesh {
this.geometry = geometry; this.geometry = geometry;
this.material.transparent = !this.viewpoint.stochastic; this.material.transparent = !this.viewpoint.stochastic;
this.material.depthWrite = this.viewpoint.stochastic; this.material.depthWrite = this.viewpoint.stochastic;
this.material.needsUpdate = true;
} else { } else {
// No Gsplats to display for this viewpoint yet // No Gsplats to display for this viewpoint yet
this.uniforms.numSplats.value = 0; this.uniforms.numSplats.value = 0;
+3 -1
View File
@@ -569,7 +569,9 @@ export class SparkViewpoint {
let activeSplats = 0; let activeSplats = 0;
let ordering = this.orderingFreelist.alloc(maxSplats); let ordering = this.orderingFreelist.alloc(maxSplats);
if (numSplats > 0) { if (this.stochastic) {
activeSplats = numSplats;
} else if (numSplats > 0) {
const { const {
reader, reader,
doubleSortReader, doubleSortReader,
+5 -6
View File
@@ -28,6 +28,7 @@ out vec4 fragColor;
in vec4 vRgba; in vec4 vRgba;
in vec2 vSplatUv; in vec2 vSplatUv;
in vec3 vNdc; in vec3 vNdc;
flat in uint vSplatIndex;
void main() { void main() {
vec4 rgba = vRgba; vec4 rgba = vRgba;
@@ -72,18 +73,16 @@ void main() {
} }
if (stochastic) { if (stochastic) {
uint uTime = floatBitsToUint(time); const bool STEADY = false;
uint uTime = STEADY ? 0u : floatBitsToUint(time);
uvec2 coord = uvec2(gl_FragCoord.xy); uvec2 coord = uvec2(gl_FragCoord.xy);
uint state = uTime + 0x9e3779b9u * coord.x + 0x85ebca6bu * coord.y; uint state = uTime + 0x9e3779b9u * coord.x + 0x85ebca6bu * coord.y + 0xc2b2ae35u * uint(vSplatIndex);
state = state * 747796405u + 2891336453u; state = state * 747796405u + 2891336453u;
uint hash = ((state >> ((state >> 28u) + 4u)) ^ state) * 277803737u; uint hash = ((state >> ((state >> 28u) + 4u)) ^ state) * 277803737u;
hash = (hash >> 22u) ^ hash; hash = (hash >> 22u) ^ hash;
float rand = float(hash) / 4294967295.0; float rand = float(hash) / 4294967296.0;
// rand *= 2.0;
if (rand < rgba.a) { if (rand < rgba.a) {
fragColor = vec4(rgba.rgb, 1.0); fragColor = vec4(rgba.rgb, 1.0);
// gl_FragDepth = gl_FragCoord.z;
// fragColor = vec4(rgba.r, 0.0, 0.0, 1.0);
} else { } else {
discard; discard;
} }
+23 -9
View File
@@ -10,6 +10,7 @@ attribute uint splatIndex;
out vec4 vRgba; out vec4 vRgba;
out vec2 vSplatUv; out vec2 vSplatUv;
out vec3 vNdc; out vec3 vNdc;
flat out uint vSplatIndex;
uniform vec2 renderSize; uniform vec2 renderSize;
uniform uint numSplats; uniform uint numSplats;
@@ -21,6 +22,7 @@ uniform float time;
uniform float deltaTime; uniform float deltaTime;
uniform bool debugFlag; uniform bool debugFlag;
uniform float minAlpha; uniform float minAlpha;
uniform bool stochastic;
uniform bool enable2DGS; uniform bool enable2DGS;
uniform float blurAmount; uniform float blurAmount;
uniform float preBlurAmount; uniform float preBlurAmount;
@@ -39,16 +41,25 @@ void main() {
if (uint(gl_InstanceID) >= numSplats) { if (uint(gl_InstanceID) >= numSplats) {
return; return;
} }
if (splatIndex == 0xffffffffu) {
// Special value reserved for "no splat"
return;
}
ivec3 texCoord = ivec3( ivec3 texCoord;
splatIndex & SPLAT_TEX_WIDTH_MASK, if (stochastic) {
(splatIndex >> SPLAT_TEX_WIDTH_BITS) & SPLAT_TEX_HEIGHT_MASK, texCoord = ivec3(
splatIndex >> SPLAT_TEX_LAYER_BITS uint(gl_InstanceID) & SPLAT_TEX_WIDTH_MASK,
); (uint(gl_InstanceID) >> SPLAT_TEX_WIDTH_BITS) & SPLAT_TEX_HEIGHT_MASK,
(uint(gl_InstanceID) >> SPLAT_TEX_LAYER_BITS)
);
} else {
if (splatIndex == 0xffffffffu) {
// Special value reserved for "no splat"
return;
}
texCoord = ivec3(
splatIndex & SPLAT_TEX_WIDTH_MASK,
(splatIndex >> SPLAT_TEX_WIDTH_BITS) & SPLAT_TEX_HEIGHT_MASK,
splatIndex >> SPLAT_TEX_LAYER_BITS
);
}
uvec4 packed = texelFetch(packedSplats, texCoord, 0); uvec4 packed = texelFetch(packedSplats, texCoord, 0);
vec3 center, scales; vec3 center, scales;
@@ -85,6 +96,9 @@ void main() {
return; return;
} }
// Record the splat index for entropy
vSplatIndex = splatIndex;
// Compute view space quaternion of splat // Compute view space quaternion of splat
vec4 viewQuaternion = quatQuat(renderToViewQuat, quaternion); vec4 viewQuaternion = quatQuat(renderToViewQuat, quaternion);