diff --git a/src/constants.js b/src/constants.js index d4477a3bad2e1b..8536726d09e8f9 100644 --- a/src/constants.js +++ b/src/constants.js @@ -1254,14 +1254,6 @@ export const RGBDepthPacking = 3202; */ export const RGDepthPacking = 3203; -/** - * The depth value is not packed. - * - * @type {number} - * @constant - */ -export const IdentityDepthPacking = 3204; - /** * Normal information is relative to the underlying surface. * diff --git a/src/renderers/shaders/ShaderLib/depth.glsl.js b/src/renderers/shaders/ShaderLib/depth.glsl.js index c025c12bd4ed3e..efacc561631b06 100644 --- a/src/renderers/shaders/ShaderLib/depth.glsl.js +++ b/src/renderers/shaders/ShaderLib/depth.glsl.js @@ -111,10 +111,6 @@ void main() { // TODO Deprecate gl_FragColor = vec4( packDepthToRG( fragCoordZ ), 0.0, 1.0 ); - #elif DEPTH_PACKING == 3204 - - gl_FragColor = vec4( vec3( fragCoordZ ), 1.0 ); - #endif } diff --git a/src/renderers/shaders/ShaderLib/vsm.glsl.js b/src/renderers/shaders/ShaderLib/vsm.glsl.js index 6b4a28a97f0aff..945662a3f9577d 100644 --- a/src/renderers/shaders/ShaderLib/vsm.glsl.js +++ b/src/renderers/shaders/ShaderLib/vsm.glsl.js @@ -43,7 +43,7 @@ void main() { mean = mean / samples; squared_mean = squared_mean / samples; - float std_dev = sqrt( squared_mean - mean * mean ); + float std_dev = sqrt( max( 0.0, squared_mean - mean * mean ) ); gl_FragColor = vec4( mean, std_dev, 0.0, 1.0 ); diff --git a/src/renderers/webgl/WebGLLights.js b/src/renderers/webgl/WebGLLights.js index bd106f34017a10..e24f9266864354 100644 --- a/src/renderers/webgl/WebGLLights.js +++ b/src/renderers/webgl/WebGLLights.js @@ -3,6 +3,7 @@ import { Matrix4 } from '../../math/Matrix4.js'; import { Vector2 } from '../../math/Vector2.js'; import { Vector3 } from '../../math/Vector3.js'; import { UniformsLib } from '../shaders/UniformsLib.js'; +import { RGFormat } from '../../constants.js'; function UniformsCache() { @@ -239,7 +240,23 @@ function WebGLLights( extensions ) { const intensity = light.intensity; const distance = light.distance; - const shadowMap = ( light.shadow && light.shadow.map ) ? ( light.shadow.map.depthTexture || light.shadow.map.texture ) : null; + let shadowMap = null; + + if ( light.shadow && light.shadow.map ) { + + if ( light.shadow.map.texture.format === RGFormat ) { + + // VSM uses color texture with blurred mean/std_dev + shadowMap = light.shadow.map.texture; + + } else { + + // Other types use depth texture + shadowMap = light.shadow.map.depthTexture || light.shadow.map.texture; + + } + + } if ( light.isAmbientLight ) { diff --git a/src/renderers/webgl/WebGLShadowMap.js b/src/renderers/webgl/WebGLShadowMap.js index e38833a78f851b..b82720085af56f 100644 --- a/src/renderers/webgl/WebGLShadowMap.js +++ b/src/renderers/webgl/WebGLShadowMap.js @@ -1,4 +1,4 @@ -import { FrontSide, BackSide, DoubleSide, NearestFilter, LinearFilter, PCFShadowMap, VSMShadowMap, NoBlending, LessEqualCompare, GreaterEqualCompare, DepthFormat, UnsignedIntType, RGFormat, HalfFloatType, PCFSoftShadowMap, IdentityDepthPacking } from '../../constants.js'; +import { FrontSide, BackSide, DoubleSide, NearestFilter, LinearFilter, PCFShadowMap, VSMShadowMap, NoBlending, LessEqualCompare, GreaterEqualCompare, DepthFormat, UnsignedIntType, RGFormat, HalfFloatType, FloatType, PCFSoftShadowMap } from '../../constants.js'; import { WebGLRenderTarget } from '../WebGLRenderTarget.js'; import { WebGLCubeRenderTarget } from '../WebGLCubeRenderTarget.js'; import { MeshDepthMaterial } from '../../materials/MeshDepthMaterial.js'; @@ -26,7 +26,6 @@ function WebGLShadowMap( renderer, objects, capabilities ) { _viewport = new Vector4(), _depthMaterial = new MeshDepthMaterial(), - _depthMaterialVSM = new MeshDepthMaterial( { depthPacking: IdentityDepthPacking } ), _distanceMaterial = new MeshDistanceMaterial(), _materialCache = {}, @@ -215,6 +214,14 @@ function WebGLShadowMap( renderer, objects, capabilities ) { } ); shadow.map.texture.name = light.name + '.shadowMap'; + // Native depth texture for VSM - depth is captured here, then blurred into the color texture + shadow.map.depthTexture = new DepthTexture( _shadowMapSize.x, _shadowMapSize.y, FloatType ); + shadow.map.depthTexture.name = light.name + '.shadowMapDepth'; + shadow.map.depthTexture.format = DepthFormat; + shadow.map.depthTexture.compareFunction = null; // For regular sampling (not shadow comparison) + shadow.map.depthTexture.minFilter = NearestFilter; + shadow.map.depthTexture.magFilter = NearestFilter; + } else { if ( light.isPointLight ) { @@ -339,9 +346,9 @@ function WebGLShadowMap( renderer, objects, capabilities ) { } - // vertical pass + // vertical pass - read from native depth texture - shadowMaterialVertical.uniforms.shadow_pass.value = shadow.map.texture; + shadowMaterialVertical.uniforms.shadow_pass.value = shadow.map.depthTexture; shadowMaterialVertical.uniforms.resolution.value = shadow.mapSize; shadowMaterialVertical.uniforms.radius.value = shadow.radius; renderer.setRenderTarget( shadow.mapPass ); @@ -371,15 +378,7 @@ function WebGLShadowMap( renderer, objects, capabilities ) { } else { - if ( type === VSMShadowMap ) { - - result = _depthMaterialVSM; - - } else { - - result = ( light.isPointLight === true ) ? _distanceMaterial : _depthMaterial; - - } + result = ( light.isPointLight === true ) ? _distanceMaterial : _depthMaterial; if ( ( renderer.localClippingEnabled && material.clipShadows === true && Array.isArray( material.clippingPlanes ) && material.clippingPlanes.length !== 0 ) || ( material.displacementMap && material.displacementScale !== 0 ) ||