Use specular texture RGB as specular reflectance, multiplied by per-material value.

This commit is contained in:
SmileTheory 2013-05-03 00:32:59 -07:00
parent aff3f18101
commit 3a47192ba8

View file

@ -140,7 +140,7 @@ float RayIntersectDisplaceMap(vec2 dp, vec2 ds, sampler2D normalMap)
} }
#endif #endif
float CalcDiffuse(vec3 N, vec3 L, vec3 E, float NE, float NL, float fzero, float shininess) vec3 CalcDiffuse(vec3 diffuseAlbedo, vec3 N, vec3 L, vec3 E, float NE, float NL, float shininess)
{ {
#if defined(USE_OREN_NAYAR) || defined(USE_TRIACE_OREN_NAYAR) #if defined(USE_OREN_NAYAR) || defined(USE_TRIACE_OREN_NAYAR)
float gamma = dot(E, L) - NE * NL; float gamma = dot(E, L) - NE * NL;
@ -160,25 +160,25 @@ float CalcDiffuse(vec3 N, vec3 L, vec3 E, float NE, float NL, float fzero, float
B *= max(max(NL, NE), EPSILON); B *= max(max(NL, NE), EPSILON);
} }
return (A + gamma / B) * (1.0 - fzero); return diffuseAlbedo * (A + gamma / B);
#else #else
return 1.0 - fzero; return diffuseAlbedo;
#endif #endif
} }
#if defined(USE_SPECULARMAP) #if defined(USE_SPECULARMAP)
float CalcSpecular(float NH, float NL, float NE, float EH, float fzero, float shininess) vec3 CalcSpecular(vec3 specularReflectance, float NH, float NL, float NE, float EH, float shininess)
{ {
#if defined(USE_BLINN) || defined(USE_TRIACE) || defined(USE_TORRANCE_SPARROW) #if defined(USE_BLINN) || defined(USE_TRIACE) || defined(USE_TORRANCE_SPARROW)
float blinn = pow(NH, shininess); float blinn = pow(NH, shininess);
#endif #endif
#if defined(USE_BLINN) #if defined(USE_BLINN)
return blinn; return specularReflectance * blinn;
#endif #endif
#if defined(USE_COOK_TORRANCE) || defined (USE_TRIACE) || defined (USE_TORRANCE_SPARROW) #if defined(USE_COOK_TORRANCE) || defined (USE_TRIACE) || defined (USE_TORRANCE_SPARROW)
float fresnel = fzero + (1.0 - fzero) * pow(1.0 - EH, 5); vec3 fresnel = specularReflectance + (vec3(1.0) - specularReflectance) * pow(1.0 - EH, 5);
#endif #endif
#if defined(USE_COOK_TORRANCE) || defined(USE_TORRANCE_SPARROW) #if defined(USE_COOK_TORRANCE) || defined(USE_TORRANCE_SPARROW)
@ -296,11 +296,15 @@ void main()
} }
#endif #endif
vec4 diffuse = texture2D(u_DiffuseMap, texCoords); vec4 diffuseAlbedo = texture2D(u_DiffuseMap, texCoords);
#if defined(USE_LIGHT) && defined(USE_GAMMA2_TEXTURES)
diffuseAlbedo.rgb *= diffuseAlbedo.rgb;
#endif
#if defined(USE_LIGHT) && defined(USE_FAST_LIGHT) #if defined(USE_LIGHT) && defined(USE_FAST_LIGHT)
gl_FragColor = diffuse.rgb;
#if defined(USE_LIGHTMAP) #if defined(USE_LIGHTMAP)
diffuse.rgb *= lightColor; gl_FragColor *= lightColor;
#endif #endif
#elif defined(USE_LIGHT) #elif defined(USE_LIGHT)
L = normalize(L); L = normalize(L);
@ -363,28 +367,28 @@ void main()
float NL = clamp(dot(N, L), 0.0, 1.0); float NL = clamp(dot(N, L), 0.0, 1.0);
float NE = clamp(dot(N, E), 0.0, 1.0); float NE = clamp(dot(N, E), 0.0, 1.0);
float fzero = u_MaterialInfo.x; float maxReflectance = u_MaterialInfo.x;
float shininess = u_MaterialInfo.y; float shininess = u_MaterialInfo.y;
#if defined(USE_SPECULARMAP) #if defined(USE_SPECULARMAP)
vec4 specular = texture2D(u_SpecularMap, texCoords); vec4 specularReflectance = texture2D(u_SpecularMap, texCoords);
//specular.rgb = clamp(specular.rgb - diffuse.rgb, 0.0, 1.0); specularReflectance.rgb *= maxReflectance;
shininess *= specular.a; shininess *= specularReflectance.a;
// adjust diffuse by specular reflectance, to maintain energy conservation
diffuseAlbedo.rgb *= vec3(1.0) - specularReflectance.rgb;
#endif #endif
float diffuseIntensity = NL * CalcDiffuse(N, L, E, NE, NL, fzero, shininess); gl_FragColor.rgb = lightColor * NL * CalcDiffuse(diffuseAlbedo.rgb, N, L, E, NE, NL, shininess);
gl_FragColor.rgb += ambientDiff * ambientColor * diffuseAlbedo.rgb;
#if defined(USE_PRIMARY_LIGHT) #if defined(USE_PRIMARY_LIGHT)
vec3 L2 = var_PrimaryLightDirection; vec3 L2 = var_PrimaryLightDirection;
float NL2 = clamp(dot(N, L2), 0.0, 1.0); float NL2 = clamp(dot(N, L2), 0.0, 1.0);
float diffuseIntensity2 = NL2 * CalcDiffuse(N, L2, E, NE, NL2, fzero, shininess);
#if defined(USE_SHADOWMAP)
diffuseIntensity2 *= shadowValue;
#endif
diffuse.rgb *= lightColor * diffuseIntensity + u_PrimaryLightColor * diffuseIntensity2 + ambientDiff * ambientColor; #if defined(USE_SHADOWMAP)
gl_FragColor.rgb += u_PrimaryLightColor * shadowValue * NL2 * CalcDiffuse(diffuseAlbedo.rgb, N, L2, E, NE, NL2, shininess);
#else #else
diffuse.rgb *= lightColor * diffuseIntensity + ambientDiff * ambientColor; gl_FragColor.rgb += u_PrimaryLightColor * NL2 * CalcDiffuse(diffuseAlbedo.rgb, N, L2, E, NE, NL2, shininess);
#endif
#endif #endif
#if defined(USE_SPECULARMAP) #if defined(USE_SPECULARMAP)
@ -393,39 +397,33 @@ void main()
float EH = clamp(dot(E, H), 0.0, 1.0); float EH = clamp(dot(E, H), 0.0, 1.0);
float NH = clamp(dot(N, H), 0.0, 1.0); float NH = clamp(dot(N, H), 0.0, 1.0);
float specularIntensity = NL * CalcSpecular(NH, NL, NE, EH, fzero, shininess); gl_FragColor.rgb += lightColor * NL * CalcSpecular(specularReflectance.rgb, NH, NL, NE, EH, shininess);
#if defined(r_normalAmbient) #if defined(r_normalAmbient)
vec3 ambientHalf = normalize(surfN + E); vec3 ambientHalf = normalize(surfN + E);
float ambientSpec = max(dot(ambientHalf, N) + 0.5, 0.0); float ambientSpec = max(dot(ambientHalf, N) + 0.5, 0.0);
ambientSpec *= ambientSpec * 0.44; ambientSpec *= ambientSpec * 0.44;
ambientSpec = pow(ambientSpec, shininess) * fzero; gl_FragColor.rgb += specularReflectance.rgb * ambientSpec * ambientColor;
#else
float ambientSpec = 0.0;
#endif #endif
#if defined(USE_PRIMARY_LIGHT) #if defined(USE_PRIMARY_LIGHT)
vec3 H2 = normalize(L2 + E); vec3 H2 = normalize(L2 + E);
float EH2 = clamp(dot(E, H2), 0.0, 1.0); float EH2 = clamp(dot(E, H2), 0.0, 1.0);
float NH2 = clamp(dot(N, H2), 0.0, 1.0); float NH2 = clamp(dot(N, H2), 0.0, 1.0);
float specularIntensity2 = NL * CalcSpecular(NH2, NL2, NE, EH2, fzero, shininess);
#if defined(USE_SHADOWMAP) #if defined(USE_SHADOWMAP)
specularIntensity2 *= shadowValue; gl_FragColor.rgb += u_PrimaryLightColor * shadowValue * NL2 * CalcSpecular(specularReflectance.rgb, NH2, NL2, NE, EH2, shininess);
#endif
specular.rgb *= specularIntensity * lightColor + specularIntensity2 * u_PrimaryLightColor + ambientSpec * ambientColor;
#else #else
specular.rgb *= specularIntensity * lightColor + ambientSpec * ambientColor; gl_FragColor.rgb += u_PrimaryLightColor * NL2 * CalcSpecular(specularReflectance.rgb, NH2, NL2, NE, EH2, shininess);
#endif #endif
#endif #endif
#endif
#else
gl_FragColor.rgb = diffuseAlbedo.rgb;
#endif #endif
gl_FragColor = diffuse; gl_FragColor.a = diffuseAlbedo.a;
#if defined(USE_SPECULARMAP) && defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
gl_FragColor.rgb += specular.rgb;
#endif
gl_FragColor *= var_Color; gl_FragColor *= var_Color;
} }