three-stdlib
Version:
stand-alone library of threejs examples
145 lines (121 loc) • 3.85 kB
JavaScript
import { Vector2 } from "three";
const DepthLimitedBlurShader = {
defines: {
KERNEL_RADIUS: 4,
DEPTH_PACKING: 1,
PERSPECTIVE_CAMERA: 1
},
uniforms: {
tDiffuse: { value: null },
size: { value: /* @__PURE__ */ new Vector2(512, 512) },
sampleUvOffsets: { value: [/* @__PURE__ */ new Vector2(0, 0)] },
sampleWeights: { value: [1] },
tDepth: { value: null },
cameraNear: { value: 10 },
cameraFar: { value: 1e3 },
depthCutoff: { value: 10 }
},
vertexShader: (
/* glsl */
`
uniform vec2 size;
varying vec2 vUv;
varying vec2 vInvSize;
void main() {
vUv = uv;
vInvSize = 1.0 / size;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}
`
),
fragmentShader: (
/* glsl */
`
uniform sampler2D tDiffuse;
uniform sampler2D tDepth;
uniform float cameraNear;
uniform float cameraFar;
uniform float depthCutoff;
uniform vec2 sampleUvOffsets[ KERNEL_RADIUS + 1 ];
uniform float sampleWeights[ KERNEL_RADIUS + 1 ];
varying vec2 vUv;
varying vec2 vInvSize;
float getDepth( const in vec2 screenPosition ) {
return unpackRGBAToDepth( texture2D( tDepth, screenPosition ) );
return texture2D( tDepth, screenPosition ).x;
}
float getViewZ( const in float depth ) {
return perspectiveDepthToViewZ( depth, cameraNear, cameraFar );
return orthographicDepthToViewZ( depth, cameraNear, cameraFar );
}
void main() {
float depth = getDepth( vUv );
if( depth >= ( 1.0 - EPSILON ) ) {
discard;
}
float centerViewZ = -getViewZ( depth );
bool rBreak = false, lBreak = false;
float weightSum = sampleWeights[0];
vec4 diffuseSum = texture2D( tDiffuse, vUv ) * weightSum;
for( int i = 1; i <= KERNEL_RADIUS; i ++ ) {
float sampleWeight = sampleWeights[i];
vec2 sampleUvOffset = sampleUvOffsets[i] * vInvSize;
vec2 sampleUv = vUv + sampleUvOffset;
float viewZ = -getViewZ( getDepth( sampleUv ) );
if( abs( viewZ - centerViewZ ) > depthCutoff ) rBreak = true;
if( ! rBreak ) {
diffuseSum += texture2D( tDiffuse, sampleUv ) * sampleWeight;
weightSum += sampleWeight;
}
sampleUv = vUv - sampleUvOffset;
viewZ = -getViewZ( getDepth( sampleUv ) );
if( abs( viewZ - centerViewZ ) > depthCutoff ) lBreak = true;
if( ! lBreak ) {
diffuseSum += texture2D( tDiffuse, sampleUv ) * sampleWeight;
weightSum += sampleWeight;
}
}
gl_FragColor = diffuseSum / weightSum;
}
`
)
};
const BlurShaderUtils = {
createSampleWeights: (kernelRadius, stdDev) => {
const gaussian = (x, stdDev2) => {
return Math.exp(-(x * x) / (2 * (stdDev2 * stdDev2))) / (Math.sqrt(2 * Math.PI) * stdDev2);
};
const weights = [];
for (let i = 0; i <= kernelRadius; i++) {
weights.push(gaussian(i, stdDev));
}
return weights;
},
createSampleOffsets: (kernelRadius, uvIncrement) => {
const offsets = [];
for (let i = 0; i <= kernelRadius; i++) {
offsets.push(uvIncrement.clone().multiplyScalar(i));
}
return offsets;
},
configure: (shader, kernelRadius, stdDev, uvIncrement) => {
shader.defines["KERNEL_RADIUS"] = kernelRadius;
shader.uniforms["sampleUvOffsets"].value = BlurShaderUtils.createSampleOffsets(kernelRadius, uvIncrement);
shader.uniforms["sampleWeights"].value = BlurShaderUtils.createSampleWeights(kernelRadius, stdDev);
shader.needsUpdate = true;
}
};
export {
BlurShaderUtils,
DepthLimitedBlurShader
};
//# sourceMappingURL=DepthLimitedBlurShader.js.map