Browse Source

Added SpotLight support to normal map shader.

Changed LeePerry in CTM example to use normal map shader.
alteredq 13 years ago
parent
commit
f75b34db18
4 changed files with 147 additions and 8 deletions
  1. 0 1
      build/Three.js
  2. 0 1
      build/custom/ThreeExtras.js
  3. 34 6
      examples/webgl_loader_ctm.html
  4. 113 0
      src/extras/ShaderUtils.js

File diff suppressed because it is too large
+ 0 - 1
build/Three.js


File diff suppressed because it is too large
+ 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",

Some files were not shown because too many files changed in this diff