mirror of
https://github.com/storytold/spark.git
synced 2026-10-09 00:09:53 +00:00
Add focalDistance and apertureAngle to SparkRenderer. Add examples/depth-of-field. (#59)
This commit is contained in:
committed by
GitHub
parent
690e09ac95
commit
db1e880ae1
@@ -373,6 +373,7 @@
|
||||
<a href="/examples/webxr/index.html" class="example-link">WebXR</a>
|
||||
<a href="/examples/glsl/index.html" class="example-link">GLSL Shaders</a>
|
||||
<a href="/examples/debug-color/index.html" class="example-link">Debug Coloring</a>
|
||||
<a href="/examples/depth-of-field/index.html" class="example-link">Depth of Field</a>
|
||||
<a href="/examples/editor/index.html" class="example-link">Editor</a>
|
||||
</div>
|
||||
<div class="content">
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Spark • Depth of Field</title>
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
canvas {
|
||||
touch-action: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script type="importmap">
|
||||
{
|
||||
"imports": {
|
||||
"three": "/examples/js/vendor/three/build/three.module.js",
|
||||
"lil-gui": "/examples/js/vendor/lil-gui/dist/lil-gui.esm.js",
|
||||
"@sparkjsdev/spark": "/dist/spark.module.js"
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<script type="module">
|
||||
import * as THREE from "three";
|
||||
import { SparkRenderer, SplatMesh, SparkControls } from "@sparkjsdev/spark";
|
||||
import GUI from "lil-gui";
|
||||
import { getAssetFileURL } from "/examples/js/get-asset-url.js";
|
||||
|
||||
const scene = new THREE.Scene();
|
||||
const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000);
|
||||
const renderer = new THREE.WebGLRenderer();
|
||||
renderer.setSize(window.innerWidth, window.innerHeight);
|
||||
document.body.appendChild(renderer.domElement)
|
||||
|
||||
const spark = new SparkRenderer({
|
||||
renderer,
|
||||
apertureAngle: 0.02,
|
||||
focalDistance: 5.0,
|
||||
enable2DGS: false,
|
||||
});
|
||||
scene.add(spark);
|
||||
|
||||
const gui = new GUI({ title: "DoF settings" });
|
||||
gui.add(spark, "focalDistance", 0.1, 15, 0.1);
|
||||
gui.add(spark, "apertureAngle", 0.0, 0.01 * Math.PI, 0.001);
|
||||
|
||||
const splatURL = await getAssetFileURL("valley.spz");
|
||||
const background = new SplatMesh({ url: splatURL });
|
||||
background.quaternion.set(1, 0, 0, 0);
|
||||
background.scale.setScalar(0.5);
|
||||
scene.add(background);
|
||||
|
||||
const controls = new SparkControls({ canvas: renderer.domElement });
|
||||
renderer.setAnimationLoop(function animate(time) {
|
||||
controls.update(camera);
|
||||
renderer.render(scene, camera);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -145,6 +145,7 @@
|
||||
<li><a href="/examples/webxr/">WebXR</a></li>
|
||||
<li><a href="/examples/glsl/">GLSL Shaders</a></li>
|
||||
<li><a href="/examples/debug-color/">Debug Coloring</a></li>
|
||||
<li><a href="/examples/depth-of-field/">Depth of Field</a></li>
|
||||
<li><a href="/examples/editor/">Editor</a></li>
|
||||
<li><a href="/examples/viewer/">Viewer</a></li>
|
||||
</ul>
|
||||
|
||||
@@ -115,6 +115,10 @@ export type SparkRendererOptions = {
|
||||
// to correctly account for "blurring" when anti-aliasing. Typically 0.3
|
||||
// (equivalent to approx 0.5 pixel radius) in scenes trained with anti-aliasing.
|
||||
blurAmount?: number;
|
||||
// Depth-of-field distance to focal plane
|
||||
focalDistance?: number;
|
||||
// Full-width angle of aperture opening (in radians), default 0.0 to disable
|
||||
apertureAngle?: number;
|
||||
// Modulate Gaussian kernel falloff. 0 means "no falloff, flat shading",
|
||||
// while 1 is the normal Gaussian kernel. (default: 1.0)
|
||||
falloff?: number;
|
||||
@@ -140,6 +144,8 @@ export class SparkRenderer extends THREE.Mesh {
|
||||
enable2DGS: boolean;
|
||||
preBlurAmount: number;
|
||||
blurAmount: number;
|
||||
focalDistance: number;
|
||||
apertureAngle: number;
|
||||
falloff: number;
|
||||
clipXY: number;
|
||||
|
||||
@@ -241,6 +247,8 @@ export class SparkRenderer extends THREE.Mesh {
|
||||
this.enable2DGS = options.enable2DGS ?? true;
|
||||
this.preBlurAmount = options.preBlurAmount ?? 0.0;
|
||||
this.blurAmount = options.blurAmount ?? 0.3;
|
||||
this.focalDistance = options.focalDistance ?? 0.0;
|
||||
this.apertureAngle = options.apertureAngle ?? 0.0;
|
||||
this.falloff = options.falloff ?? 1.0;
|
||||
this.clipXY = options.clipXY ?? 1.4;
|
||||
|
||||
@@ -287,6 +295,10 @@ export class SparkRenderer extends THREE.Mesh {
|
||||
preBlurAmount: { value: 0.0 },
|
||||
// Add to 2D splat covariance diagonal and adjust opacity (anti-aliasing)
|
||||
blurAmount: { value: 0.3 },
|
||||
// Depth-of-field distance to focal plane
|
||||
focalDistance: { value: 0.0 },
|
||||
// Full-width angle of aperture opening (in radians)
|
||||
apertureAngle: { value: 0.0 },
|
||||
// Modulate Gaussian kernal falloff. 0 means "no falloff, flat shading",
|
||||
// 1 is normal e^-x^2 falloff.
|
||||
falloff: { value: 1.0 },
|
||||
@@ -424,6 +436,8 @@ export class SparkRenderer extends THREE.Mesh {
|
||||
this.uniforms.enable2DGS.value = this.enable2DGS;
|
||||
this.uniforms.preBlurAmount.value = this.preBlurAmount;
|
||||
this.uniforms.blurAmount.value = this.blurAmount;
|
||||
this.uniforms.focalDistance.value = this.focalDistance;
|
||||
this.uniforms.apertureAngle.value = this.apertureAngle;
|
||||
this.uniforms.falloff.value = this.falloff;
|
||||
this.uniforms.clipXY.value = this.clipXY;
|
||||
|
||||
|
||||
@@ -22,6 +22,8 @@ uniform bool debugFlag;
|
||||
uniform bool enable2DGS;
|
||||
uniform float blurAmount;
|
||||
uniform float preBlurAmount;
|
||||
uniform float focalDistance;
|
||||
uniform float apertureAngle;
|
||||
uniform float clipXY;
|
||||
|
||||
uniform usampler2DArray packedSplats;
|
||||
@@ -135,10 +137,21 @@ void main() {
|
||||
a += preBlurAmount;
|
||||
d += preBlurAmount;
|
||||
|
||||
float fullBlurAmount = blurAmount;
|
||||
if ((focalDistance > 0.0) && (apertureAngle > 0.0)) {
|
||||
float focusRadius = MAX_PIXEL_RADIUS;
|
||||
if (viewCenter.z < 0.0) {
|
||||
float focusBlur = abs((-viewCenter.z - focalDistance) / viewCenter.z);
|
||||
float apertureRadius = focal.x * tan(0.5 * apertureAngle);
|
||||
focusRadius = focusBlur * apertureRadius;
|
||||
}
|
||||
fullBlurAmount = clamp(sqr(focusRadius), blurAmount, sqr(MAX_PIXEL_RADIUS));
|
||||
}
|
||||
|
||||
// Do convolution with a 0.5-pixel Gaussian for anti-aliasing: sqrt(0.3) ~= 0.5
|
||||
float detOrig = a * d - b * b;
|
||||
a += blurAmount;
|
||||
d += blurAmount;
|
||||
a += fullBlurAmount;
|
||||
d += fullBlurAmount;
|
||||
float det = a * d - b * b;
|
||||
|
||||
// Compute anti-aliasing intensity scaling factor
|
||||
|
||||
Reference in New Issue
Block a user