<@if not DEFERRED_GLOBAL_LIGHT_SLH@> <@def DEFERRED_GLOBAL_LIGHT_SLH@> <@include model/Light.slh@> <@include DeferredLighting.slh@> <@func declareSkyboxMap()@> // declareSkyboxMap uniform samplerCube skyboxMap; vec4 evalSkyboxLight(vec3 direction, float lod) { // textureQueryLevels is not available until #430, so we require explicit lod // float mipmapLevel = lod * textureQueryLevels(skyboxMap); return textureLod(skyboxMap, direction, lod); } <@endfunc@> <@func prepareGlobalLight()@> // prepareGlobalLight // Transform directions to worldspace vec3 fragNormal = vec3(invViewMat * vec4(normal, 0.0)); // vec3 fragEyeVector = vec3(invViewMat * vec4(-position, 0.0)); vec3 fragEyeVector = vec3(invViewMat * vec4(-normalize(position), 0.0)); vec3 fragEyeDir = normalize(fragEyeVector); // Get light Light light = getLight(); vec3 fresnel = vec3(0.03); // Default Di-electric fresnel value if (metallic > 0.5) { fresnel = albedo; metallic = 1.0; } vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, metallic, fresnel, roughness); vec3 color = vec3(albedo * shading.w + shading.rgb) * min(shadowAttenuation, obscurance) * getLightColor(light) * getLightIntensity(light); color += emissive; <@endfunc@> <@func declareAmbientFresnel()@> vec3 fresnelSchlickAmbient(vec3 fresnelColor, vec3 lightDir, vec3 halfDir, float gloss) { return fresnelColor + (max(vec3(gloss), fresnelColor) - fresnelColor) * pow(1.0 - clamp(dot(lightDir, halfDir), 0.0, 1.0), 5); } <@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()@> <$declareAmbientFresnel()$> vec3 evalAmbientSphereGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, float metallic, vec3 emissive, float roughness) { <$prepareGlobalLight()$> // Diffuse from ambient color += (1 - metallic) * albedo * evalSphericalLight(getLightAmbientSphere(light), fragNormal).xyz * obscurance * getLightAmbientIntensity(light); // Specular highlight from ambient vec3 direction = -reflect(fragEyeDir, fragNormal); vec3 skyboxLight = evalSphericalLight(getLightAmbientSphere(light), direction).xyz; vec3 ambientFresnel = fresnelSchlickAmbient(fresnel, fragEyeDir, fragNormal, 1 - roughness); color += ambientFresnel * skyboxLight.rgb * obscurance * getLightAmbientIntensity(light); return color; } <@endfunc@> <@func declareEvalSkyboxGlobalColor()@> <$declareSkyboxMap()$> <$declareAmbientFresnel()$> vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, float metallic, vec3 emissive, float roughness) { <$prepareGlobalLight()$> // Diffuse from ambient color += (1 - metallic) * albedo * evalSphericalLight(getLightAmbientSphere(light), fragNormal).xyz * obscurance * getLightAmbientIntensity(light); // Specular highlight from ambient //vec3 direction = -reflect(fragEyeDir, fragNormal); // -normalize(position) vec3 direction = -reflect(-normalize(position), normal); // vec3 direction = normal; // if (gl_FragCoord.x > 1000) { float angleY = fract(asin(direction.y)/ 0.314); float angleX = fract(acos(normalize(direction.xz).x)/ 0.314); float stripeY = step(0.05,abs(angleY)); float stripeX = step(0.05,abs(angleX)); float grid = max(stripeY, stripeX); return mix( 0.5 * direction + vec3(0.5), mix(vec3(0.0, 1.0, 0.0), vec3(1.0, 0.0, 0.0), stripeY), grid); // } float levels = getLightAmbientMapNumMips(light); float lod = min(floor((roughness) * levels), levels); // vec4 skyboxLight = evalSkyboxLight(direction, lod); vec4 skyboxLight = evalSkyboxLight(direction, levels * 0.5); return skyboxLight.xyz; //vec3 ambientFresnel = fresnelSchlickAmbient(fresnel, fragEyeDir, fragNormal, 1 - roughness); //color += ambientFresnel * skyboxLight.rgb * obscurance * getLightAmbientIntensity(light); //return color; } <@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 obscurance * albedo * (diffuseLight + ambientLight); } <@endfunc@> <@endif@>