#include "lighting_util.glsl" void perLightSun(out vec3 diffuseOut, vec3 viewPos, vec3 viewNormal) { vec3 lightDir = normalize(lcalcPosition(0)); float lambert = dot(viewNormal.xyz, lightDir); #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(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; } } vec3 getSpecular(vec3 viewNormal, vec3 viewDirection, float shininess, vec3 matSpec) { vec3 lightDir = normalize(lcalcPosition(0)); float NdotL = dot(viewNormal, lightDir); if (NdotL <= 0.0) return vec3(0.0); vec3 halfVec = normalize(lightDir - viewDirection); float NdotH = dot(viewNormal, halfVec); return pow(max(NdotH, 0.0), max(1e-4, shininess)) * lcalcSpecular(0).xyz * matSpec; }