diff --git a/files/shaders/compatibility/bs/default.frag b/files/shaders/compatibility/bs/default.frag index 7e2be9aa8f..70d9ef7ba7 100644 --- a/files/shaders/compatibility/bs/default.frag +++ b/files/shaders/compatibility/bs/default.frag @@ -61,34 +61,30 @@ void main() gl_FragData[0].a *= diffuseColor.a; gl_FragData[0].a = alphaTest(gl_FragData[0].a, alphaRef); + vec3 specularColor = getSpecularColor().xyz; #if @normalMap vec4 normalTex = texture2D(normalMap, normalMapUV); vec3 viewNormal = normalToView(normalTex.xyz * 2.0 - 1.0); + specularColor *= normalTex.a; #else vec3 viewNormal = normalToView(normalize(passNormal)); #endif float shadowing = unshadowedLightRatio(linearDepth); - vec3 diffuseLight, ambientLight; - doLighting(passViewPos, viewNormal, shadowing, diffuseLight, ambientLight); + vec3 diffuseLight, ambientLight, specularLight; + doLighting(passViewPos, viewNormal, gl_FrontMaterial.shininess, shadowing, diffuseLight, ambientLight, specularLight); + vec3 diffuse = diffuseColor.xyz * diffuseLight; + vec3 ambient = getAmbientColor().xyz * ambientLight; vec3 emission = getEmissionColor().xyz * emissiveMult; #if @emissiveMap emission *= texture2D(emissiveMap, emissiveMapUV).xyz; #endif - vec3 lighting = diffuseColor.xyz * diffuseLight + getAmbientColor().xyz * ambientLight + emission; + vec3 lighting = diffuse + ambient + emission; + vec3 specular = specularColor * specularLight * specStrength; clampLightingResult(lighting); - gl_FragData[0].xyz *= lighting; - - float shininess = gl_FrontMaterial.shininess; - vec3 matSpec = getSpecularColor().xyz * specStrength; -#if @normalMap - matSpec *= normalTex.a; -#endif - - if (matSpec != vec3(0.0)) - gl_FragData[0].xyz += matSpec * getSpecular(viewNormal, passViewPos, shininess, shadowing); + gl_FragData[0].xyz = gl_FragData[0].xyz * lighting + specular; gl_FragData[0] = applyFogAtDist(gl_FragData[0], euclideanDepth, linearDepth, far); diff --git a/files/shaders/compatibility/groundcover.frag b/files/shaders/compatibility/groundcover.frag index f87beaf447..dfdd6518c3 100644 --- a/files/shaders/compatibility/groundcover.frag +++ b/files/shaders/compatibility/groundcover.frag @@ -70,8 +70,8 @@ void main() #if !PER_PIXEL_LIGHTING lighting = passLighting + shadowDiffuseLighting * shadowing; #else - vec3 diffuseLight, ambientLight; - doLighting(passViewPos, viewNormal, shadowing, diffuseLight, ambientLight); + vec3 diffuseLight, ambientLight, specularLight; + doLighting(passViewPos, viewNormal, gl_FrontMaterial.shininess, shadowing, diffuseLight, ambientLight, specularLight); lighting = diffuseLight + ambientLight; #endif diff --git a/files/shaders/compatibility/groundcover.vert b/files/shaders/compatibility/groundcover.vert index c1bb35da05..95a17b5084 100644 --- a/files/shaders/compatibility/groundcover.vert +++ b/files/shaders/compatibility/groundcover.vert @@ -170,8 +170,9 @@ void main(void) #if PER_PIXEL_LIGHTING passViewPos = viewPos.xyz; #else - vec3 diffuseLight, ambientLight; - doLighting(viewPos.xyz, viewNormal, diffuseLight, ambientLight, shadowDiffuseLighting); + vec3 diffuseLight, ambientLight, specularLight; + vec3 unusedShadowSpecular; + doLighting(viewPos.xyz, viewNormal, gl_FrontMaterial.shininess, diffuseLight, ambientLight, specularLight, shadowDiffuseLighting, unusedShadowSpecular); passLighting = diffuseLight + ambientLight; clampLightingResult(passLighting); #endif diff --git a/files/shaders/compatibility/objects.frag b/files/shaders/compatibility/objects.frag index dd9c3e5f3b..80de6b0e9d 100644 --- a/files/shaders/compatibility/objects.frag +++ b/files/shaders/compatibility/objects.frag @@ -67,15 +67,17 @@ uniform float near; uniform float far; uniform float alphaRef; -#define PER_PIXEL_LIGHTING (@normalMap || @forcePPL) +#define PER_PIXEL_LIGHTING (@normalMap || @specularMap || @forcePPL) #if !PER_PIXEL_LIGHTING centroid varying vec3 passLighting; +centroid varying vec3 passSpecular; centroid varying vec3 shadowDiffuseLighting; +centroid varying vec3 shadowSpecularLighting; #else uniform float emissiveMult; -#endif uniform float specStrength; +#endif varying vec3 passViewPos; varying vec3 passNormal; #if @normalMap || @diffuseParallax @@ -200,19 +202,27 @@ void main() #endif float shadowing = unshadowedLightRatio(-passViewPos.z); - vec3 lighting; + vec3 lighting, specular; #if !PER_PIXEL_LIGHTING lighting = passLighting + shadowDiffuseLighting * shadowing; + specular = passSpecular + shadowSpecularLighting * shadowing; #else - vec3 diffuseLight, ambientLight; - doLighting(passViewPos, viewNormal, shadowing, diffuseLight, ambientLight); - vec3 emission = getEmissionColor().xyz * emissiveMult; - lighting = diffuseColor.xyz * diffuseLight + getAmbientColor().xyz * ambientLight + emission; +#if @specularMap + vec4 specTex = texture2D(specularMap, specularMapUV); + float shininess = specTex.a * 255.0; + vec3 specularColor = specTex.xyz; +#else + float shininess = gl_FrontMaterial.shininess; + vec3 specularColor = getSpecularColor().xyz; +#endif + vec3 diffuseLight, ambientLight, specularLight; + doLighting(passViewPos, viewNormal, shininess, shadowing, diffuseLight, ambientLight, specularLight); + lighting = diffuseColor.xyz * diffuseLight + getAmbientColor().xyz * ambientLight + getEmissionColor().xyz * emissiveMult; + specular = specularColor * specularLight * specStrength; #endif clampLightingResult(lighting); - - gl_FragData[0].xyz *= lighting; + gl_FragData[0].xyz = gl_FragData[0].xyz * lighting + specular; #if @envMap && !@preLightEnv gl_FragData[0].xyz += envEffect; @@ -222,21 +232,6 @@ void main() gl_FragData[0].xyz += texture2D(emissiveMap, emissiveMapUV).xyz; #endif -#if @specularMap - vec4 specTex = texture2D(specularMap, specularMapUV); - float shininess = specTex.a * 255.0; - vec3 matSpec = specTex.xyz; -#else - float shininess = gl_FrontMaterial.shininess; - vec3 matSpec = getSpecularColor().xyz; -#endif - - matSpec *= specStrength; - if (matSpec != vec3(0.0)) - { - gl_FragData[0].xyz += matSpec * getSpecular(viewNormal, passViewPos, shininess, shadowing); - } - gl_FragData[0] = applyFogAtPos(gl_FragData[0], passViewPos, far); vec2 screenCoords = gl_FragCoord.xy / screenRes; diff --git a/files/shaders/compatibility/objects.vert b/files/shaders/compatibility/objects.vert index 1ec0917ea8..2bebcd60bf 100644 --- a/files/shaders/compatibility/objects.vert +++ b/files/shaders/compatibility/objects.vert @@ -49,12 +49,15 @@ varying vec2 specularMapUV; varying vec2 glossMapUV; #endif -#define PER_PIXEL_LIGHTING (@normalMap || @forcePPL) +#define PER_PIXEL_LIGHTING (@normalMap || @specularMap || @forcePPL) #if !PER_PIXEL_LIGHTING centroid varying vec3 passLighting; +centroid varying vec3 passSpecular; centroid varying vec3 shadowDiffuseLighting; +centroid varying vec3 shadowSpecularLighting; uniform float emissiveMult; +uniform float specStrength; #endif varying vec3 passViewPos; varying vec3 passNormal; @@ -145,12 +148,13 @@ void main(void) #endif #if !PER_PIXEL_LIGHTING - vec3 diffuseLight, ambientLight; - doLighting(viewPos.xyz, viewNormal, diffuseLight, ambientLight, shadowDiffuseLighting); - vec3 emission = getEmissionColor().xyz * emissiveMult; - passLighting = getDiffuseColor().xyz * diffuseLight + getAmbientColor().xyz * ambientLight + emission; + vec3 diffuseLight, ambientLight, specularLight; + doLighting(viewPos.xyz, viewNormal, gl_FrontMaterial.shininess, diffuseLight, ambientLight, specularLight, shadowDiffuseLighting, shadowSpecularLighting); + passLighting = getDiffuseColor().xyz * diffuseLight + getAmbientColor().xyz * ambientLight + getEmissionColor().xyz * emissiveMult; + passSpecular = getSpecularColor().xyz * specularLight * specStrength; clampLightingResult(passLighting); shadowDiffuseLighting *= getDiffuseColor().xyz; + shadowSpecularLighting *= getSpecularColor().xyz * specStrength; #endif #if (@shadows_enabled) diff --git a/files/shaders/compatibility/terrain.frag b/files/shaders/compatibility/terrain.frag index 734a358590..38b985223e 100644 --- a/files/shaders/compatibility/terrain.frag +++ b/files/shaders/compatibility/terrain.frag @@ -23,11 +23,13 @@ uniform sampler2D blendMap; varying float euclideanDepth; varying float linearDepth; -#define PER_PIXEL_LIGHTING (@normalMap || @forcePPL) +#define PER_PIXEL_LIGHTING (@normalMap || @specularMap || @forcePPL) #if !PER_PIXEL_LIGHTING centroid varying vec3 passLighting; +centroid varying vec3 passSpecular; centroid varying vec3 shadowDiffuseLighting; +centroid varying vec3 shadowSpecularLighting; #endif varying vec3 passViewPos; varying vec3 passNormal; @@ -67,31 +69,26 @@ void main() #endif float shadowing = unshadowedLightRatio(linearDepth); - vec3 lighting; + vec3 lighting, specular; #if !PER_PIXEL_LIGHTING lighting = passLighting + shadowDiffuseLighting * shadowing; + specular = passSpecular + shadowSpecularLighting * shadowing; #else - vec3 diffuseLight, ambientLight; - doLighting(passViewPos, viewNormal, shadowing, diffuseLight, ambientLight); +#if @specularMap + float shininess = 128.0; // TODO: make configurable + vec3 specularColor = vec3(diffuseTex.a); +#else + float shininess = gl_FrontMaterial.shininess; + vec3 specularColor = getSpecularColor().xyz; +#endif + vec3 diffuseLight, ambientLight, specularLight; + doLighting(passViewPos, viewNormal, shininess, shadowing, diffuseLight, ambientLight, specularLight); lighting = diffuseColor.xyz * diffuseLight + getAmbientColor().xyz * ambientLight + getEmissionColor().xyz; + specular = specularColor * specularLight; #endif clampLightingResult(lighting); - - gl_FragData[0].xyz *= lighting; - -#if @specularMap - float shininess = 128.0; // TODO: make configurable - vec3 matSpec = vec3(diffuseTex.a); -#else - float shininess = gl_FrontMaterial.shininess; - vec3 matSpec = getSpecularColor().xyz; -#endif - - if (matSpec != vec3(0.0)) - { - gl_FragData[0].xyz += matSpec * getSpecular(viewNormal, passViewPos, shininess, shadowing); - } + gl_FragData[0].xyz = gl_FragData[0].xyz * lighting + specular; gl_FragData[0] = applyFogAtDist(gl_FragData[0], euclideanDepth, linearDepth, far); diff --git a/files/shaders/compatibility/terrain.vert b/files/shaders/compatibility/terrain.vert index f74bc1a95f..3b2cb16db4 100644 --- a/files/shaders/compatibility/terrain.vert +++ b/files/shaders/compatibility/terrain.vert @@ -13,11 +13,13 @@ varying vec2 uv; varying float euclideanDepth; varying float linearDepth; -#define PER_PIXEL_LIGHTING (@normalMap || @forcePPL) +#define PER_PIXEL_LIGHTING (@normalMap || @specularMap || @forcePPL) #if !PER_PIXEL_LIGHTING centroid varying vec3 passLighting; +centroid varying vec3 passSpecular; centroid varying vec3 shadowDiffuseLighting; +centroid varying vec3 shadowSpecularLighting; #endif varying vec3 passViewPos; varying vec3 passNormal; @@ -54,11 +56,13 @@ void main(void) #endif #if !PER_PIXEL_LIGHTING - vec3 diffuseLight, ambientLight; - doLighting(viewPos.xyz, viewNormal, diffuseLight, ambientLight, shadowDiffuseLighting); + vec3 diffuseLight, ambientLight, specularLight; + doLighting(viewPos.xyz, viewNormal, gl_FrontMaterial.shininess, diffuseLight, ambientLight, specularLight, shadowDiffuseLighting, shadowSpecularLighting); passLighting = getDiffuseColor().xyz * diffuseLight + getAmbientColor().xyz * ambientLight + getEmissionColor().xyz; + passSpecular = getSpecularColor().xyz * specularLight; clampLightingResult(passLighting); shadowDiffuseLighting *= getDiffuseColor().xyz; + shadowSpecularLighting *= getSpecularColor().xyz; #endif uv = gl_MultiTexCoord0.xy; diff --git a/files/shaders/lib/light/lighting.glsl b/files/shaders/lib/light/lighting.glsl index 8351fce8a0..8bb6ba148f 100644 --- a/files/shaders/lib/light/lighting.glsl +++ b/files/shaders/lib/light/lighting.glsl @@ -3,15 +3,13 @@ #include "lighting_util.glsl" -void perLightSun(out vec3 diffuseOut, vec3 viewPos, vec3 viewNormal) +float calcLambert(vec3 viewNormal, vec3 lightDir, vec3 viewDir) { - vec3 lightDir = normalize(lcalcPosition(0)); - float lambert = dot(viewNormal.xyz, lightDir); - + float lambert = dot(viewNormal, lightDir); #ifndef GROUNDCOVER lambert = max(lambert, 0.0); #else - float eyeCosine = dot(normalize(viewPos), viewNormal.xyz); + float eyeCosine = dot(viewNormal, viewDir); if (lambert < 0.0) { lambert = -lambert; @@ -19,75 +17,7 @@ void perLightSun(out vec3 diffuseOut, vec3 viewPos, vec3 viewNormal) } lambert *= clamp(-8.0 * (1.0 - 0.3) * eyeCosine + 1.0, 0.3, 1.0); #endif - - diffuseOut = lcalcDiffuse(0).xyz * lambert; -} - -void perLightPoint(out vec3 ambientOut, out vec3 diffuseOut, int lightIndex, vec3 viewPos, vec3 viewNormal) -{ - vec3 lightPos = lcalcPosition(lightIndex) - viewPos; - float lightDistance = length(lightPos); - -// cull non-FFP point lighting by radius, light is guaranteed to not fall outside this bound with our cutoff -#if !@lightingMethodFFP - float radius = lcalcRadius(lightIndex); - - if (lightDistance > radius * 2.0) - { - ambientOut = vec3(0.0); - diffuseOut = vec3(0.0); - return; - } -#endif - - lightPos = normalize(lightPos); - - float illumination = lcalcIllumination(lightIndex, lightDistance); - ambientOut = lcalcAmbient(lightIndex) * illumination; - float lambert = dot(viewNormal.xyz, lightPos) * illumination; - -#ifndef GROUNDCOVER - lambert = max(lambert, 0.0); -#else - float eyeCosine = dot(normalize(viewPos), viewNormal.xyz); - if (lambert < 0.0) - { - lambert = -lambert; - eyeCosine = -eyeCosine; - } - lambert *= clamp(-8.0 * (1.0 - 0.3) * eyeCosine + 1.0, 0.3, 1.0); -#endif - - diffuseOut = lcalcDiffuse(lightIndex) * lambert; -} - -#if PER_PIXEL_LIGHTING -void doLighting(vec3 viewPos, vec3 viewNormal, float shadowing, out vec3 diffuseLight, out vec3 ambientLight) -#else -void doLighting(vec3 viewPos, vec3 viewNormal, out vec3 diffuseLight, out vec3 ambientLight, out vec3 shadowDiffuse) -#endif -{ - vec3 ambientOut, diffuseOut; - - perLightSun(diffuseOut, viewPos, viewNormal); - ambientLight = gl_LightModel.ambient.xyz; -#if PER_PIXEL_LIGHTING - diffuseLight = diffuseOut * shadowing; -#else - shadowDiffuse = diffuseOut; - diffuseLight = vec3(0.0); -#endif - - for (int i = @startLight; i < @endLight; ++i) - { -#if @lightingMethodUBO - perLightPoint(ambientOut, diffuseOut, PointLightIndex[i], viewPos, viewNormal); -#else - perLightPoint(ambientOut, diffuseOut, i, viewPos, viewNormal); -#endif - ambientLight += ambientOut; - diffuseLight += diffuseOut; - } + return lambert; } float calcSpecIntensity(vec3 viewNormal, vec3 viewDir, float shininess, vec3 lightDir) @@ -102,12 +32,28 @@ float calcSpecIntensity(vec3 viewNormal, vec3 viewDir, float shininess, vec3 lig return 0.0; } -vec3 getSpecular(vec3 viewNormal, vec3 viewPos, float shininess, float shadowing) +#if PER_PIXEL_LIGHTING +void doLighting(vec3 viewPos, vec3 viewNormal, float shininess, float shadowing, out vec3 diffuseLight, out vec3 ambientLight, out vec3 specularLight) +#else +void doLighting(vec3 viewPos, vec3 viewNormal, float shininess, out vec3 diffuseLight, out vec3 ambientLight, out vec3 specularLight, out vec3 shadowDiffuse, out vec3 shadowSpecular) +#endif { - shininess = max(shininess, 1e-4); vec3 viewDir = normalize(viewPos); - vec3 specularLight = lcalcSpecular(0).xyz * calcSpecIntensity(viewNormal, viewDir, shininess, normalize(lcalcPosition(0))); + shininess = max(shininess, 1e-4); + + vec3 sunDir = normalize(lcalcPosition(0)); + diffuseLight = lcalcDiffuse(0) * calcLambert(viewNormal, sunDir, viewDir); + ambientLight = gl_LightModel.ambient.xyz; + specularLight = lcalcSpecular(0).xyz * calcSpecIntensity(viewNormal, viewDir, shininess, sunDir); +#if PER_PIXEL_LIGHTING + diffuseLight *= shadowing; specularLight *= shadowing; +#else + shadowDiffuse = diffuseLight; + shadowSpecular = specularLight; + diffuseLight = vec3(0.0); + specularLight = vec3(0.0); +#endif for (int i = @startLight; i < @endLight; ++i) { @@ -116,21 +62,22 @@ vec3 getSpecular(vec3 viewNormal, vec3 viewPos, float shininess, float shadowing #else int lightIndex = i; #endif - vec3 lightPos = lcalcPosition(lightIndex) - viewPos; float lightDistance = length(lightPos); + // cull non-FFP point lighting by radius, light is guaranteed to not fall outside this bound with our cutoff #if !@lightingMethodFFP if (lightDistance > lcalcRadius(lightIndex) * 2.0) continue; #endif - float illumination = lcalcIllumination(lightIndex, lightDistance); - float intensity = calcSpecIntensity(viewNormal, viewDir, shininess, normalize(lightPos)); - specularLight += lcalcSpecular(lightIndex).xyz * intensity * illumination; - } + vec3 lightDir = lightPos / lightDistance; - return specularLight; + float illumination = lcalcIllumination(lightIndex, lightDistance); + diffuseLight += lcalcDiffuse(lightIndex) * calcLambert(viewNormal, lightDir, viewDir) * illumination; + ambientLight += lcalcAmbient(lightIndex) * illumination; + specularLight += lcalcSpecular(lightIndex).xyz * calcSpecIntensity(viewNormal, viewDir, shininess, lightDir) * illumination; + } } #endif