Browse Source

Merge pull request #7110 from tschw/SkinTangents

Skin shader example update.
Mr.doob 10 years ago
parent
commit
47e1c58d19
2 changed files with 62 additions and 59 deletions
  1. 47 54
      examples/js/ShaderSkin.js
  2. 15 5
      examples/webgl_materials_skin.html

+ 47 - 54
examples/js/ShaderSkin.js

@@ -167,7 +167,7 @@ THREE.ShaderSkin = {
 				"diffuseColor = diffuseColor * colDiffuse;",
 
 				"vec3 normal = normalize( vNormal );",
-				"vec3 viewPosition = normalize( vViewPosition );",
+				"vec3 viewerDirection = normalize( vViewPosition );",
 
 				"float specularStrength;",
 
@@ -207,10 +207,10 @@ THREE.ShaderSkin = {
 						"float pointDiffuseWeightHalf = max( 0.5 * dot( normal, lVector ) + 0.5, 0.0 );",
 						"vec3 pointDiffuseWeight = mix( vec3 ( pointDiffuseWeightFull ), vec3( pointDiffuseWeightHalf ), uWrapRGB );",
 
-						"float pointSpecularWeight = KS_Skin_Specular( normal, lVector, viewPosition, uRoughness, uSpecularBrightness );",
+						"float pointSpecularWeight = KS_Skin_Specular( normal, lVector, viewerDirection, uRoughness, uSpecularBrightness );",
 
-						"totalDiffuseLight += attenuation * pointLightColor[ i ] * pointDiffuseWeight;",
-						"totalSpecularLight += attenuation * specular * pointLightColor[ i ] * pointSpecularWeight * specularStrength;",
+						"totalDiffuseLight += pointLightColor[ i ] * ( pointDiffuseWeight * attenuation );",
+						"totalSpecularLight += pointLightColor[ i ] * specular * ( pointSpecularWeight * specularStrength * attenuation );",
 
 					"}",
 
@@ -228,10 +228,10 @@ THREE.ShaderSkin = {
 						"float dirDiffuseWeightHalf = max( 0.5 * dot( normal, dirVector ) + 0.5, 0.0 );",
 						"vec3 dirDiffuseWeight = mix( vec3 ( dirDiffuseWeightFull ), vec3( dirDiffuseWeightHalf ), uWrapRGB );",
 
-						"float dirSpecularWeight = KS_Skin_Specular( normal, dirVector, viewPosition, uRoughness, uSpecularBrightness );",
+						"float dirSpecularWeight = KS_Skin_Specular( normal, dirVector, viewerDirection, uRoughness, uSpecularBrightness );",
 
 						"totalDiffuseLight += directionalLightColor[ i ] * dirDiffuseWeight;",
-						"totalSpecularLight += specular * directionalLightColor[ i ] * dirSpecularWeight * specularStrength;",
+						"totalSpecularLight += directionalLightColor[ i ] * ( dirSpecularWeight * specularStrength );",
 
 					"}",
 
@@ -253,14 +253,16 @@ THREE.ShaderSkin = {
 						// specular (sky light)
 
 						"float hemiSpecularWeight = 0.0;",
-						"hemiSpecularWeight += KS_Skin_Specular( normal, lVector, viewPosition, uRoughness, uSpecularBrightness );",
+						"hemiSpecularWeight += KS_Skin_Specular( normal, lVector, viewerDirection, uRoughness, uSpecularBrightness );",
 
 						// specular (ground light)
 
 						"vec3 lVectorGround = -lVector;",
-						"hemiSpecularWeight += KS_Skin_Specular( normal, lVectorGround, viewPosition, uRoughness, uSpecularBrightness );",
+						"hemiSpecularWeight += KS_Skin_Specular( normal, lVectorGround, viewerDirection, uRoughness, uSpecularBrightness );",
 
-						"totalSpecularLight += specular * mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight ) * hemiSpecularWeight * specularStrength;",
+						"vec3 hemiSpecularColor = mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );",
+
+						"totalSpecularLight += hemiSpecularColor * specular * ( hemiSpecularWeight * specularStrength );",
 
 					"}",
 
@@ -355,7 +357,9 @@ THREE.ShaderSkin = {
 				"opacity": 	  { type: "f", value: 1 },
 
 				"uRoughness": 	  		{ type: "f", value: 0.15 },
-				"uSpecularBrightness": 	{ type: "f", value: 0.75 }
+				"uSpecularBrightness": 	{ type: "f", value: 0.75 },
+
+				"uPixelSize":	{ type: "f", value: 0.01 }
 
 			}
 
@@ -383,9 +387,8 @@ THREE.ShaderSkin = {
 			"uniform sampler2D tBeckmann;",
 
 			"uniform float uNormalScale;",
+			"uniform float uPixelSize;",
 
-			"varying vec3 vTangent;",
-			"varying vec3 vBinormal;",
 			"varying vec3 vNormal;",
 			"varying vec2 vUv;",
 
@@ -453,20 +456,30 @@ THREE.ShaderSkin = {
 
 				"vec4 mSpecular = vec4( specular, opacity );",
 
-				"vec3 normalTex = texture2D( tNormal, vUv ).xyz * 2.0 - 1.0;",
-				"normalTex.xy *= uNormalScale;",
-				"normalTex = normalize( normalTex );",
-
 				"vec4 colDiffuse = texture2D( tDiffuse, vUv );",
 				"colDiffuse *= colDiffuse;",
 
 				"diffuseColor *= colDiffuse;",
 
-				"mat3 tsb = mat3( vTangent, vBinormal, vNormal );",
+				// normal mapping
+
+				"vec2 uz = vec2( vUv.x, vViewPosition.z );",
+				"vec2 uzDx = dFdx( uz ), uzDy = dFdy( uz );",
+				"vec2 tangent2D = normalize( vec2( uzDx.x, uzDy.x ) );",
+				"vec2 zVec2D = vec2( uzDx.y, uzDy.y );",
+				"vec3 tangent = vec3( tangent2D * uPixelSize, dot( tangent2D, zVec2D ) );",
+				"vec3 binormal = normalize( cross( vNormal, tangent ) );",
+				"tangent = cross( binormal, vNormal );",
+				"mat3 tsb = mat3( tangent, binormal, vNormal );",
+
+				"vec3 normalTex = texture2D( tNormal, vUv ).xyz * 2.0 - 1.0;",
+				"normalTex.xy *= uNormalScale;",
+				"normalTex = normalize( normalTex );",
+
 				"vec3 finalNormal = tsb * normalTex;",
 
 				"vec3 normal = normalize( finalNormal );",
-				"vec3 viewPosition = normalize( vViewPosition );",
+				"vec3 viewerDirection = normalize( vViewPosition );",
 
 				// point lights
 
@@ -478,14 +491,19 @@ THREE.ShaderSkin = {
 					"for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {",
 
 						"vec3 pointVector = normalize( vPointLight[ i ].xyz );",
-						"float pointDistance = vPointLight[ i ].w;",
+						"float attenuation = vPointLight[ i ].w;",
 
 						"float pointDiffuseWeight = max( dot( normal, pointVector ), 0.0 );",
 
-						"totalDiffuseLight += pointDistance * pointLightColor[ i ] * pointDiffuseWeight;",
+						"totalDiffuseLight += pointLightColor[ i ] * ( pointDiffuseWeight * attenuation );",
+
+						"if ( passID == 1 ) {",
 
-						"if ( passID == 1 )",
-							"totalSpecularLight += pointDistance * mSpecular.xyz * pointLightColor[ i ] * KS_Skin_Specular( normal, pointVector, viewPosition, uRoughness, uSpecularBrightness );",
+							"float pointSpecularWeight = KS_Skin_Specular( normal, pointVector, viewerDirection, uRoughness, uSpecularBrightness );",
+
+							"totalSpecularLight += pointLightColor[ i ] * mSpecular.xyz * ( pointSpecularWeight * attenuation );",
+
+						"}",
 
 					"}",
 
@@ -503,8 +521,13 @@ THREE.ShaderSkin = {
 
 						"totalDiffuseLight += directionalLightColor[ i ] * dirDiffuseWeight;",
 
-						"if ( passID == 1 )",
-							"totalSpecularLight += mSpecular.xyz * directionalLightColor[ i ] * KS_Skin_Specular( normal, dirVector, viewPosition, uRoughness, uSpecularBrightness );",
+						"if ( passID == 1 ) {",
+
+							"float dirSpecularWeight = KS_Skin_Specular( normal, dirVector, viewerDirection, uRoughness, uSpecularBrightness );",
+
+							"totalSpecularLight += directionalLightColor[ i ] * mSpecular.xyz * dirSpecularWeight;",
+
+						"}",
 
 					"}",
 
@@ -572,8 +595,6 @@ THREE.ShaderSkin = {
 
 		vertexShader: [
 
-			"attribute vec4 tangent;",
-
 			"#ifdef VERTEX_TEXTURES",
 
 				"uniform sampler2D tDisplacement;",
@@ -582,8 +603,6 @@ THREE.ShaderSkin = {
 
 			"#endif",
 
-			"varying vec3 vTangent;",
-			"varying vec3 vBinormal;",
 			"varying vec3 vNormal;",
 			"varying vec2 vUv;",
 
@@ -611,13 +630,6 @@ THREE.ShaderSkin = {
 
 				"vNormal = normalize( normalMatrix * normal );",
 
-				// tangent and binormal vectors
-
-				"vTangent = normalize( normalMatrix * tangent.xyz );",
-
-				"vBinormal = cross( vNormal, vTangent ) * tangent.w;",
-				"vBinormal = normalize( vBinormal );",
-
 				"vUv = uv;",
 
 				// point lights
@@ -659,18 +671,6 @@ THREE.ShaderSkin = {
 
 		vertexShaderUV: [
 
-			"attribute vec4 tangent;",
-
-			"#ifdef VERTEX_TEXTURES",
-
-				"uniform sampler2D tDisplacement;",
-				"uniform float uDisplacementScale;",
-				"uniform float uDisplacementBias;",
-
-			"#endif",
-
-			"varying vec3 vTangent;",
-			"varying vec3 vBinormal;",
 			"varying vec3 vNormal;",
 			"varying vec2 vUv;",
 
@@ -698,13 +698,6 @@ THREE.ShaderSkin = {
 
 				"vNormal = normalize( normalMatrix * normal );",
 
-				// tangent and binormal vectors
-
-				"vTangent = normalize( normalMatrix * tangent.xyz );",
-
-				"vBinormal = cross( vNormal, vTangent ) * tangent.w;",
-				"vBinormal = normalize( vBinormal );",
-
 				"vUv = uv;",
 
 				// point lights

+ 15 - 5
examples/webgl_materials_skin.html

@@ -87,6 +87,8 @@
 			var windowHalfX = window.innerWidth / 2;
 			var windowHalfY = window.innerHeight / 2;
 
+			var pixelSizeUniform = { type: 'f', value: 0.001 };
+
 			var firstPass = true;
 
 			init();
@@ -134,14 +136,18 @@
 				uniformsUV[ "uRoughness" ].value = 0.185;
 				uniformsUV[ "uSpecularBrightness" ].value = 0.8;
 
+
 				var uniforms = THREE.UniformsUtils.clone( uniformsUV );
 				uniforms[ "tDiffuse" ].value = uniformsUV[ "tDiffuse" ].value;
 				uniforms[ "tNormal" ].value = uniformsUV[ "tNormal" ].value;
 				uniforms[ "passID" ].value = 1;
 
-				var parameters = { fragmentShader: shader.fragmentShader, vertexShader: shader.vertexShader, uniforms: uniforms, lights: true };
-				var parametersUV = { fragmentShader: shader.fragmentShader, vertexShader: shader.vertexShaderUV, uniforms: uniformsUV, lights: true };
+				// let those refer to the same object for central control
+				uniformsUV[ "pixelSize" ] = pixelSizeUniform;
+				uniforms[ "pixelSize" ] = pixelSizeUniform;
 
+				var parameters = { fragmentShader: shader.fragmentShader, vertexShader: shader.vertexShader, uniforms: uniforms, lights: true, derivatives: true };
+				var parametersUV = { fragmentShader: shader.fragmentShader, vertexShader: shader.vertexShaderUV, uniforms: uniformsUV, lights: true, derivatives: true };
 
 				material = new THREE.ShaderMaterial( parameters );
 				var materialUV = new THREE.ShaderMaterial( parametersUV );
@@ -156,9 +162,10 @@
 				renderer = new THREE.WebGLRenderer( { antialias: false } );
 				renderer.setClearColor( 0x050505 );
 				renderer.setPixelRatio( window.devicePixelRatio );
-				renderer.setSize( window.innerWidth, window.innerHeight );
 				renderer.autoClear = false;
 
+				onWindowResize(); // sets size
+
 				container.appendChild( renderer.domElement );
 
 				// STATS
@@ -267,14 +274,17 @@
 				camera.aspect = window.innerWidth / window.innerHeight;
 				camera.updateProjectionMatrix();
 
+				var projection00 = camera.projectionMatrix.elements[0];
+				// == 1 / windowHalfX, in view space, assuming near == 1
+
+				pixelSizeUniform.value = 1 / ( projection00 * windowHalfX );
+
 				renderer.setSize( window.innerWidth, window.innerHeight );
 
 			}
 
 			function createScene( geometry, scale, material ) {
 
-				geometry.computeTangents();
-
 				mesh = new THREE.Mesh( geometry, material );
 				mesh.position.y = - 50;
 				mesh.scale.set( scale, scale, scale );