#include "lighting.glsl" layout(location = 0) out vec4 outColor; layout(location = 0) in vec2 uv; layout(std140, binding = 0) uniform UniformSceneData { mat4 projection, view, model; vec4 cameraPosition, lightPosition; vec3 color; float radius; vec2 viewport; } sceneData; layout(binding = 1) uniform sampler2D positionSampler; layout(binding = 2) uniform sampler2D normalSampler; layout(binding = 3) uniform sampler2D albedoSampler; layout(binding = 4) uniform sampler2D materialSampler; vec2 CalcTexCoord() { return gl_FragCoord.xy / vec2(sceneData.viewport.x, sceneData.viewport.y); } void main() { vec3 FragPos = texture(positionSampler, CalcTexCoord()).rgb; vec3 Normal = texture(normalSampler, CalcTexCoord()).rgb; vec3 Albedo = texture(albedoSampler, CalcTexCoord()).rgb; float roughness = texture(materialSampler, CalcTexCoord()).r; float metallic = texture(materialSampler, CalcTexCoord()).g; float emission = texture(materialSampler, CalcTexCoord()).b; vec3 V = normalize(sceneData.cameraPosition.xyz - FragPos); vec3 F0 = vec3(0.04); F0 = mix(F0, Albedo, metallic); vec3 F = fresnelSchlickRoughness(max(dot(Normal, V), 0.0), F0, roughness); vec3 kS = F; vec3 kD = vec3(1.0) - kS; kD *= 1.0 - metallic; vec3 L = normalize(sceneData.lightPosition.xyz - FragPos); vec3 H = normalize(V + L); vec3 radiance = sceneData.color * (CalculateAttenuation(sceneData.lightPosition.xyz, sceneData.radius, FragPos) * sceneData.radius); float NDF = DistributionGGX(Normal, H, roughness); float G = GeometrySmith(Normal, V, L, roughness); vec3 nominator = NDF * G * F; float denominator = 4 * max(dot(V, Normal), 0.0) * max(dot(L, Normal), 0.0) + 0.001; vec3 brdf = nominator / denominator; // add to outgoing radiance Lo float NdotL = max(dot(Normal, L), 0.0); outColor = vec4(((kD * Albedo / PI + brdf) * radiance * NdotL), 1.0); }