diff options
author | Tim Angus <tim@ngus.net> | 2016-04-09 17:57:28 +0100 |
---|---|---|
committer | Tim Angus <tim@ngus.net> | 2016-04-09 17:57:28 +0100 |
commit | f45fbef604e05144057dec8d1dbfc5d4f5a2a822 (patch) | |
tree | 152d2a428b078f7a89756ea9e156695fc69f1686 /src/renderergl2/glsl/lightall_fp.glsl | |
parent | 7f9e97d611b4b267d9dd913144cb9632f96c90c2 (diff) | |
parent | 87abdd914988724e164ffb16380ad26be8420b84 (diff) |
Merge branch 'master' into gpp
Diffstat (limited to 'src/renderergl2/glsl/lightall_fp.glsl')
-rw-r--r-- | src/renderergl2/glsl/lightall_fp.glsl | 342 |
1 files changed, 84 insertions, 258 deletions
diff --git a/src/renderergl2/glsl/lightall_fp.glsl b/src/renderergl2/glsl/lightall_fp.glsl index d1182781..64cae3fa 100644 --- a/src/renderergl2/glsl/lightall_fp.glsl +++ b/src/renderergl2/glsl/lightall_fp.glsl @@ -29,11 +29,6 @@ uniform samplerCube u_CubeMap; uniform vec4 u_EnableTextures; #endif -#if defined(USE_LIGHT_VECTOR) && !defined(USE_FAST_LIGHT) -uniform vec3 u_DirectedLight; -uniform vec3 u_AmbientLight; -#endif - #if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP) uniform vec3 u_PrimaryLightColor; uniform vec3 u_PrimaryLightAmbient; @@ -53,6 +48,9 @@ uniform vec4 u_CubeMapInfo; varying vec4 var_TexCoords; varying vec4 var_Color; +#if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) +varying vec4 var_ColorAmbient; +#endif #if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) #if defined(USE_VERT_TANGENT_SPACE) @@ -150,156 +148,35 @@ float RayIntersectDisplaceMap(vec2 dp, vec2 ds, sampler2D normalMap) } #endif -vec3 CalcDiffuse(vec3 diffuseAlbedo, vec3 N, vec3 L, vec3 E, float NE, float NL, float shininess) +vec3 CalcDiffuse(vec3 diffuseAlbedo, float NH, float EH, float roughness) { - #if defined(USE_OREN_NAYAR) || defined(USE_TRIACE_OREN_NAYAR) - float gamma = dot(E, L) - NE * NL; - float B = 2.22222 + 0.1 * shininess; - - #if defined(USE_OREN_NAYAR) - float A = 1.0 - 1.0 / (2.0 + 0.33 * shininess); - gamma = clamp(gamma, 0.0, 1.0); - #endif - - #if defined(USE_TRIACE_OREN_NAYAR) - float A = 1.0 - 1.0 / (2.0 + 0.65 * shininess); - - if (gamma >= 0.0) - #endif - { - B = max(B * max(NL, NE), EPSILON); - } - - return diffuseAlbedo * (A + gamma / B); - #else - return diffuseAlbedo; - #endif -} - -vec3 EnvironmentBRDF(float gloss, float NE, vec3 specular) -{ - #if 1 - // from http://blog.selfshadow.com/publications/s2013-shading-course/lazarov/s2013_pbs_black_ops_2_notes.pdf - vec4 t = vec4( 1.0/0.96, 0.475, (0.0275 - 0.25 * 0.04)/0.96,0.25 ) * gloss; - t += vec4( 0.0, 0.0, (0.015 - 0.75 * 0.04)/0.96,0.75 ); - float a0 = t.x * min( t.y, exp2( -9.28 * NE ) ) + t.z; - float a1 = t.w; - return clamp( a0 + specular * ( a1 - a0 ), 0.0, 1.0 ); - #elif 0 - // from http://seblagarde.wordpress.com/2011/08/17/hello-world/ - return specular + CalcFresnel(NE) * clamp(vec3(gloss) - specular, 0.0, 1.0); - #else - // from http://advances.realtimerendering.com/s2011/Lazarov-Physically-Based-Lighting-in-Black-Ops%20%28Siggraph%202011%20Advances%20in%20Real-Time%20Rendering%20Course%29.pptx - return mix(specular.rgb, vec3(1.0), CalcFresnel(NE) / (4.0 - 3.0 * gloss)); - #endif -} - -float CalcBlinn(float NH, float shininess) -{ -#if defined(USE_BLINN) || defined(USE_BLINN_FRESNEL) - // Normalized Blinn-Phong - float norm = shininess * 0.125 + 1.0; -#elif defined(USE_MCAULEY) - // Cook-Torrance as done by Stephen McAuley - // http://blog.selfshadow.com/publications/s2012-shading-course/mcauley/s2012_pbs_farcry3_notes_v2.pdf - float norm = shininess * 0.25 + 0.125; -#elif defined(USE_GOTANDA) - // Neumann-Neumann as done by Yoshiharu Gotanda - // http://research.tri-ace.com/Data/s2012_beyond_CourseNotes.pdf - float norm = shininess * 0.124858 + 0.269182; -#elif defined(USE_LAZAROV) - // Cook-Torrance as done by Dimitar Lazarov - // http://blog.selfshadow.com/publications/s2013-shading-course/lazarov/s2013_pbs_black_ops_2_notes.pdf - float norm = shininess * 0.125 + 0.25; -#else - float norm = 1.0; -#endif - -#if 0 - // from http://seblagarde.wordpress.com/2012/06/03/spherical-gaussien-approximation-for-blinn-phong-phong-and-fresnel/ - float a = shininess + 0.775; - return norm * exp(a * NH - a); +#if defined(USE_BURLEY) + // modified from https://disney-animation.s3.amazonaws.com/library/s2012_pbs_disney_brdf_notes_v2.pdf + float fd90 = -0.5 + EH * EH * roughness; + float burley = 1.0 + fd90 * 0.04 / NH; + burley *= burley; + return diffuseAlbedo * burley; #else - return norm * pow(NH, shininess); -#endif -} - -float CalcGGX(float NH, float gloss) -{ - // from http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf - float a_sq = exp2(gloss * -13.0 + 1.0); - float d = ((NH * NH) * (a_sq - 1.0) + 1.0); - return a_sq / (d * d); -} - -float CalcFresnel(float EH) -{ -#if 1 - // From http://blog.selfshadow.com/publications/s2013-shading-course/lazarov/s2013_pbs_black_ops_2_notes.pdf - // not accurate, but fast - return exp2(-10.0 * EH); -#elif 0 - // From http://seblagarde.wordpress.com/2012/06/03/spherical-gaussien-approximation-for-blinn-phong-phong-and-fresnel/ - return exp2((-5.55473 * EH - 6.98316) * EH); -#elif 0 - float blend = 1.0 - EH; - float blend2 = blend * blend; - blend *= blend2 * blend2; - - return blend; -#else - return pow(1.0 - EH, 5.0); + return diffuseAlbedo; #endif } -float CalcVisibility(float NH, float NL, float NE, float EH, float gloss) +vec3 EnvironmentBRDF(float roughness, float NE, vec3 specular) { -#if defined(USE_GOTANDA) - // Neumann-Neumann as done by Yoshiharu Gotanda - // http://research.tri-ace.com/Data/s2012_beyond_CourseNotes.pdf - return 1.0 / max(max(NL, NE), EPSILON); -#elif defined(USE_LAZAROV) - // Cook-Torrance as done by Dimitar Lazarov - // http://blog.selfshadow.com/publications/s2013-shading-course/lazarov/s2013_pbs_black_ops_2_notes.pdf - float k = min(1.0, gloss + 0.545); - return 1.0 / (k * (EH * EH - 1.0) + 1.0); -#elif defined(USE_GGX) - float roughness = exp2(gloss * -6.5); - - // Modified from http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf - // NL, NE in numerator factored out from cook-torrance - float k = roughness + 1.0; - k *= k * 0.125; - - float k2 = 1.0 - k; - - float invGeo1 = NL * k2 + k; - float invGeo2 = NE * k2 + k; - - return 1.0 / (invGeo1 * invGeo2); -#else - return 1.0; -#endif + // from http://community.arm.com/servlet/JiveServlet/download/96891546-19496/siggraph2015-mmg-renaldas-slides.pdf + float v = 1.0 - max(roughness, NE); + v *= v * v; + return vec3(v) + specular; } - -vec3 CalcSpecular(vec3 specular, float NH, float NL, float NE, float EH, float gloss, float shininess) +vec3 CalcSpecular(vec3 specular, float NH, float EH, float roughness) { -#if defined(USE_GGX) - float distrib = CalcGGX(NH, gloss); -#else - float distrib = CalcBlinn(NH, shininess); -#endif - -#if defined(USE_BLINN) - vec3 fSpecular = specular; -#else - vec3 fSpecular = mix(specular, vec3(1.0), CalcFresnel(EH)); -#endif - - float vis = CalcVisibility(NH, NL, NE, EH, gloss); - - return fSpecular * (distrib * vis); + // from http://community.arm.com/servlet/JiveServlet/download/96891546-19496/siggraph2015-mmg-renaldas-slides.pdf + float rr = roughness*roughness; + float rrrr = rr*rr; + float d = (NH * NH) * (rrrr - 1.0) + 1.0; + float v = (EH * EH) * (roughness + 0.5); + return specular * (rrrr / (4.0 * d * d * v)); } @@ -341,7 +218,7 @@ mat3 cotangent_frame( vec3 N, vec3 p, vec2 uv ) void main() { - vec3 viewDir, lightColor, ambientColor; + vec3 viewDir, lightColor, ambientColor, reflectance; vec3 L, N, E, H; float NL, NH, NE, EH, attenuation; @@ -353,21 +230,20 @@ void main() mat3 tangentToWorld = cotangent_frame(var_Normal, -var_ViewDir, var_TexCoords.xy); viewDir = var_ViewDir; #endif - E = normalize(viewDir); - - L = var_LightDir.xyz; - #if defined(USE_DELUXEMAP) - L += (texture2D(u_DeluxeMap, var_TexCoords.zw).xyz - vec3(0.5)) * u_EnableTextures.y; - #endif - float sqrLightDist = dot(L, L); #endif + lightColor = var_Color.rgb; + #if defined(USE_LIGHTMAP) vec4 lightmapColor = texture2D(u_LightMap, var_TexCoords.zw); #if defined(RGBM_LIGHTMAP) lightmapColor.rgb *= lightmapColor.a; #endif + #if defined(USE_PBR) && !defined(USE_FAST_LIGHT) + lightmapColor.rgb *= lightmapColor.rgb; + #endif + lightColor *= lightmapColor.rgb; #endif vec2 texCoords = var_TexCoords.xy; @@ -383,17 +259,16 @@ void main() vec4 diffuse = texture2D(u_DiffuseMap, texCoords); #if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) - #if defined(USE_LIGHTMAP) - lightColor = lightmapColor.rgb * var_Color.rgb; - ambientColor = vec3(0.0); - attenuation = 1.0; - #elif defined(USE_LIGHT_VECTOR) - lightColor = u_DirectedLight * var_Color.rgb; - ambientColor = u_AmbientLight * var_Color.rgb; + L = var_LightDir.xyz; + #if defined(USE_DELUXEMAP) + L += (texture2D(u_DeluxeMap, var_TexCoords.zw).xyz - vec3(0.5)) * u_EnableTextures.y; + #endif + float sqrLightDist = dot(L, L); + L /= sqrt(sqrLightDist); + + #if defined(USE_LIGHT_VECTOR) attenuation = CalcLightAttenuation(float(var_LightDir.w > 0.0), var_LightDir.w / sqrLightDist); - #elif defined(USE_LIGHT_VERTEX) - lightColor = var_Color.rgb; - ambientColor = vec3(0.0); + #else attenuation = 1.0; #endif @@ -411,33 +286,20 @@ void main() #endif N = normalize(N); - L /= sqrt(sqrLightDist); #if defined(USE_SHADOWMAP) vec2 shadowTex = gl_FragCoord.xy * r_FBufScale; float shadowValue = texture2D(u_ShadowMap, shadowTex).r; // surfaces not facing the light are always shadowed - shadowValue *= float(dot(var_Normal.xyz, var_PrimaryLightDir.xyz) > 0.0); + shadowValue *= clamp(dot(N, var_PrimaryLightDir.xyz), 0.0, 1.0); #if defined(SHADOWMAP_MODULATE) - //vec3 shadowColor = min(u_PrimaryLightAmbient, lightColor); - vec3 shadowColor = u_PrimaryLightAmbient * lightColor; - - #if 0 - // Only shadow when the world light is parallel to the primary light - shadowValue = 1.0 + (shadowValue - 1.0) * clamp(dot(L, var_PrimaryLightDir.xyz), 0.0, 1.0); - #endif - lightColor = mix(shadowColor, lightColor, shadowValue); + lightColor *= shadowValue * (1.0 - u_PrimaryLightAmbient.r) + u_PrimaryLightAmbient.r; #endif #endif - #if defined(r_lightGamma) - lightColor = pow(lightColor, vec3(r_lightGamma)); - ambientColor = pow(ambientColor, vec3(r_lightGamma)); - #endif - - #if defined(USE_LIGHTMAP) || defined(USE_LIGHT_VERTEX) + #if !defined(USE_LIGHT_VECTOR) ambientColor = lightColor; float surfNL = clamp(dot(var_Normal.xyz, L), 0.0, 1.0); @@ -447,10 +309,10 @@ void main() // Recover any unused light as ambient, in case attenuation is over 4x or // light is below the surface - ambientColor = clamp(ambientColor - lightColor * surfNL, 0.0, 1.0); + ambientColor = max(ambientColor - lightColor * surfNL, vec3(0.0)); + #else + ambientColor = var_ColorAmbient.rgb; #endif - - vec3 reflectance; NL = clamp(dot(N, L), 0.0, 1.0); NE = clamp(dot(N, E), 0.0, 1.0); @@ -460,70 +322,47 @@ void main() #else vec4 specular = vec4(1.0); #endif - specular *= u_SpecularScale; - #if defined(r_materialGamma) - diffuse.rgb = pow(diffuse.rgb, vec3(r_materialGamma)); - specular.rgb = pow(specular.rgb, vec3(r_materialGamma)); + #if defined(USE_PBR) + diffuse.rgb *= diffuse.rgb; #endif + #if defined(USE_PBR) + // diffuse rgb is base color + // specular red is gloss + // specular green is metallicness + float gloss = specular.r; + float metal = specular.g; + specular.rgb = metal * diffuse.rgb + vec3(0.04 - 0.04 * metal); + diffuse.rgb *= 1.0 - metal; + #else + // diffuse rgb is diffuse + // specular rgb is specular reflectance at normal incidence + // specular alpha is gloss float gloss = specular.a; - float shininess = exp2(gloss * 13.0); - - #if defined(SPECULAR_IS_METALLIC) - // diffuse is actually base color, and red of specular is metallicness - float metallic = specular.r; - specular.rgb = (0.96 * metallic) * diffuse.rgb + vec3(0.04); - diffuse.rgb *= 1.0 - metallic; - #else // adjust diffuse by specular reflectance, to maintain energy conservation diffuse.rgb *= vec3(1.0) - specular.rgb; #endif - reflectance = CalcDiffuse(diffuse.rgb, N, L, E, NE, NL, shininess); - - #if defined(r_deluxeSpecular) || defined(USE_LIGHT_VECTOR) - float adjGloss = gloss; - float adjShininess = shininess; - - #if !defined(USE_LIGHT_VECTOR) - adjGloss *= r_deluxeSpecular; - adjShininess = exp2(adjGloss * 13.0); - #endif - - H = normalize(L + E); - - EH = clamp(dot(E, H), 0.0, 1.0); - NH = clamp(dot(N, H), 0.0, 1.0); - - #if !defined(USE_LIGHT_VECTOR) - reflectance += CalcSpecular(specular.rgb, NH, NL, NE, EH, adjGloss, adjShininess) * r_deluxeSpecular; - #else - reflectance += CalcSpecular(specular.rgb, NH, NL, NE, EH, adjGloss, adjShininess); - #endif + #if defined(GLOSS_IS_GLOSS) + float roughness = exp2(-3.0 * gloss); + #elif defined(GLOSS_IS_SMOOTHNESS) + float roughness = 1.0 - gloss; + #elif defined(GLOSS_IS_ROUGHNESS) + float roughness = gloss; + #elif defined(GLOSS_IS_SHININESS) + float roughness = pow(2.0 / (8190.0 * gloss + 2.0), 0.25); #endif - gl_FragColor.rgb = lightColor * reflectance * (attenuation * NL); - -#if 0 - vec3 aSpecular = EnvironmentBRDF(gloss, NE, specular.rgb); - - // do ambient as two hemisphere lights, one straight up one straight down - float hemiDiffuseUp = N.z * 0.5 + 0.5; - float hemiDiffuseDown = 1.0 - hemiDiffuseUp; - float hemiSpecularUp = mix(hemiDiffuseUp, float(N.z >= 0.0), gloss); - float hemiSpecularDown = 1.0 - hemiSpecularUp; + reflectance = CalcDiffuse(diffuse.rgb, NH, EH, roughness); - gl_FragColor.rgb += ambientColor * 0.75 * (diffuse.rgb * hemiDiffuseUp + aSpecular * hemiSpecularUp); - gl_FragColor.rgb += ambientColor * 0.25 * (diffuse.rgb * hemiDiffuseDown + aSpecular * hemiSpecularDown); -#else - gl_FragColor.rgb += ambientColor * (diffuse.rgb + specular.rgb); -#endif + gl_FragColor.rgb = lightColor * reflectance * (attenuation * NL); + gl_FragColor.rgb += ambientColor * diffuse.rgb; #if defined(USE_CUBEMAP) - reflectance = EnvironmentBRDF(gloss, NE, specular.rgb); + reflectance = EnvironmentBRDF(roughness, NE, specular.rgb); vec3 R = reflect(E, N); @@ -531,15 +370,15 @@ void main() // from http://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/ vec3 parallax = u_CubeMapInfo.xyz + u_CubeMapInfo.w * viewDir; - vec3 cubeLightColor = textureCubeLod(u_CubeMap, R + parallax, 7.0 - gloss * 7.0).rgb * u_EnableTextures.w; + vec3 cubeLightColor = textureCubeLod(u_CubeMap, R + parallax, 7.0 * roughness).rgb * u_EnableTextures.w; // normalize cubemap based on lowest mip (~diffuse) // multiplying cubemap values by lighting below depends on either this or the cubemap being normalized at generation //vec3 cubeLightDiffuse = max(textureCubeLod(u_CubeMap, N, 6.0).rgb, 0.5 / 255.0); //cubeLightColor /= dot(cubeLightDiffuse, vec3(0.2125, 0.7154, 0.0721)); - #if defined(r_framebufferGamma) - cubeLightColor = pow(cubeLightColor, vec3(r_framebufferGamma)); + #if defined(USE_PBR) + cubeLightColor *= cubeLightColor; #endif // multiply cubemap values by lighting @@ -549,7 +388,7 @@ void main() gl_FragColor.rgb += cubeLightColor * reflectance; #endif - #if defined(USE_PRIMARY_LIGHT) + #if defined(USE_PRIMARY_LIGHT) || defined(SHADOWMAP_MODULATE) vec3 L2, H2; float NL2, EH2, NH2; @@ -560,20 +399,19 @@ void main() //L2 /= sqrt(sqrLightDist); NL2 = clamp(dot(N, L2), 0.0, 1.0); - H2 = normalize(L2 + E); EH2 = clamp(dot(E, H2), 0.0, 1.0); NH2 = clamp(dot(N, H2), 0.0, 1.0); - reflectance = CalcDiffuse(diffuse.rgb, N, L2, E, NE, NL2, shininess); - reflectance += CalcSpecular(specular.rgb, NH2, NL2, NE, EH2, gloss, shininess); - - lightColor = u_PrimaryLightColor * var_Color.rgb; + reflectance = CalcSpecular(specular.rgb, NH2, EH2, roughness); - #if defined(r_lightGamma) - lightColor = pow(lightColor, vec3(r_lightGamma)); + // bit of a hack, with modulated shadowmaps, ignore diffuse + #if !defined(SHADOWMAP_MODULATE) + reflectance += CalcDiffuse(diffuse.rgb, NH2, EH2, roughness); #endif + lightColor = u_PrimaryLightColor; + #if defined(USE_SHADOWMAP) lightColor *= shadowValue; #endif @@ -583,28 +421,16 @@ void main() gl_FragColor.rgb += lightColor * reflectance * NL2; #endif -#else - lightColor = var_Color.rgb; - - #if defined(USE_LIGHTMAP) - lightColor *= lightmapColor.rgb; - #endif - #if defined(r_lightGamma) - lightColor = pow(lightColor, vec3(r_lightGamma)); + #if defined(USE_PBR) + gl_FragColor.rgb = sqrt(gl_FragColor.rgb); #endif - #if defined(r_materialGamma) - diffuse.rgb = pow(diffuse.rgb, vec3(r_materialGamma)); - #endif +#else gl_FragColor.rgb = diffuse.rgb * lightColor; #endif -#if defined(r_framebufferGamma) - gl_FragColor.rgb = pow(gl_FragColor.rgb, vec3(1.0 / r_framebufferGamma)); -#endif - gl_FragColor.a = diffuse.a * var_Color.a; } |