瀏覽代碼

Added handling of HemisphereLight and shadow maps to terrain shader.

alteredq 13 年之前
父節點
當前提交
e08818649e
共有 1 個文件被更改,包括 79 次插入8 次删除
  1. 79 8
      examples/js/ShaderTerrain.js

+ 79 - 8
examples/js/ShaderTerrain.js

@@ -9,7 +9,8 @@ THREE.ShaderTerrain = {
 	//	Dynamic terrain shader
 	//		- Blinn-Phong
 	//		- height + normal + diffuse1 + diffuse2 + specular + detail maps
-	//		- point and directional lights (use with "lights: true" material option)
+	//		- point, directional and hemisphere lights (use with "lights: true" material option)
+	//		- shadow maps receiving
 	 ------------------------------------------------------------------------- */
 
 	'terrain' : {
@@ -18,6 +19,7 @@ THREE.ShaderTerrain = {
 
 			THREE.UniformsLib[ "fog" ],
 			THREE.UniformsLib[ "lights" ],
+			THREE.UniformsLib[ "shadowmap" ],
 
 			{
 
@@ -87,18 +89,31 @@ THREE.ShaderTerrain = {
 			"uniform vec3 ambientLightColor;",
 
 			"#if MAX_DIR_LIGHTS > 0",
+
 				"uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];",
 				"uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];",
+
+			"#endif",
+
+			"#if MAX_HEMI_LIGHTS > 0",
+
+				"uniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];",
+				"uniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];",
+				"uniform vec3 hemisphereLightPosition[ MAX_HEMI_LIGHTS ];",
+
 			"#endif",
 
 			"#if MAX_POINT_LIGHTS > 0",
+
 				"uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];",
 				"uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];",
 				"uniform float pointLightDistance[ MAX_POINT_LIGHTS ];",
+
 			"#endif",
 
 			"varying vec3 vViewPosition;",
 
+			THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
 			THREE.ShaderChunk[ "fog_pars_fragment" ],
 
 			"void main() {",
@@ -206,6 +221,47 @@ THREE.ShaderTerrain = {
 
 				"#endif",
 
+				// hemisphere lights
+
+				"#if MAX_HEMI_LIGHTS > 0",
+
+					"vec3 hemiDiffuse  = vec3( 0.0 );",
+					"vec3 hemiSpecular = vec3( 0.0 );" ,
+
+					"for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {",
+
+						"vec4 lPosition = viewMatrix * vec4( hemisphereLightPosition[ i ], 1.0 );",
+						"vec3 lVector = normalize( lPosition.xyz + vViewPosition.xyz );",
+
+						// diffuse
+
+						"float dotProduct = dot( normal, lVector );",
+						"float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;",
+
+						"hemiDiffuse += uDiffuseColor * mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );",
+
+						// specular (sky light)
+
+						"float hemiSpecularWeight = 0.0;",
+
+						"vec3 hemiHalfVectorSky = normalize( lVector + viewPosition );",
+						"float hemiDotNormalHalfSky = 0.5 * dot( normal, hemiHalfVectorSky ) + 0.5;",
+						"hemiSpecularWeight += specularTex.r * max( pow( hemiDotNormalHalfSky, uShininess ), 0.0 );",
+
+						// specular (ground light)
+
+						"vec3 lVectorGround = normalize( -lPosition.xyz + vViewPosition.xyz );",
+
+						"vec3 hemiHalfVectorGround = normalize( lVectorGround + viewPosition );",
+						"float hemiDotNormalHalfGround = 0.5 * dot( normal, hemiHalfVectorGround ) + 0.5;",
+						"hemiSpecularWeight += specularTex.r * max( pow( hemiDotNormalHalfGround, uShininess ), 0.0 );",
+
+						"hemiSpecular += uSpecularColor * mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight ) * hemiSpecularWeight * hemiDiffuseWeight;",
+
+					"}",
+
+				"#endif",
+
 				// all lights contribution summation
 
 				"vec3 totalDiffuse = vec3( 0.0 );",
@@ -218,6 +274,13 @@ THREE.ShaderTerrain = {
 
 				"#endif",
 
+				"#if MAX_HEMI_LIGHTS > 0",
+
+					"totalDiffuse += hemiDiffuse;",
+					"totalSpecular += hemiSpecular;",
+
+				"#endif",
+
 				"#if MAX_POINT_LIGHTS > 0",
 
 					"totalDiffuse += pointDiffuse;",
@@ -228,6 +291,7 @@ THREE.ShaderTerrain = {
 				//"gl_FragColor.xyz = gl_FragColor.xyz * ( totalDiffuse + ambientLightColor * uAmbientColor) + totalSpecular;",
 				"gl_FragColor.xyz = gl_FragColor.xyz * ( totalDiffuse + ambientLightColor * uAmbientColor + totalSpecular );",
 
+				THREE.ShaderChunk[ "shadowmap_fragment" ],
 				THREE.ShaderChunk[ "linear_to_gamma_fragment" ],
 				THREE.ShaderChunk[ "fog_fragment" ],
 
@@ -258,11 +322,9 @@ THREE.ShaderTerrain = {
 
 			"varying vec3 vViewPosition;",
 
-			"void main() {",
-
-				"vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
+			THREE.ShaderChunk[ "shadowmap_pars_vertex" ],
 
-				"vViewPosition = -mvPosition.xyz;",
+			"void main() {",
 
 				"vNormal = normalize( normalMatrix * normal );",
 
@@ -285,18 +347,27 @@ THREE.ShaderTerrain = {
 
 					"vec3 dv = texture2D( tDisplacement, uvBase ).xyz;",
 					"float df = uDisplacementScale * dv.x + uDisplacementBias;",
-					"vec4 displacedPosition = vec4( vNormal.xyz * df, 0.0 ) + mvPosition;",
-					"gl_Position = projectionMatrix * displacedPosition;",
+					"vec3 displacedPosition = normal * df + position;",
+
+					"vec4 mPosition = modelMatrix * vec4( displacedPosition, 1.0 );",
+					"vec4 mvPosition = modelViewMatrix * vec4( displacedPosition, 1.0 );",
 
 				"#else",
 
-					"gl_Position = projectionMatrix * mvPosition;",
+					"vec4 mPosition = modelMatrix * vec4( position, 1.0 );",
+					"vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
 
 				"#endif",
 
+				"gl_Position = projectionMatrix * mvPosition;",
+
+				"vViewPosition = -mvPosition.xyz;",
+
 				"vec3 normalTex = texture2D( tNormal, uvBase ).xyz * 2.0 - 1.0;",
 				"vNormal = normalMatrix * normalTex;",
 
+				THREE.ShaderChunk[ "shadowmap_vertex" ],
+
 			"}"
 
 		].join("\n")