ソースを参照

Merge pull request #11591 from WestLangley/dev-distanceRGBA

Add map/alphaMap support to distanceRGBA shader
Mr.doob 8 年 前
コミット
295159fa16

+ 74 - 5
examples/webgl_shadowmap_pointlight.html

@@ -51,7 +51,7 @@
 				scene = new THREE.Scene();
 				scene.add( new THREE.AmbientLight( 0x222233 ) );
 
-				// Lights
+				// lights
 
 				function createLight( color ) {
 
@@ -59,7 +59,6 @@
 					pointLight.castShadow = true;
 					pointLight.shadow.camera.near = 1;
 					pointLight.shadow.camera.far = 30;
-					// pointLight.shadowCameraVisible = true;
 					pointLight.shadow.bias = 0.01;
 
 					var geometry = new THREE.SphereGeometry( 0.3, 12, 6 );
@@ -67,7 +66,7 @@
 					var sphere = new THREE.Mesh( geometry, material );
 					pointLight.add( sphere );
 
-					return pointLight
+					return pointLight;
 
 				}
 
@@ -77,25 +76,62 @@
 				pointLight2 = createLight( 0xff0000 );
 				scene.add( pointLight2 );
 
+				//
+
 				var geometry = new THREE.TorusKnotGeometry( 14, 1, 150, 20 );
+
+				var texture = new THREE.CanvasTexture( generateTexture() );
+				texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
+				texture.repeat.set( 32, 1 );
+
 				var material = new THREE.MeshPhongMaterial( {
 					color: 0xff0000,
 					shininess: 100,
-					specular: 0x222222
+					specular: 0x222222,
+					alphaMap: texture, // alphaMap uses the g channel
+					alphaTest: 0.5,
+					transparent: true,
+					side: THREE.DoubleSide
 				} );
+
 				torusKnot = new THREE.Mesh( geometry, material );
 				torusKnot.position.set( 0, 5, 0 );
 				torusKnot.castShadow = true;
-				torusKnot.receiveShadow = true;
 				scene.add( torusKnot );
 
+				// custom distance material
+
+				var shader = THREE.ShaderLib[ "distanceRGBA" ];
+
+				var uniforms = THREE.UniformsUtils.clone( shader.uniforms );
+				uniforms.alphaMap.value = material.alphaMap;
+				uniforms.offsetRepeat.value.set( texture.offset.x, texture.offset.y, texture.repeat.x, texture.repeat.y );
+
+				var distanceMaterial = new THREE.ShaderMaterial( {
+					defines: {
+						'USE_SHADOWMAP': '',
+						'USE_ALPHAMAP': '',
+						'ALPHATEST': material.alphaTest
+					},
+					uniforms: uniforms,
+					vertexShader: shader.vertexShader,
+					fragmentShader: shader.fragmentShader,
+					side: THREE.DoubleSide
+				} );
+
+				torusKnot.customDistanceMaterial = distanceMaterial;
+
+				//
+
 				var geometry = new THREE.BoxGeometry( 30, 30, 30 );
+
 				var material = new THREE.MeshPhongMaterial( {
 					color: 0xa0adaf,
 					shininess: 10,
 					specular: 0x111111,
 					side: THREE.BackSide
 				} );
+
 				var mesh = new THREE.Mesh( geometry, material );
 				mesh.position.y = 10;
 				mesh.receiveShadow = true;
@@ -108,6 +144,7 @@
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				renderer.shadowMap.enabled = true;
 				renderer.shadowMap.type = THREE.BasicShadowMap;
+				renderer.shadowMap.renderSingleSided = false; // must be set to false to honor double-sided materials
 				document.body.appendChild( renderer.domElement );
 
 				var controls = new THREE.OrbitControls( camera, renderer.domElement );
@@ -132,6 +169,38 @@
 
 			}
 
+			function generateTexture() {
+
+				var canvas = document.createElement( 'canvas' );
+				canvas.width = 256;
+				canvas.height = 256;
+
+				var context = canvas.getContext( '2d' );
+				var image = context.getImageData( 0, 0, 256, 256 );
+
+				var x = 0, y = 0, cvalue;
+
+				for ( var i = 0, j = 0, l = image.data.length; i < l; i += 4, j ++ ) {
+
+					x = j % 256;				// pixel col
+					y = ( x == 0 ) ? y + 1 : y;	// pixel row
+
+					// diagonal stripes
+					cvalue = Math.floor( ( x + y ) / 32 ) % 2;
+
+					image.data[ i + 0 ] = 255 * cvalue;
+					image.data[ i + 1 ] = 255 * cvalue;
+					image.data[ i + 2 ] = 255 * cvalue;
+					image.data[ i + 3 ] = 255;
+
+				}
+
+				context.putImageData( image, 0, 0 );
+
+				return canvas;
+
+			}
+
 			function animate() {
 
 				requestAnimationFrame( animate );

+ 6 - 3
src/renderers/shaders/ShaderLib.js

@@ -190,9 +190,12 @@ var ShaderLib = {
 
 	distanceRGBA: {
 
-		uniforms: {
-			lightPos: { value: new Vector3() }
-		},
+		uniforms: UniformsUtils.merge( [
+			UniformsLib.common,
+			{
+				lightPos: { value: new Vector3() }
+			}
+		] ),
 
 		vertexShader: ShaderChunk.distanceRGBA_vert,
 		fragmentShader: ShaderChunk.distanceRGBA_frag

+ 9 - 0
src/renderers/shaders/ShaderLib/distanceRGBA_frag.glsl

@@ -3,12 +3,21 @@ varying vec4 vWorldPosition;
 
 #include <common>
 #include <packing>
+#include <uv_pars_fragment>
+#include <map_pars_fragment>
+#include <alphamap_pars_fragment>
 #include <clipping_planes_pars_fragment>
 
 void main () {
 
 	#include <clipping_planes_fragment>
 
+	vec4 diffuseColor = vec4( 1.0 );
+
+	#include <map_fragment>
+	#include <alphamap_fragment>
+	#include <alphatest_fragment>
+
 	gl_FragColor = packDepthToRGBA( length( vWorldPosition.xyz - lightPos.xyz ) / 1000.0 );
 
 }

+ 3 - 0
src/renderers/shaders/ShaderLib/distanceRGBA_vert.glsl

@@ -1,12 +1,15 @@
 varying vec4 vWorldPosition;
 
 #include <common>
+#include <uv_pars_vertex>
 #include <morphtarget_pars_vertex>
 #include <skinning_pars_vertex>
 #include <clipping_planes_pars_vertex>
 
 void main() {
 
+	#include <uv_vertex>
+
 	#include <skinbase_vertex>
 	#include <begin_vertex>
 	#include <morphtarget_vertex>