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); - lighting = diffuseColor.xyz * diffuseLight + getAmbientColor().xyz * ambientLight + getEmissionColor().xyz; -#endif - - clampLightingResult(lighting); - - gl_FragData[0].xyz *= lighting; - #if @specularMap float shininess = 128.0; // TODO: make configurable - vec3 matSpec = vec3(diffuseTex.a); + vec3 specularColor = vec3(diffuseTex.a); #else float shininess = gl_FrontMaterial.shininess; - vec3 matSpec = getSpecularColor().xyz; + 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 - if (matSpec != vec3(0.0)) - { - gl_FragData[0].xyz += matSpec * getSpecular(viewNormal, passViewPos, shininess, shadowing); - } + clampLightingResult(lighting); + 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 689aee0911..8bb6ba148f 100644 --- a/files/shaders/lib/light/lighting.glsl +++ b/files/shaders/lib/light/lighting.glsl @@ -20,21 +20,39 @@ float calcLambert(vec3 viewNormal, vec3 lightDir, vec3 viewDir) return lambert; } +float calcSpecIntensity(vec3 viewNormal, vec3 viewDir, float shininess, vec3 lightDir) +{ + if (dot(viewNormal, lightDir) > 0.0) + { + vec3 halfVec = normalize(lightDir - viewDir); + float NdotH = max(dot(viewNormal, halfVec), 0.0); + return pow(NdotH, shininess); + } + + return 0.0; +} + #if PER_PIXEL_LIGHTING -void doLighting(vec3 viewPos, vec3 viewNormal, float shadowing, out vec3 diffuseLight, out vec3 ambientLight) +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, out vec3 diffuseLight, out vec3 ambientLight, out vec3 shadowDiffuse) +void doLighting(vec3 viewPos, vec3 viewNormal, float shininess, out vec3 diffuseLight, out vec3 ambientLight, out vec3 specularLight, out vec3 shadowDiffuse, out vec3 shadowSpecular) #endif { vec3 viewDir = normalize(viewPos); + shininess = max(shininess, 1e-4); - diffuseLight = lcalcDiffuse(0).xyz * calcLambert(viewNormal, normalize(lcalcPosition(0)), viewDir); + 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) @@ -56,52 +74,10 @@ void doLighting(vec3 viewPos, vec3 viewNormal, out vec3 diffuseLight, out vec3 a vec3 lightDir = lightPos / lightDistance; float illumination = lcalcIllumination(lightIndex, lightDistance); - ambientLight += lcalcAmbient(lightIndex) * illumination; diffuseLight += lcalcDiffuse(lightIndex) * calcLambert(viewNormal, lightDir, viewDir) * illumination; + ambientLight += lcalcAmbient(lightIndex) * illumination; + specularLight += lcalcSpecular(lightIndex).xyz * calcSpecIntensity(viewNormal, viewDir, shininess, lightDir) * illumination; } } -float calcSpecIntensity(vec3 viewNormal, vec3 viewDir, float shininess, vec3 lightDir) -{ - if (dot(viewNormal, lightDir) > 0.0) - { - vec3 halfVec = normalize(lightDir - viewDir); - float NdotH = max(dot(viewNormal, halfVec), 0.0); - return pow(NdotH, shininess); - } - - return 0.0; -} - -vec3 getSpecular(vec3 viewNormal, vec3 viewPos, float shininess, float shadowing) -{ - shininess = max(shininess, 1e-4); - vec3 viewDir = normalize(viewPos); - vec3 specularLight = lcalcSpecular(0).xyz * calcSpecIntensity(viewNormal, viewDir, shininess, normalize(lcalcPosition(0))); - specularLight *= shadowing; - - for (int i = @startLight; i < @endLight; ++i) - { -#if @lightingMethodUBO - int lightIndex = PointLightIndex[i]; -#else - int lightIndex = i; -#endif - - vec3 lightPos = lcalcPosition(lightIndex) - viewPos; - float lightDistance = length(lightPos); - -#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; - } - - return specularLight; -} - #endif