|
@@ -483,7 +483,7 @@ THREE.ShaderDeferred = {
|
|
|
|
|
|
// simple specular
|
|
|
|
|
|
- //"vec3 specular = specularIntensity * max( pow( dotNormalHalf, shininess ), 0.0 ) * diffuse;",
|
|
|
+ //"vec3 specular = max( pow( dotNormalHalf, shininess ), 0.0 ) * diffuse;",
|
|
|
|
|
|
// physically based specular
|
|
|
|
|
@@ -506,7 +506,6 @@ THREE.ShaderDeferred = {
|
|
|
|
|
|
"}",
|
|
|
|
|
|
-
|
|
|
"}"
|
|
|
|
|
|
].join("\n"),
|
|
@@ -531,6 +530,174 @@ THREE.ShaderDeferred = {
|
|
|
|
|
|
},
|
|
|
|
|
|
+ "spotLight" : {
|
|
|
+
|
|
|
+ uniforms: {
|
|
|
+
|
|
|
+ samplerNormalDepth: { type: "t", value: null },
|
|
|
+ samplerColor: { type: "t", value: null },
|
|
|
+ matView: { type: "m4", value: new THREE.Matrix4() },
|
|
|
+ matProjInverse: { type: "m4", value: new THREE.Matrix4() },
|
|
|
+ viewWidth: { type: "f", value: 800 },
|
|
|
+ viewHeight: { type: "f", value: 600 },
|
|
|
+ lightPositionWS:{ type: "v3", value: new THREE.Vector3( 0, 1, 0 ) },
|
|
|
+ lightTargetWS: { type: "v3", value: new THREE.Vector3( 0, 1, 0 ) },
|
|
|
+ lightColor: { type: "c", value: new THREE.Color( 0x000000 ) },
|
|
|
+ lightIntensity: { type: "f", value: 1.0 },
|
|
|
+ lightDistance: { type: "f", value: 1.0 },
|
|
|
+ lightAngle: { type: "f", value: 1.0 }
|
|
|
+
|
|
|
+ },
|
|
|
+
|
|
|
+ fragmentShader : [
|
|
|
+
|
|
|
+ "uniform sampler2D samplerColor;",
|
|
|
+ "uniform sampler2D samplerNormalDepth;",
|
|
|
+
|
|
|
+ "uniform float viewHeight;",
|
|
|
+ "uniform float viewWidth;",
|
|
|
+
|
|
|
+ "uniform float lightAngle;"+
|
|
|
+ "uniform float lightIntensity;"+
|
|
|
+ "uniform vec3 lightColor;",
|
|
|
+
|
|
|
+ "uniform mat4 matProjInverse;",
|
|
|
+
|
|
|
+ "varying vec3 vLightPositionVS;",
|
|
|
+ "varying vec3 vLightDirectionVS;",
|
|
|
+
|
|
|
+ "vec3 float_to_vec3( float data ) {",
|
|
|
+
|
|
|
+ "vec3 uncompressed;",
|
|
|
+ "uncompressed.x = fract( data );",
|
|
|
+ "float zInt = floor( data / 255.0 );",
|
|
|
+ "uncompressed.z = fract( zInt / 255.0 );",
|
|
|
+ "uncompressed.y = fract( floor( data - ( zInt * 255.0 ) ) / 255.0 );",
|
|
|
+ "return uncompressed;",
|
|
|
+
|
|
|
+ "}",
|
|
|
+
|
|
|
+ "void main() {",
|
|
|
+
|
|
|
+ "vec2 texCoord = gl_FragCoord.xy / vec2( viewWidth, viewHeight );",
|
|
|
+
|
|
|
+ "vec4 normalDepth = texture2D( samplerNormalDepth, texCoord );",
|
|
|
+ "float z = normalDepth.w;",
|
|
|
+
|
|
|
+ "if ( z == 0.0 ) discard;",
|
|
|
+
|
|
|
+ "float x = texCoord.x * 2.0 - 1.0;",
|
|
|
+ "float y = texCoord.y * 2.0 - 1.0;",
|
|
|
+
|
|
|
+ "vec4 projectedPos = vec4( x, y, z, 1.0 );",
|
|
|
+ "vec4 positionVS = matProjInverse * projectedPos;",
|
|
|
+ "positionVS.xyz /= positionVS.w;",
|
|
|
+ "positionVS.w = 1.0;",
|
|
|
+
|
|
|
+ // normal
|
|
|
+
|
|
|
+ "vec3 normal = normalDepth.xyz * 2.0 - 1.0;",
|
|
|
+
|
|
|
+ // color
|
|
|
+
|
|
|
+ "vec4 colorMap = texture2D( samplerColor, texCoord );",
|
|
|
+
|
|
|
+ "vec3 albedo = float_to_vec3( abs( colorMap.x ) );",
|
|
|
+ "vec3 specularColor = float_to_vec3( abs( colorMap.y ) );",
|
|
|
+ "float shininess = abs( colorMap.z );",
|
|
|
+ "float wrapAround = sign( colorMap.z );",
|
|
|
+ "float additiveSpecular = sign( colorMap.y );",
|
|
|
+
|
|
|
+ //
|
|
|
+
|
|
|
+ "vec3 surfToLight = normalize( vLightPositionVS.xyz - positionVS.xyz );",
|
|
|
+ "float dotProduct = max( dot( normal, surfToLight ), 0.0 );",
|
|
|
+
|
|
|
+ "float rho = dot( vLightDirectionVS, -surfToLight );",
|
|
|
+ "float rhoMax = cos( lightAngle * 0.5 );",
|
|
|
+
|
|
|
+ "if ( rho > rhoMax ) {",
|
|
|
+
|
|
|
+ "float theta = rhoMax + 0.0001;",
|
|
|
+ "float phi = rhoMax + 0.05;",
|
|
|
+ "float falloff = 4.0;",
|
|
|
+
|
|
|
+ "float spot = 0.0;",
|
|
|
+
|
|
|
+ "if ( rho >= phi ) {",
|
|
|
+
|
|
|
+ "spot = 1.0;",
|
|
|
+
|
|
|
+ "} else if ( rho <= theta ) {",
|
|
|
+
|
|
|
+ "spot = 0.0;",
|
|
|
+
|
|
|
+ "} else { ",
|
|
|
+
|
|
|
+ "spot = pow( ( rho - theta ) / ( phi - theta ), falloff );",
|
|
|
+
|
|
|
+ "}",
|
|
|
+
|
|
|
+ "float diffuse = spot * dotProduct;",
|
|
|
+
|
|
|
+ "vec3 halfVector = normalize( surfToLight - normalize( positionVS.xyz ) );",
|
|
|
+ "float dotNormalHalf = max( dot( normal, halfVector ), 0.0 );",
|
|
|
+
|
|
|
+ // simple specular
|
|
|
+
|
|
|
+ "vec3 specular = max( pow( dotNormalHalf, shininess ), 0.0 ) * spot * diffuse * specularColor;",
|
|
|
+
|
|
|
+ // combine
|
|
|
+
|
|
|
+ "vec3 light = lightIntensity * lightColor;",
|
|
|
+
|
|
|
+ "if ( additiveSpecular < 0.0 ) {",
|
|
|
+
|
|
|
+ "gl_FragColor = vec4( light * ( albedo * diffuse + specular ), 1.0 );",
|
|
|
+
|
|
|
+ "} else {",
|
|
|
+
|
|
|
+ "gl_FragColor = vec4( light * albedo * ( diffuse + specular ), 1.0 );",
|
|
|
+
|
|
|
+ "}",
|
|
|
+
|
|
|
+ "return;",
|
|
|
+
|
|
|
+
|
|
|
+ "}",
|
|
|
+
|
|
|
+ "gl_FragColor = vec4( 0.0 );",
|
|
|
+
|
|
|
+ "}"
|
|
|
+
|
|
|
+ ].join("\n"),
|
|
|
+
|
|
|
+ vertexShader : [
|
|
|
+
|
|
|
+ "uniform vec3 lightPositionWS;",
|
|
|
+ "uniform vec3 lightTargetWS;",
|
|
|
+
|
|
|
+ "uniform mat4 matView;",
|
|
|
+
|
|
|
+ "varying vec3 vLightPositionVS;",
|
|
|
+ "varying vec3 vLightDirectionVS;",
|
|
|
+
|
|
|
+ "void main() { ",
|
|
|
+
|
|
|
+ "vec4 quadPosition = vec4( sign( position.xy ), 0.0, 1.0 );",
|
|
|
+ "gl_Position = quadPosition;",
|
|
|
+
|
|
|
+ "vLightPositionVS = vec3( matView * vec4( lightPositionWS, 1.0 ) );",
|
|
|
+
|
|
|
+ "vec3 lightDirectionWS = lightTargetWS - lightPositionWS;"+
|
|
|
+ "vLightDirectionVS = normalize( mat3( matView ) * lightDirectionWS );",
|
|
|
+
|
|
|
+ "}"
|
|
|
+
|
|
|
+ ].join("\n")
|
|
|
+
|
|
|
+ },
|
|
|
+
|
|
|
"directionalLight" : {
|
|
|
|
|
|
uniforms: {
|