diff --git a/examples/js/ShaderSkin.js b/examples/js/ShaderSkin.js index 1debbaac4064829d04504637ba5bdb374d808803..8866dbf7a0144fcc73013bb5fc0b5b9b578f9db9 100644 --- a/examples/js/ShaderSkin.js +++ b/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 diff --git a/examples/webgl_materials_skin.html b/examples/webgl_materials_skin.html index a4f8b9b48ee45bc59e84911c78f2416b35672f76..d8f74aff8394ea29cd5fa01b50073fcf7e533f65 100644 --- a/examples/webgl_materials_skin.html +++ b/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 );