<@if not DEFERRED_GLOBAL_LIGHT_SLH@> <@def DEFERRED_GLOBAL_LIGHT_SLH@> <@include graphics/Light.slh@> <@include LightingModel.slh@> <$declareLightBuffer()$> <$declareLightAmbientBuffer()$> <@include LightAmbient.slh@> <@include LightDirectional.slh@> <@func fetchGlobalLight()@> // Get light Light light = getKeyLight(); LightAmbient lightAmbient = getLightAmbient(); vec3 lightDirection = getLightDirection(light); vec3 lightIrradiance = getLightIrradiance(light); vec3 color = vec3(0.0); <@endfunc@> <@func prepareGlobalLight(positionES, normalWS)@> // prepareGlobalLight // Transform directions to worldspace vec3 fragNormalWS = vec3(<$normalWS$>); vec3 fragPositionWS = vec3(invViewMat * vec4(<$positionES$>, 1.0)); vec3 fragEyeVectorWS = invViewMat[3].xyz - fragPositionWS; vec3 fragEyeDirWS = normalize(fragEyeVectorWS); <$fetchGlobalLight()$> <@endfunc@> <@func declareEvalAmbientGlobalColor()@> vec3 evalAmbientGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, vec3 fresnel, float metallic, float roughness) { <$prepareGlobalLight(position, normal)$> color += albedo * getLightColor(light) * obscurance * getLightAmbientIntensity(lightAmbient); return color; } <@endfunc@> <@func declareEvalAmbientSphereGlobalColor(supportScattering)@> <$declareLightingAmbient(1, _SCRIBE_NULL, _SCRIBE_NULL, $supportScattering$)$> <$declareLightingDirectional($supportScattering$)$> <@if supportScattering@> <$declareDeferredCurvature()$> <@endif@> vec3 evalAmbientSphereGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, vec3 fresnel, float metallic, float roughness <@if supportScattering@> , float scattering, vec4 midNormalCurvature, vec4 lowNormalCurvature <@endif@> ) { <$prepareGlobalLight(position, normal)$> SurfaceData surfaceWS = initSurfaceData(roughness, fragNormalWS, fragEyeDirWS); // Ambient vec3 ambientDiffuse; vec3 ambientSpecular; evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surfaceWS, metallic, fresnel, albedo, obscurance <@if supportScattering@> ,scattering, midNormalCurvature, lowNormalCurvature <@endif@> ); color += ambientDiffuse; color += ambientSpecular; // Directional vec3 directionalDiffuse; vec3 directionalSpecular; evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surfaceWS, metallic, fresnel, albedo, shadowAttenuation <@if supportScattering@> ,scattering, midNormalCurvature, lowNormalCurvature <@endif@> ); color += directionalDiffuse; color += directionalSpecular; return color; } <@endfunc@> <@include Haze.slh@> <@func declareEvalSkyboxGlobalColor(supportScattering)@> <$declareLightingAmbient(_SCRIBE_NULL, 1, _SCRIBE_NULL, $supportScattering$)$> <$declareLightingDirectional($supportScattering$)$> <@if supportScattering@> <$declareDeferredCurvature()$> <@endif@> vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, vec3 fresnel, float metallic, float roughness <@if supportScattering@> , float scattering, vec4 midNormalCurvature, vec4 lowNormalCurvature <@endif@> ) { <$prepareGlobalLight(position, normal)$> SurfaceData surfaceWS = initSurfaceData(roughness, fragNormalWS, fragEyeDirWS); // Ambient vec3 ambientDiffuse; vec3 ambientSpecular; evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surfaceWS, metallic, fresnel, albedo, obscurance <@if supportScattering@> ,scattering, midNormalCurvature, lowNormalCurvature <@endif@> ); color += ambientDiffuse; color += ambientSpecular; vec3 directionalDiffuse; vec3 directionalSpecular; evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surfaceWS, metallic, fresnel, albedo, shadowAttenuation <@if supportScattering@> ,scattering, midNormalCurvature, lowNormalCurvature <@endif@> ); color += directionalDiffuse; color += directionalSpecular; // Attenuate the light if haze effect selected if ((isHazeEnabled() > 0.0) && (hazeParams.hazeMode & HAZE_MODE_IS_KEYLIGHT_ATTENUATED) == HAZE_MODE_IS_KEYLIGHT_ATTENUATED) { color = computeHazeColorKeyLightAttenuation(color, lightDirection, fragPositionWS); } return color; } <@endfunc@> <@func declareEvalLightmappedColor()@> vec3 evalLightmappedColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 normal, vec3 albedo, vec3 lightmap) { Light light = getKeyLight(); LightAmbient ambient = getLightAmbient(); // 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.0 - 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.0 - lightAttenuation) * lightmap * getLightAmbientIntensity(ambient); 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, vec3 fresnel, float metallic, vec3 emissive, float roughness, float opacity, vec3 prevLighting) { <$prepareGlobalLight(position, normal)$> SurfaceData surfaceWS = initSurfaceData(roughness, fragNormalWS, fragEyeDirWS); color = prevLighting; color += emissive * isEmissiveEnabled(); // Ambient vec3 ambientDiffuse; vec3 ambientSpecular; evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surfaceWS, metallic, fresnel, albedo, obscurance); color += ambientDiffuse; // Directional vec3 directionalDiffuse; vec3 directionalSpecular; evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surfaceWS, metallic, fresnel, albedo, shadowAttenuation); color += directionalDiffuse; color += evalSpecularWithOpacity(ambientSpecular + directionalSpecular, opacity); return color; } <@endfunc@> <@func declareEvalGlobalLightingAlphaBlendedWithHaze()@> <$declareLightingAmbient(1, 1, 1)$> <$declareLightingDirectional()$> vec3 evalGlobalLightingAlphaBlendedWithHaze( mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 positionES, vec3 normalWS, vec3 albedo, vec3 fresnel, float metallic, vec3 emissive, float roughness, float opacity) { <$prepareGlobalLight(positionES, normalWS)$> SurfaceData surfaceWS = initSurfaceData(roughness, fragNormalWS, fragEyeDirWS); color += emissive * isEmissiveEnabled(); // Ambient vec3 ambientDiffuse; vec3 ambientSpecular; evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surfaceWS, metallic, fresnel, albedo, obscurance); color += ambientDiffuse; // Directional vec3 directionalDiffuse; vec3 directionalSpecular; evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surfaceWS, metallic, fresnel, albedo, shadowAttenuation); color += directionalDiffuse; color += evalSpecularWithOpacity(ambientSpecular + directionalSpecular, opacity); // Haze if ((isHazeEnabled() > 0.0) && (hazeParams.hazeMode & HAZE_MODE_IS_ACTIVE) == HAZE_MODE_IS_ACTIVE) { vec4 hazeColor = computeHazeColor( positionES, // fragment position in eye coordinates fragPositionWS, // fragment position in world coordinates invViewMat[3].xyz, // eye position in world coordinates lightDirection // keylight direction vector in world coordinates ); color = mix(color.rgb, hazeColor.rgb, hazeColor.a); } return color; } vec3 evalGlobalLightingAlphaBlendedWithHaze( mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 positionES, vec3 positionWS, vec3 albedo, vec3 fresnel, float metallic, vec3 emissive, SurfaceData surface, float opacity, vec3 prevLighting) { <$fetchGlobalLight()$> color = prevLighting; color += emissive * isEmissiveEnabled(); // Ambient vec3 ambientDiffuse; vec3 ambientSpecular; evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surface, metallic, fresnel, albedo, obscurance); // Directional vec3 directionalDiffuse; vec3 directionalSpecular; evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surface, metallic, fresnel, albedo, shadowAttenuation); color += ambientDiffuse + directionalDiffuse; color += evalSpecularWithOpacity(ambientSpecular + directionalSpecular, opacity); // Haze if ((isHazeEnabled() > 0.0) && (hazeParams.hazeMode & HAZE_MODE_IS_ACTIVE) == HAZE_MODE_IS_ACTIVE) { vec4 hazeColor = computeHazeColor( positionES, // fragment position in eye coordinates positionWS, // fragment position in world coordinates invViewMat[3].xyz, // eye position in world coordinates lightDirection // keylight direction vector ); color = mix(color.rgb, hazeColor.rgb, hazeColor.a); } return color; } <@endfunc@> <@endif@>