Kaynağa Gözat

Added SpotLight support to normal map shader.

Changed LeePerry in CTM example to use normal map shader.
alteredq 13 yıl önce
ebeveyn
işleme
f75b34db18

Dosya farkı çok büyük olduğundan ihmal edildi
+ 0 - 1
build/Three.js


Dosya farkı çok büyük olduğundan ihmal edildi
+ 0 - 1
build/custom/ThreeExtras.js


+ 34 - 6
examples/webgl_loader_ctm.html

@@ -104,9 +104,6 @@
 
 				scene.add( light );
 
-				var light = new THREE.DirectionalLight( 0xffeedd, 0.25 );
-				light.position.set( 0, -50, 200 );
-				//scene.add( light );
 
 				// RENDERER
 
@@ -174,13 +171,11 @@
 
 				loader.load( "models/ctm/WaltHead.ctm",  function( geometry ) {
 
-					//geometry.computeVertexNormals();
-
 					var material1 = new THREE.MeshLambertMaterial( { color: 0xffffff } );
 					var material2 = new THREE.MeshPhongMaterial( { color: 0xff4400, specular: 0x333333, shininess: 100 } );
 					var material3 = new THREE.MeshPhongMaterial( { color: 0x00ff44, specular: 0x333333, shininess: 100 } );
 
-					callbackModel( geometry, 5, material1, -200, 0, 0, 0, 0 );
+					callbackModel( geometry, 5, material1, -200, 0, -50, 0, 0 );
 					callbackModel( geometry, 2, material2,  100, 0, 125, 0, 0 );
 					callbackModel( geometry, 2, material3, -100, 0, 125, 0, 0 );
 
@@ -190,8 +185,41 @@
 
 				loader.load( "models/ctm/LeePerry.ctm",  function( geometry ) {
 
+					/*
 					var material = new THREE.MeshPhongMaterial( { wrapAround: true, color: 0xffffff, specular: 0x232323, shininess: 50, map: THREE.ImageUtils.loadTexture( "obj/leeperrysmith/Map-COL.jpg" ) } );
 					material.wrapRGB.set( 0.65, 0.5, 0.5 );
+					*/
+
+					var ambient = 0xffffff, diffuse = 0xffffff, specular = 0x0e0e0e, shininess = 50;
+
+					var shader = THREE.ShaderUtils.lib[ "normal" ];
+					var uniforms = THREE.UniformsUtils.clone( shader.uniforms );
+
+					uniforms[ "tNormal" ].texture = THREE.ImageUtils.loadTexture( "obj/leeperrysmith/Infinite-Level_02_Tangent_SmoothUV.jpg" );
+					uniforms[ "uNormalScale" ].value = 0.8;
+
+					uniforms[ "tDiffuse" ].texture = THREE.ImageUtils.loadTexture( "obj/leeperrysmith/Map-COL.jpg" );
+					uniforms[ "tSpecular" ].texture = THREE.ImageUtils.loadTexture( "obj/leeperrysmith/Map-SPEC.jpg" );
+
+					uniforms[ "enableAO" ].value = false;
+					uniforms[ "enableDiffuse" ].value = true;
+					uniforms[ "enableSpecular" ].value = true;
+
+					uniforms[ "uDiffuseColor" ].value.setHex( diffuse );
+					uniforms[ "uSpecularColor" ].value.setHex( specular );
+					uniforms[ "uAmbientColor" ].value.setHex( ambient );
+
+					uniforms[ "uShininess" ].value = shininess;
+
+					uniforms[ "wrapRGB" ].value.set( 0.75, 0.5, 0.5 );
+
+					var parameters = { fragmentShader: shader.fragmentShader, vertexShader: shader.vertexShader, uniforms: uniforms, lights: true };
+					var material = new THREE.ShaderMaterial( parameters );
+
+					material.wrapAround = true;
+
+					geometry.computeTangents();
+
 					callbackModel( geometry, 1300, material, 200, 50, 0, 0, 0 );
 					checkTime();
 

+ 113 - 0
src/extras/ShaderUtils.js

@@ -182,6 +182,17 @@ THREE.ShaderUtils = {
 					"varying vec4 vPointLight[ MAX_POINT_LIGHTS ];",
 				"#endif",
 
+				"#if MAX_SPOT_LIGHTS > 0",
+					"uniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ];",
+					"uniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];",
+					"uniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ];",
+					"uniform float spotLightAngle[ MAX_SPOT_LIGHTS ];",
+					"uniform float spotLightExponent[ MAX_SPOT_LIGHTS ];",
+
+					"varying vec4 vSpotLight[ MAX_SPOT_LIGHTS ];",
+					"varying vec3 vWorldPosition;",
+				"#endif",
+
 				"#ifdef WRAP_AROUND",
 					"uniform vec3 wrapRGB;",
 				"#endif",
@@ -298,6 +309,68 @@ THREE.ShaderUtils = {
 
 					"#endif",
 
+					// spot lights
+
+					"#if MAX_SPOT_LIGHTS > 0",
+
+						"vec3 spotDiffuse = vec3( 0.0 );",
+						"vec3 spotSpecular = vec3( 0.0 );",
+
+						"for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {",
+
+							"vec3 spotVector = normalize( vSpotLight[ i ].xyz );",
+							"float spotDistance = vSpotLight[ i ].w;",
+
+							"float spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - vWorldPosition ) );",
+
+							"if ( spotEffect > spotLightAngle[ i ] ) {",
+
+								"spotEffect = pow( spotEffect, spotLightExponent[ i ] );",
+
+								// diffuse
+
+								"#ifdef WRAP_AROUND",
+
+									"float spotDiffuseWeightFull = max( dot( normal, spotVector ), 0.0 );",
+									"float spotDiffuseWeightHalf = max( 0.5 * dot( normal, spotVector ) + 0.5, 0.0 );",
+
+									"vec3 spotDiffuseWeight = mix( vec3 ( spotDiffuseWeightFull ), vec3( spotDiffuseWeightHalf ), wrapRGB );",
+
+								"#else",
+
+									"float spotDiffuseWeight = max( dot( normal, spotVector ), 0.0 );",
+
+								"#endif",
+
+								"spotDiffuse += spotDistance * spotLightColor[ i ] * uDiffuseColor * spotDiffuseWeight * spotEffect;",
+
+								// specular
+
+								"vec3 spotHalfVector = normalize( spotVector + viewPosition );",
+								"float spotDotNormalHalf = max( dot( normal, spotHalfVector ), 0.0 );",
+								"float spotSpecularWeight = specularTex.r * max( pow( spotDotNormalHalf, uShininess ), 0.0 );",
+
+								"#ifdef PHYSICALLY_BASED_SHADING",
+
+									// 2.0 => 2.0001 is hack to work around ANGLE bug
+
+									"float specularNormalization = ( uShininess + 2.0001 ) / 8.0;",
+
+									"vec3 schlick = uSpecularColor + vec3( 1.0 - uSpecularColor ) * pow( 1.0 - dot( spotVector, spotHalfVector ), 5.0 );",
+									"spotSpecular += schlick * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * spotDistance * specularNormalization * spotEffect;",
+
+								"#else",
+
+									"spotSpecular += spotDistance * spotLightColor[ i ] * uSpecularColor * spotSpecularWeight * spotDiffuseWeight * spotEffect;",
+
+								"#endif",
+
+							"}",
+
+						"}",
+
+					"#endif",
+
 					// directional lights
 
 					"#if MAX_DIR_LIGHTS > 0",
@@ -371,6 +444,13 @@ THREE.ShaderUtils = {
 
 					"#endif",
 
+					"#if MAX_SPOT_LIGHTS > 0",
+
+						"totalDiffuse += spotDiffuse;",
+						"totalSpecular += spotSpecular;",
+
+					"#endif",
+
 					"gl_FragColor.xyz = gl_FragColor.xyz * ( totalDiffuse + ambientLightColor * uAmbientColor) + totalSpecular;",
 
 					"if ( enableReflection ) {",
@@ -427,6 +507,17 @@ THREE.ShaderUtils = {
 
 				"#endif",
 
+				"#if MAX_SPOT_LIGHTS > 0",
+
+					"uniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];",
+					"uniform float spotLightDistance[ MAX_SPOT_LIGHTS ];",
+
+					"varying vec4 vSpotLight[ MAX_SPOT_LIGHTS ];",
+
+					"varying vec3 vWorldPosition;",
+
+				"#endif",
+
 				"varying vec3 vViewPosition;",
 
 				THREE.ShaderChunk[ "shadowmap_pars_vertex" ],
@@ -466,6 +557,28 @@ THREE.ShaderUtils = {
 
 					"#endif",
 
+					// spot lights
+
+					"#if MAX_SPOT_LIGHTS > 0",
+
+						"for( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {",
+
+							"vec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );",
+							"vec3 lVector = lPosition.xyz - mvPosition.xyz;",
+
+							"float lDistance = 1.0;",
+							"if ( spotLightDistance[ i ] > 0.0 )",
+								"lDistance = 1.0 - min( ( length( lVector ) / spotLightDistance[ i ] ), 1.0 );",
+
+							"vSpotLight[ i ] = vec4( lVector, lDistance );",
+
+						"}",
+
+						"vec4 mPosition = objectMatrix * vec4( position, 1.0 );",
+						"vWorldPosition = mPosition.xyz;",
+
+					"#endif",
+
 					// displacement mapping
 
 					"#ifdef VERTEX_TEXTURES",

Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor