<@if not DEFERRED_GLOBAL_LIGHT_SLH@> <@def DEFERRED_GLOBAL_LIGHT_SLH@> <@include model/Light.slh@> !> <@include LightingModel.slh@> <$declareLightingModel()$> <@include LightAmbient.slh@> <@include LightDirectional.slh@> <@func prepareGlobalLight(isScattering)@> // prepareGlobalLight // Transform directions to worldspace vec3 fragNormal = vec3((normal)); vec3 fragEyeVector = vec3(invViewMat * vec4(-position, 0.0)); vec3 fragEyeDir = normalize(fragEyeVector); // Get light Light light = getLight(); vec3 color = vec3(0.0); <@if isScattering@> <@else@> color += emissive * isEmissiveEnabled(); <@endif@> vec3 fresnel = vec3(0.03); // Default Di-electric fresnel value if (metallic > 0.5) { fresnel = albedo; metallic = 1.0; } <@endfunc@> <@func declareEvalAmbientGlobalColor()@> vec3 evalAmbientGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, float metallic, vec3 emissive, float roughness) { <$prepareGlobalLight()$> color += albedo * getLightColor(light) * obscurance * getLightAmbientIntensity(light); return color; } <@endfunc@> <@func declareEvalAmbientSphereGlobalColor(supportScattering)@> <$declareLightingAmbient(1, 0, 0, supportScattering)$> <$declareLightingDirectional(supportScattering)$> vec3 evalAmbientSphereGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, float metallic, vec3 emissive, float roughness) { <$prepareGlobalLight()$> // Ambient vec3 ambientDiffuse; vec3 ambientSpecular; evalLightingAmbient(ambientDiffuse, ambientSpecular, light, fragEyeDir, fragNormal, roughness, metallic, fresnel, albedo, obscurance); color += ambientDiffuse * isDiffuseEnabled() * isAmbientEnabled(); color += ambientSpecular * isSpecularEnabled() * isAmbientEnabled(); // Directional vec3 directionalDiffuse; vec3 directionalSpecular; evalLightingDirectional(directionalDiffuse, directionalSpecular, light, fragEyeDir, fragNormal, roughness, metallic, fresnel, albedo, shadowAttenuation); color += directionalDiffuse * isDiffuseEnabled() * isDirectionalEnabled(); color += directionalSpecular * isSpecularEnabled() * isDirectionalEnabled(); return color; } <@if supportScattering@> <$declareDeferredCurvature()$> vec3 evalAmbientSphereGlobalColorScattering(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, float metallic, vec3 emissive, float roughness, float scattering, vec4 midNormalCurvature, vec4 lowNormalCurvature) { <$prepareGlobalLight(1)$> // Ambient vec3 ambientDiffuse; vec3 ambientSpecular; evalLightingAmbientScattering(ambientDiffuse, ambientSpecular, light, fragEyeDir, fragNormal, roughness, metallic, fresnel, albedo, obscurance, isScatteringEnabled() * scattering, midNormalCurvature, lowNormalCurvature); color += ambientDiffuse * isDiffuseEnabled() * isAmbientEnabled(); color += ambientSpecular * isSpecularEnabled() * isAmbientEnabled(); // Directional vec3 directionalDiffuse; vec3 directionalSpecular; evalLightingDirectionalScattering(directionalDiffuse, directionalSpecular, light, fragEyeDir, fragNormal, roughness, metallic, fresnel, albedo, shadowAttenuation, isScatteringEnabled() * scattering, midNormalCurvature, lowNormalCurvature); color += directionalDiffuse * isDiffuseEnabled() * isDirectionalEnabled(); color += directionalSpecular * isSpecularEnabled() * isDirectionalEnabled(); return color; } <@endif@> <@endfunc@> <@func declareEvalSkyboxGlobalColor(supportScattering)@> <$declareLightingAmbient(0, 1, 0, supportScattering)$> <$declareLightingDirectional(supportScattering)$> vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, float metallic, vec3 emissive, float roughness) { <$prepareGlobalLight()$> // Ambient vec3 ambientDiffuse; vec3 ambientSpecular; evalLightingAmbient(ambientDiffuse, ambientSpecular, light, fragEyeDir, fragNormal, roughness, metallic, fresnel, albedo, obscurance); color += ambientDiffuse * isDiffuseEnabled() * isAmbientEnabled(); color += ambientSpecular * isSpecularEnabled() * isAmbientEnabled(); // Directional vec3 directionalDiffuse; vec3 directionalSpecular; evalLightingDirectional(directionalDiffuse, directionalSpecular, light, fragEyeDir, fragNormal, roughness, metallic, fresnel, albedo, shadowAttenuation); color += directionalDiffuse * isDiffuseEnabled() * isDirectionalEnabled(); color += directionalSpecular * isSpecularEnabled() * isDirectionalEnabled(); return color; } <@if supportScattering@> <$declareDeferredCurvature()$> vec3 evalSkyboxGlobalColorScattering(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, float metallic, vec3 emissive, float roughness, float scattering, vec4 blurredCurvature, vec4 diffusedCurvature) { <$prepareGlobalLight(1)$> // Ambient vec3 ambientDiffuse; vec3 ambientSpecular; evalLightingAmbientScattering(ambientDiffuse, ambientSpecular, light, fragEyeDir, fragNormal, roughness, metallic, fresnel, albedo, obscurance, isScatteringEnabled() * scattering, lowNormal, highCurvature, lowCurvature); color += ambientDiffuse * isDiffuseEnabled() * isAmbientEnabled(); color += ambientSpecular * isSpecularEnabled() * isAmbientEnabled(); // Directional vec3 directionalDiffuse; vec3 directionalSpecular; evalLightingDirectionalScattering(directionalDiffuse, directionalSpecular, light, fragEyeDir, fragNormal, roughness, metallic, fresnel, albedo, shadowAttenuation, isScatteringEnabled() * scattering, , midNormalCurvature, lowNormalCurvature); color += directionalDiffuse * isDiffuseEnabled() * isDirectionalEnabled(); color += directionalSpecular * isSpecularEnabled() * isDirectionalEnabled(); return vec3(color); } <@endif@> <@endfunc@> <@func declareEvalLightmappedColor()@> vec3 evalLightmappedColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 normal, vec3 albedo, vec3 lightmap) { Light light = getLight(); // Catch normals perpendicular to the projection plane, hence the magic number for the threshold // It should be just 0, but we have inaccuracy so we overshoot const float PERPENDICULAR_THRESHOLD = -0.005; vec3 fragNormal = vec3(invViewMat * vec4(normal, 0.0)); // transform to worldspace float diffuseDot = dot(fragNormal, -getLightDirection(light)); float facingLight = step(PERPENDICULAR_THRESHOLD, diffuseDot); // Reevaluate the shadow attenuation for light facing fragments float lightAttenuation = (1 - facingLight) + facingLight * shadowAttenuation; // Diffuse light is the lightmap dimmed by shadow vec3 diffuseLight = lightAttenuation * lightmap; // Ambient light is the lightmap when in shadow vec3 ambientLight = (1 - lightAttenuation) * lightmap * getLightAmbientIntensity(light); return isLightmapEnabled() * obscurance * albedo * (diffuseLight + ambientLight); } <@endfunc@> <@func declareEvalGlobalLightingAlphaBlended()@> <$declareLightingAmbient(1, 1, 1)$> <$declareLightingDirectional()$> vec3 evalGlobalLightingAlphaBlended(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, float metallic, vec3 emissive, float roughness, float opacity) { <$prepareGlobalLight()$> // Ambient vec3 ambientDiffuse; vec3 ambientSpecular; evalLightingAmbient(ambientDiffuse, ambientSpecular, light, fragEyeDir, fragNormal, roughness, metallic, fresnel, albedo, obscurance); color += ambientDiffuse * isDiffuseEnabled() * isAmbientEnabled(); color += ambientSpecular * isSpecularEnabled() * isAmbientEnabled() / opacity; // Directional vec3 directionalDiffuse; vec3 directionalSpecular; evalLightingDirectional(directionalDiffuse, directionalSpecular, light, fragEyeDir, fragNormal, roughness, metallic, fresnel, albedo, shadowAttenuation); color += directionalDiffuse * isDiffuseEnabled() * isDirectionalEnabled(); color += directionalSpecular * isSpecularEnabled() * isDirectionalEnabled() / opacity; return color; } <@endfunc@> <@endif@>