Explorar o código

Depth packing and double sided shadows (#8745)

* Improved precision of RGBA fixpoint packing.

* Added switch to enable double-sided shadow casters.

- Off by default, see #8692

* Updated WebGLRenderer docs, shadow mapping.

* Enabled back face shadows, webgl_clipping_advanced.
tschw %!s(int64=9) %!d(string=hai) anos
pai
achega
fa0951f1af

+ 9 - 14
docs/api/renderers/WebGLRenderer.html

@@ -91,27 +91,28 @@
 
 		<div>Default is false.  If set, then it expects that all textures and colors need to be outputted in premultiplied gamma.</div>
 
+		<h3>[property:WebGLShadowMap shadowMap]</h3>
+		<div>
+		This contains the reference to the component implementing shadow mapping.
+		</div>
 
-		<h3>[property:Boolean shadowMapEnabled]</h3>
+		<h3>[property:Boolean shadowMap.enabled]</h3>
 
 		<div>Default is false. If set, use shadow maps in the scene.</div>
 
-
-		<h3>[property:Integer shadowMapType]</h3>
+		<h3>[property:Integer shadowMap.type]</h3>
 
 		<div>Defines shadow map type (unfiltered, percentage close filtering, percentage close filtering with bilinear filtering in shader)</div>
 		<div>Options are THREE.BasicShadowMap, THREE.PCFShadowMap, THREE.PCFSoftShadowMap. Default is THREE.PCFShadowMap.</div>
 
 
-		<h3>[property:Integer shadowMapCullFace]</h3>
+		<h3>[property:Integer shadowMap.cullFace]</h3>
 
 		<div>Default is THREE.CullFaceFront. The faces that needed to be culled. Possible values: THREE.CullFaceFront and THREE.CullFaceBack</div>
 
+		<h3>[property:Integer shadowMap.allowDoubleSided]</h3>
 
-		<h3>[property:Boolean shadowMapCascade]</h3>
-
-		<div>Default is false. If Set, use cascaded shadowmaps. See [link:http://developer.download.nvidia.com/SDK/10.5/opengl/src/cascaded_shadow_maps/doc/cascaded_shadow_maps.pdf cascaded shadowmaps] for more information.</div>
-
+		<div>Whether to allow double sided shadow rendering, off by default. When enabled, an appropriate shadow.bias must be set on the light source to keep surfaces from casting a shadow on themselves that will not render properly.</div>
 
 		<h3>[property:Integer maxMorphTargets]</h3>
 
@@ -152,12 +153,6 @@
 		</ul>
 		</div>
 
-		<h3>[property:WebGLShadowMap shadowMap]</h3>
-		<div>
-		This contains the reference to the component implementing shadow mapping.
-		</div>
-
-
 		<h2>Methods</h2>
 
 		<h3>[method:WebGLRenderingContext getContext]()</h3>

+ 1 - 0
examples/webgl_clipping_advanced.html

@@ -267,6 +267,7 @@
 
 				renderer = new THREE.WebGLRenderer();
 				renderer.shadowMap.enabled = true;
+				renderer.shadowMap.allowDoubleSided = true;
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				window.addEventListener( 'resize', onWindowResize, false );

+ 18 - 9
src/renderers/shaders/ShaderChunk/packing.glsl

@@ -6,17 +6,26 @@ vec3 unpackRGBToNormal( const in vec3 rgb ) {
   return 1.0 - 2.0 * rgb.xyz;
 }
 
+const float PackUpscale = 256. / 255.; // fraction -> 0..1 (including 1)
+const float UnpackDownscale = 255. / 256.; // 0..1 -> fraction (excluding 1)
+
+const vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256.,  256. );
+const vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );
+
+const float ShiftRight8 = 1. / 256.;
+
+vec4 packDepthToRGBA( const in float v ) {
+
+	vec4 r = vec4( fract( v * PackFactors ), v );
+	r.yzw -= r.xyz * ShiftRight8; // tidy overflow
+	return r * PackUpscale;
 
-vec4 packDepthToRGBA( const in float value ) {
-	const vec4 bit_shift = vec4( 256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0 );
-	const vec4 bit_mask = vec4( 0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0 );
-	vec4 res = mod( value * bit_shift * vec4( 255 ), vec4( 256 ) ) / vec4( 255 );
-	res -= res.xxyz * bit_mask;
-	return res;
 }
-float unpackRGBAToDepth( const in vec4 rgba ) {
-	const vec4 bitSh = vec4( 1.0 / ( 256.0 * 256.0 * 256.0 ), 1.0 / ( 256.0 * 256.0 ), 1.0 / 256.0, 1.0 );
-	return dot( rgba, bitSh );
+
+float unpackRGBAToDepth( const in vec4 v ) {
+
+	return dot( v, UnpackFactors );
+
 }
 
 // NOTE: viewZ/eyeZ is < 0 when in front of the camera per OpenGL conventions

+ 3 - 1
src/renderers/webgl/WebGLShadowMap.js

@@ -92,6 +92,8 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) {
 	this.type = THREE.PCFShadowMap;
 	this.cullFace = THREE.CullFaceFront;
 
+	this.allowDoubleSided = false;
+
 	this.render = function ( scene, camera ) {
 
 		if ( scope.enabled === false ) return;
@@ -365,7 +367,7 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) {
 
 		result.visible = material.visible;
 		result.wireframe = material.wireframe;
-		result.side = material.side;
+		result.side = scope.allowDoubleSided ? material.side : THREE.FrontSide;
 		result.clipShadows = material.clipShadows;
 		result.clippingPlanes = material.clippingPlanes;
 		result.wireframeLinewidth = material.wireframeLinewidth;