Browse Source

Merge pull request #15591 from IvoJager/dev

Added PCFSoftShadowMapFast for better looking shadows on low powered devices
Mr.doob 6 years ago
parent
commit
93a6b8e41e

+ 2 - 0
docs/api/en/constants/Renderer.html

@@ -39,6 +39,7 @@
 		THREE.BasicShadowMap
 		THREE.BasicShadowMap
 		THREE.PCFShadowMap
 		THREE.PCFShadowMap
 		THREE.PCFSoftShadowMap
 		THREE.PCFSoftShadowMap
+		THREE.PCFSoftShadowMapFast
 		</code>
 		</code>
 		<p>
 		<p>
 		These define the WebGLRenderer's [page:WebGLRenderer.shadowMap.type shadowMap.type] property.<br /><br />
 		These define the WebGLRenderer's [page:WebGLRenderer.shadowMap.type shadowMap.type] property.<br /><br />
@@ -46,6 +47,7 @@
 		[page:constant BasicShadowMap] gives unfiltered shadow maps - fastest, but lowest quality.<br />
 		[page:constant BasicShadowMap] gives unfiltered shadow maps - fastest, but lowest quality.<br />
 		[page:constant PCFShadowMap] filters shadow maps using the Percentage-Closer Filtering (PCF) algorithm (default).<br />
 		[page:constant PCFShadowMap] filters shadow maps using the Percentage-Closer Filtering (PCF) algorithm (default).<br />
 		[page:constant PCFSoftShadowMap] filters shadow maps using the Percentage-Closer Soft Shadows (PCSS) algorithm.
 		[page:constant PCFSoftShadowMap] filters shadow maps using the Percentage-Closer Soft Shadows (PCSS) algorithm.
+		[page:constant PCFSoftShadowMapFast] filters shadow maps using the Percentage-Closer Filtering (PCF) algorithm with additional sub-sampling.<br />
 		</p>
 		</p>
 
 
 		<h2>Tone Mapping</h2>
 		<h2>Tone Mapping</h2>

+ 1 - 1
docs/api/en/renderers/WebGLRenderer.html

@@ -258,7 +258,7 @@
 
 
 		<h3>[property:Integer shadowMap.type]</h3>
 		<h3>[property:Integer shadowMap.type]</h3>
 		<p>Defines shadow map type (unfiltered, percentage close filtering, percentage close filtering with bilinear filtering in shader)</p>
 		<p>Defines shadow map type (unfiltered, percentage close filtering, percentage close filtering with bilinear filtering in shader)</p>
-		<p>Options are THREE.BasicShadowMap, THREE.PCFShadowMap (default), THREE.PCFSoftShadowMap. See [page:Renderer Renderer constants] for details.</p>
+		<p>Options are THREE.BasicShadowMap, THREE.PCFShadowMap (default), THREE.PCFSoftShadowMap and THREE.PCFSoftShadowMapFast. See [page:Renderer Renderer constants] for details.</p>
 
 
 		<h3>[property:Boolean sortObjects]</h3>
 		<h3>[property:Boolean sortObjects]</h3>
 		<p>
 		<p>

+ 1 - 0
src/constants.js

@@ -9,6 +9,7 @@ export var FrontFaceDirectionCCW = 1;
 export var BasicShadowMap = 0;
 export var BasicShadowMap = 0;
 export var PCFShadowMap = 1;
 export var PCFShadowMap = 1;
 export var PCFSoftShadowMap = 2;
 export var PCFSoftShadowMap = 2;
+export var PCFSoftShadowMapFast = 3;
 export var FrontSide = 0;
 export var FrontSide = 0;
 export var BackSide = 1;
 export var BackSide = 1;
 export var DoubleSide = 2;
 export var DoubleSide = 2;

+ 33 - 0
src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js

