Archived
1
Fork 0
This repository has been archived on 2025-04-12. You can view files and clone it, but cannot push or open issues or pull requests.
graphite/dist/shaders/forward/lighting.frag

195 lines
5.3 KiB
GLSL
Raw Normal View History

2024-01-03 16:05:02 -05:00
#include "lighting.glsl"
in VS_OUT {
vec3 FragPos;
vec3 Normal;
vec2 TexCoords;
mat3 TBN;
} vs_in;
layout(location = 0) out vec4 outColor;
layout(location = 1) out vec4 brightColor;
struct Light {
vec4 position;
vec3 color;
int type;
vec3 direction;
float radius;
mat4 lightspace;
};
layout(std140, binding = 0) uniform UniformSceneData {
mat4 projection, view, model;
vec4 cameraPosition;
} sceneData;
layout(std140, binding = 1) uniform UniformMaterialData {
vec4 albedoTint;
vec3 emission;
float metallic, roughness;
} materialData;
layout(std140, binding = 2) uniform UniformLightData {
Light lights[MAX_LIGHTS];
int numlights;
} lightData;
const mat4 biasMat = mat4(
0.5, 0.0, 0.0, 0.0,
0.0, 0.5, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.5, 0.5, 0.0, 1.0 );
layout(binding = 3) uniform sampler2D albedo_tex;
layout(binding = 4) uniform sampler2D normal_tex;
layout(binding = 5) uniform sampler2D metallic_tex;
layout(binding = 6) uniform sampler2D roughness_tex;
layout(binding = 7) uniform sampler2D directional_shadow;
layout(binding = 8) uniform samplerCube point_shadow;
float PointShadowCalculation(Light light)
{
if(light.position.w == 0.0f)
return 1.0f;
vec3 fragToLight = vs_in.FragPos - light.position.xyz;
float closestDepth = texture(point_shadow, fragToLight).r;
closestDepth *= 25.0; //far-plane
float currentDepth = length(fragToLight);
float bias = 0.05;
float shadow = currentDepth - bias > closestDepth ? 0.0 : 1.0;
return shadow;
}
float ShadowCalculation(Light light)
{
if(light.position.w == 0.0f)
return 1.0f;
vec4 fragPosLightSpace = light.lightspace * vec4(vs_in.FragPos, 1.0);
float bias = 0.001;
vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w;
projCoords = projCoords * 0.5 + 0.5;
float closestDepth = texture(directional_shadow, projCoords.xy).r;
float currentDepth = projCoords.z;
float shadow = currentDepth - bias > closestDepth ? 0.0 : 1.0;
return shadow;
}
vec4 GetAlbedo() {
if(textureSize(albedo_tex, 0).x <= 1)
return vec4(materialData.albedoTint.rgb, 1.0);
return vec4(texture(albedo_tex, vs_in.TexCoords).rgb * materialData.albedoTint.rgb, texture(albedo_tex, vs_in.TexCoords).a);
}
vec3 GetNormal() {
if(textureSize(normal_tex, 0).x <= 1)
return normalize(vs_in.Normal);
vec3 normal = texture(normal_tex, vs_in.TexCoords).rgb;
normal = 2.0 * normal - 1.0;
normal = vs_in.TBN * normal;
return normalize(normal);
}
float GetMetallic() {
if(textureSize(metallic_tex, 0).x <= 1)
return materialData.metallic;
return texture(metallic_tex, vs_in.TexCoords).r;
}
float GetRoughness() {
if(textureSize(roughness_tex, 0).x <= 1)
return materialData.roughness;
return texture(roughness_tex, vs_in.TexCoords).r;
}
vec3 CalculatePointLight(Light light, vec3 kD, vec3 F) {
vec3 N = GetNormal();
vec3 V = normalize(sceneData.cameraPosition.xyz - vs_in.FragPos);
vec3 L = normalize(light.position.xyz - vs_in.FragPos);
vec3 H = normalize(V + L);
vec3 radiance = (light.color * (CalculateAttenuation(light.position.xyz, light.radius, vs_in.FragPos) * light.radius)) * PointShadowCalculation(light);
float NDF = DistributionGGX(N, H, GetRoughness());
float G = GeometrySmith(N, V, L, GetRoughness());
vec3 nominator = NDF * G * F;
float denominator = 4 * max(dot(V, N), 0.0) * max(dot(L, N), 0.0) + 0.001;
vec3 brdf = nominator / denominator;
// add to outgoing radiance Lo
float NdotL = max(dot(N, L), 0.0);
return (kD * GetAlbedo().rgb / PI + brdf) * radiance * NdotL;
}
vec3 CalculateDirectionalLight(Light light, vec3 kD, vec3 F) {
vec3 N = GetNormal();
vec3 V = normalize(sceneData.cameraPosition.xyz - vs_in.FragPos);
vec3 L = normalize(-light.direction);
vec3 H = normalize(V + L);
vec3 radiance = light.color * ShadowCalculation(light);
float NDF = DistributionGGX(N, H, GetRoughness());
float G = GeometrySmith(N, V, L, GetRoughness());
vec3 nominator = NDF * G * F;
float denominator = 4 * max(dot(V, N), 0.0) * max(dot(L, N), 0.0) + 0.001;
vec3 brdf = nominator / denominator;
// add to outgoing radiance Lo
float NdotL = max(dot(N, L), 0.0);
return (kD * GetAlbedo().rgb / PI + brdf) * radiance * NdotL;
}
void main() {
if(GetAlbedo().a < 0.1)
discard;
vec3 V = normalize(sceneData.cameraPosition.xyz - vs_in.FragPos);
vec3 F0 = vec3(0.04);
F0 = mix(F0, GetAlbedo().rgb, GetMetallic());
vec3 F = fresnelSchlickRoughness(max(dot(GetNormal(), V), 0.0), F0, GetRoughness());
vec3 kS = F;
vec3 kD = vec3(1.0) - kS;
kD *= 1.0 - GetMetallic();
vec3 result = vec3(0);
for(int i = 0; i < lightData.numlights; i++) {
switch(lightData.lights[i].type) {
case 0:
result += CalculateDirectionalLight(lightData.lights[i], kD, F);
break;
case 1:
result += CalculatePointLight(lightData.lights[i], kD, F);
break;
}
}
vec3 ambient = vec3(0.01) * GetAlbedo().rgb;
outColor = vec4(ambient + result + materialData.emission, GetAlbedo().a);
float brightness = dot(outColor.rgb, vec3(0.2126, 0.7152, 0.0722));
if(brightness > 0.9)
brightColor = vec4(outColor.rgb, 1.0);
}