mirror of
https://github.com/storytold/spark.git
synced 2026-10-09 00:09:53 +00:00
Add minPixelRadius to skip splats below a given pixel radius (#184)
This commit is contained in:
@@ -57,6 +57,7 @@ const spark = new SparkRenderer({
|
||||
| **preUpdate** | Controls whether to update the splats before or after rendering. For WebXR this *must* be false in order to complete rendering as soon as possible. (default: `false`)
|
||||
| **originDistance** | Distance threshold for `SparkRenderer` movement triggering a splat update at the new origin. (default: `1.0`) This can be useful when your `SparkRenderer` is a child of your camera and you want to retain high precision coordinates near the camera.
|
||||
| **maxStdDev** | Maximum standard deviations from the center to render Gaussians. Values `Math.sqrt(5)`..`Math.sqrt(9)` produce good results and can be tweaked for performance. (default: `Math.sqrt(8)`)
|
||||
| **minPixelRadius** | Minimum pixel radius for splat rendering. (default: `0.0`)
|
||||
| **maxPixelRadius** | Maximum pixel radius for splat rendering. (default: `512.0`)
|
||||
| **minAlpha** | Minimum alpha value for splat rendering. (default: `0.5 * (1.0 / 255.0)`)
|
||||
| **enable2DGS** | Enable 2D Gaussian splatting rendering ability. When this mode is enabled, any `scale` x/y/z component that is exactly `0` (minimum quantized value) results in the other two non-zero axes being interpreted as an oriented 2D Gaussian Splat instead of the usual approximate projected 3DGS Z-slice. When reading PLY files, scale values less than e^-30 will be interpreted as `0`. (default: `false`)
|
||||
|
||||
@@ -540,6 +540,7 @@
|
||||
debugFolder.add(spark, "focalAdjustment", 0.1, 2.0, 0.1).name("Tweak focalAdjustment");
|
||||
spark.defaultView.sort32 = true;
|
||||
debugFolder.add(spark.defaultView, "sort32").name("Float32 sort").listen();
|
||||
debugFolder.add(spark, "minPixelRadius", 0, 16, 0.1).name("Min 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();
|
||||
|
||||
|
||||
@@ -84,6 +84,11 @@ export type SparkRendererOptions = {
|
||||
* @default Math.sqrt(8)
|
||||
*/
|
||||
maxStdDev?: number;
|
||||
/**
|
||||
* Minimum pixel radius for splat rendering.
|
||||
* @default 0.0
|
||||
*/
|
||||
minPixelRadius?: number;
|
||||
/**
|
||||
* Maximum pixel radius for splat rendering.
|
||||
* @default 512.0
|
||||
@@ -170,6 +175,7 @@ export class SparkRenderer extends THREE.Mesh {
|
||||
needsUpdate: boolean;
|
||||
originDistance: number;
|
||||
maxStdDev: number;
|
||||
minPixelRadius: number;
|
||||
maxPixelRadius: number;
|
||||
minAlpha: number;
|
||||
enable2DGS: boolean;
|
||||
@@ -294,6 +300,7 @@ export class SparkRenderer extends THREE.Mesh {
|
||||
this.needsUpdate = false;
|
||||
this.originDistance = options.originDistance ?? 1;
|
||||
this.maxStdDev = options.maxStdDev ?? Math.sqrt(8.0);
|
||||
this.minPixelRadius = options.minPixelRadius ?? 0.0;
|
||||
this.maxPixelRadius = options.maxPixelRadius ?? 512.0;
|
||||
this.minAlpha = options.minAlpha ?? 0.5 * (1.0 / 255.0);
|
||||
this.enable2DGS = options.enable2DGS ?? false;
|
||||
@@ -344,6 +351,8 @@ export class SparkRenderer extends THREE.Mesh {
|
||||
renderToViewPos: { value: new THREE.Vector3() },
|
||||
// Maximum distance (in stddevs) from Gsplat center to render
|
||||
maxStdDev: { value: 1.0 },
|
||||
// Minimum pixel radius for splat rendering
|
||||
minPixelRadius: { value: 0.0 },
|
||||
// Maximum pixel radius for splat rendering
|
||||
maxPixelRadius: { value: 512.0 },
|
||||
// Minimum alpha value for splat rendering
|
||||
@@ -528,6 +537,7 @@ export class SparkRenderer extends THREE.Mesh {
|
||||
this.uniforms.far.value = typedCamera.far;
|
||||
this.uniforms.encodeLinear.value = viewpoint.encodeLinear;
|
||||
this.uniforms.maxStdDev.value = this.maxStdDev;
|
||||
this.uniforms.minPixelRadius.value = this.minPixelRadius;
|
||||
this.uniforms.maxPixelRadius.value = this.maxPixelRadius;
|
||||
this.uniforms.minAlpha.value = this.minAlpha;
|
||||
this.uniforms.stochastic.value = viewpoint.stochastic;
|
||||
|
||||
@@ -17,6 +17,7 @@ uniform uint numSplats;
|
||||
uniform vec4 renderToViewQuat;
|
||||
uniform vec3 renderToViewPos;
|
||||
uniform float maxStdDev;
|
||||
uniform float minPixelRadius;
|
||||
uniform float maxPixelRadius;
|
||||
uniform float time;
|
||||
uniform float deltaTime;
|
||||
@@ -199,11 +200,14 @@ void main() {
|
||||
vec2 eigenVec1 = normalize(vec2((abs(b) < 0.001) ? 1.0 : b, eigen1 - a));
|
||||
vec2 eigenVec2 = vec2(eigenVec1.y, -eigenVec1.x);
|
||||
|
||||
float scale1 = position.x * min(maxPixelRadius, maxStdDev * sqrt(eigen1));
|
||||
float scale2 = position.y * min(maxPixelRadius, maxStdDev * sqrt(eigen2));
|
||||
float scale1 = min(maxPixelRadius, maxStdDev * sqrt(eigen1));
|
||||
float scale2 = min(maxPixelRadius, maxStdDev * sqrt(eigen2));
|
||||
if (scale1 < minPixelRadius && scale2 < minPixelRadius) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Compute the NDC coordinates for the ellipsoid's diagonal axes.
|
||||
vec2 pixelOffset = eigenVec1 * scale1 + eigenVec2 * scale2;
|
||||
vec2 pixelOffset = position.x * eigenVec1 * scale1 + position.y * eigenVec2 * scale2;
|
||||
vec2 ndcOffset = (2.0 / scaledRenderSize) * pixelOffset;
|
||||
vec3 ndc = vec3(ndcCenter.xy + ndcOffset, ndcCenter.z);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user