#version 450 core out vec4 frag_color; in vec2 tex_coords; uniform sampler2D albedoGbuffer; uniform sampler2D positionGbuffer; uniform sampler2D normalGbuffer; layout(std140, binding = 0) uniform SceneUniforms { mat4 PV; //camera projection * view matrix vec4 eye_w; //world-space eye position }; vec3 calculateDisneySpecular(vec3 N, vec3 V, vec3 L, vec3 albedo) { vec3 H = normalize(V + L); // Fresnel - Schlick's Approximation vec3 F0 = vec3(0.04f); vec3 F = F0 + (1.0f - F0) * pow(1.0f - dot(H, V), 5.0f); // Normal Distribution Function (GGX) float roughness = 0.7f; float alpha = roughness * roughness; float alpha2 = alpha * alpha; float NdotH = max(dot(N, H), 0.0f); float D = alpha2 / (3.14159265359 * pow(NdotH * NdotH * (alpha2 - 1.0f) + 1.0f, 2.0f)); // Geometry Function (Smith's G) float NdotV = max(dot(N, V), 0.0f); float NdotL = max(dot(N, L), 0.0f); float k = (roughness + 1.0f) * (roughness + 1.0f) / 8.0f; float G1V = NdotV / (NdotV * (1.0f - k) + k); float G1L = NdotL / (NdotL * (1.0f - k) + k); float G = G1V * G1L; vec3 specular = (D * G * F) / (4.0f * NdotL * NdotV + 0.001f); // Adding a small bias to prevent division by zero return specular; } void main() { vec4 albedo = texture(albedoGbuffer, tex_coords); // albedo = vec4(vec3(0.18f), texture(albedoGbuffer, tex_coords).a); vec4 position = texture(positionGbuffer, tex_coords); vec4 normal = texture(normalGbuffer, tex_coords); vec4 lightDirection = vec4(0.707f, 0.707f, 0.0f, 0.0f); vec3 N = normalize(normal.xyz); vec3 L = normalize(lightDirection.xyz); vec3 V = normalize(eye_w.xyz); float NdotL = max(dot(N, L), 0.0f); vec4 skyColor = vec4(0.6f, 0.7f, 0.8f, 0.0f); // Light blue sky vec4 groundColor = vec4(0.2f, 0.2f, 0.2f, 0.0f); // Dark gray ground float factor = 0.5f * (N.y + 1.0f); // Blend factor based on normal's Y component vec4 ambientLight = mix(groundColor, skyColor, factor); // Disney Diffuse Fresnel vec3 F0 = vec3(0.04f); vec3 fresnel = F0 + (1.0f - F0) * (pow(1.0f - NdotL, 5.0f)); // Disney Diffuse Term vec4 diffuse = vec4(vec3((albedo.rgb / 3.14159265359f) * NdotL * fresnel), albedo.a); // Disney Specular Term vec4 specular = vec4(calculateDisneySpecular(N, V, L, albedo.rgb), albedo.a); // Light Intensity vec4 lightColor = vec4(vec3(25.0f), 1.0f); vec4 finalDiffuse = (diffuse + specular) * lightColor + (ambientLight * 0.1f); vec4 hdr_color = finalDiffuse; vec4 tone_mapped_color = hdr_color / (hdr_color + vec4(vec3(1.0f), 0.0f)); tone_mapped_color = pow(tone_mapped_color, vec4(vec3(1.0f/2.2f), 1.0f)); frag_color = tone_mapped_color; }