@@ -119,6 +119,39 @@ export default /* glsl */`
 				texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )
 				texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )
 			) * ( 1.0 / 9.0 );
 			) * ( 1.0 / 9.0 );
 
 
+		#elif defined( SHADOWMAP_TYPE_PCF_SOFT_FAST )
+
+			vec2 texelSize = vec2( 1.0 ) / shadowMapSize;
+
+			float dx0 = - texelSize.x * shadowRadius;
+			float dy0 = - texelSize.y * shadowRadius;
+			float dx1 = + texelSize.x * shadowRadius;
+			float dy1 = + texelSize.y * shadowRadius;
+			float dx2 = dx0 / 2.0;
+			float dy2 = dy0 / 2.0;
+			float dx3 = dx1 / 2.0;
+			float dy3 = dy1 / 2.0;
+
+			shadow = (
+				texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +
+				texture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +
+				texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +
+				texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy2 ), shadowCoord.z ) +
+				texture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy2 ), shadowCoord.z ) +
+				texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy2 ), shadowCoord.z ) +
+				texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +
+				texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, 0.0 ), shadowCoord.z ) +
+				texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +
+				texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, 0.0 ), shadowCoord.z ) +
+				texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +
+				texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy3 ), shadowCoord.z ) +
+				texture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy3 ), shadowCoord.z ) +
+				texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy3 ), shadowCoord.z ) +
+				texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +
+				texture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +
+				texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )
+			) * ( 1.0 / 17.0 );
+
 		#else // no percentage-closer filtering:
 		#else // no percentage-closer filtering:
 
 
 			shadow = texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );
 			shadow = texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );

+ 5 - 1
src/renderers/webgl/WebGLProgram.js

@@ -5,7 +5,7 @@
 import { WebGLUniforms } from './WebGLUniforms.js';
 import { WebGLUniforms } from './WebGLUniforms.js';
 import { WebGLShader } from './WebGLShader.js';
 import { WebGLShader } from './WebGLShader.js';
 import { ShaderChunk } from '../shaders/ShaderChunk.js';
 import { ShaderChunk } from '../shaders/ShaderChunk.js';
-import { NoToneMapping, AddOperation, MixOperation, MultiplyOperation, EquirectangularRefractionMapping, CubeRefractionMapping, SphericalReflectionMapping, EquirectangularReflectionMapping, CubeUVRefractionMapping, CubeUVReflectionMapping, CubeReflectionMapping, PCFSoftShadowMap, PCFShadowMap, ACESFilmicToneMapping, CineonToneMapping, Uncharted2ToneMapping, ReinhardToneMapping, LinearToneMapping, GammaEncoding, RGBDEncoding, RGBM16Encoding, RGBM7Encoding, RGBEEncoding, sRGBEncoding, LinearEncoding } from '../../constants.js';
+import { NoToneMapping, AddOperation, MixOperation, MultiplyOperation, EquirectangularRefractionMapping, CubeRefractionMapping, SphericalReflectionMapping, EquirectangularReflectionMapping, CubeUVRefractionMapping, CubeUVReflectionMapping, CubeReflectionMapping, PCFSoftShadowMapFast, PCFSoftShadowMap, PCFShadowMap, ACESFilmicToneMapping, CineonToneMapping, Uncharted2ToneMapping, ReinhardToneMapping, LinearToneMapping, GammaEncoding, RGBDEncoding, RGBM16Encoding, RGBM7Encoding, RGBEEncoding, sRGBEncoding, LinearEncoding } from '../../constants.js';
 
 
 var programIdCount = 0;
 var programIdCount = 0;
 
 
@@ -255,6 +255,10 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters,
 
 
 		shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT';
 		shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT';
 
 
+	} else if ( parameters.shadowMapType === PCFSoftShadowMapFast ) {
+
+		shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT_FAST';
+
 	}
 	}
 
 
 	var envMapTypeDefine = 'ENVMAP_TYPE_CUBE';
 	var envMapTypeDefine = 'ENVMAP_TYPE_CUBE';