Skip to content

Commit

Permalink
Fixed IBL and reduced SSAO samples to 32
Browse files Browse the repository at this point in the history
  • Loading branch information
Fabian Huber authored and Fabian Huber committed May 4, 2024
1 parent 3dd5aea commit ed724fc
Show file tree
Hide file tree
Showing 9 changed files with 145 additions and 147 deletions.
8 changes: 4 additions & 4 deletions shaders/pbr/directional_light_pass.frag
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ void main()
float roughness = textureLod(gNormalRoughness, TexCoords, 0).a;
float metallic = textureLod(gBaseColorMetallic, TexCoords, 0).a;

vec3 viewDir = normalize(-fragPos);
vec3 viewDir = normalize(viewPos - fragPos);

vec3 F0 = vec3(0.04);
F0 = mix(F0, baseColor, metallic);
Expand Down Expand Up @@ -84,8 +84,8 @@ void main()
float normalDotFragToLightDir = max(dot(normal, fragToLightDir), 0.0);
vec3 color = (kDiffuse * baseColor / PI + specular) * radiance * normalDotFragToLightDir;

vec4 viewFragPos = view * vec4(fragPos, 1.0);
float depthValue = -viewFragPos.z;
vec3 viewSpaceFragPos = vec3(view * vec4(fragPos.xyz, 1.0));
float depthValue = -viewSpaceFragPos.z;
vec4 res = step(csmFarDistances, vec4(depthValue));
int shadowCascadeIndex = int(res.x + res.y + res.z + res.w);

Expand Down Expand Up @@ -173,7 +173,7 @@ float ComputeShadowIntensity(int cascadeIndex, vec4 fragPosLightSpace, vec3 norm

// Compute bias (based on depth map resolution and slope)
vec3 lightDirection = normalize(directionalLight.direction);
float bias = max(0.0005 * (1.0 / dot(normal, lightDirection)), 0.0002);
float bias = max(0.0005 * (1.0 / dot(normal, lightDirection)), 0.0003);

// PCF (Percentage-Closer Filtering)
float shadow = 0.0;
Expand Down
24 changes: 12 additions & 12 deletions shaders/pbr/gbuffer.vert
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,22 @@ out mat3 TangentToWorldMatrix;

layout (std140, binding = 0) uniform Matrices
{
mat4 projection;
mat4 view;
mat4 projection;
mat4 view;
};

void main()
{
TexCoords = aTexCoords;
vec4 fragPos = view * modelMatrix * vec4(aPos, 1.0);
FragPos = vec3(fragPos);
TexCoords = aTexCoords;
vec4 fragPos = modelMatrix * vec4(aPos, 1.0);
FragPos = vec3(fragPos);

mat3 normalMatrix = transpose(inverse(mat3(view * modelMatrix)));
vec3 T = normalize(normalMatrix * aTangent);
vec3 N = normalize(normalMatrix * aNormal);
T = normalize(T - dot(T, N) * N);
vec3 B = cross(N, T);
TangentToWorldMatrix = mat3(T, B, N);
mat3 normalMatrix = transpose(inverse(mat3(modelMatrix)));
vec3 T = normalize(normalMatrix * aTangent);
vec3 N = normalize(normalMatrix * aNormal);
T = normalize(T - dot(T, N) * N);
vec3 B = cross(N, T);
TangentToWorldMatrix = mat3(T, B, N);

gl_Position = projection * fragPos;
gl_Position = projection * view * fragPos;
}
112 changes: 59 additions & 53 deletions shaders/pbr/ibl_ambient.frag
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#version 430
#version 460

const float PI = 3.14159265359;
const float MAX_REFLECTION_LOD = 4.0;
Expand All @@ -15,6 +15,7 @@ uniform sampler2D gSsao;
uniform samplerCube irradianceMap;
uniform samplerCube prefilterMap;
uniform sampler2D brdfLut;
uniform vec3 viewPos;

vec3 FresnelSchlick(float cosTheta, vec3 F0);
float DistributionGGX(vec3 N, vec3 H, float roughness);
Expand All @@ -24,81 +25,86 @@ vec3 FresnelSchlickRoughness(float cosTheta, vec3 F0, float roughness);

void main()
{
vec3 fragPos = textureLod(gPositionAmbientOcclusion, TexCoords, 0).rgb;
vec3 normal = textureLod(gNormalRoughness, TexCoords, 0).rgb;
vec3 baseColor = textureLod(gBaseColorMetallic, TexCoords, 0).rgb;
float roughness = textureLod(gNormalRoughness, TexCoords, 0).a;
float metallic = textureLod(gBaseColorMetallic, TexCoords, 0).a;
float ambientOcclusion = textureLod(gSsao, TexCoords, 0).r * textureLod(gPositionAmbientOcclusion, TexCoords, 0).a;

// V
vec3 viewDir = normalize(-fragPos);
// R
vec3 reflection = reflect(-viewDir, normal);

vec3 F0 = vec3(0.04);
F0 = mix(F0, baseColor, metallic);

vec3 kSpecular = FresnelSchlickRoughness(max(dot(normal, viewDir), 0.0), F0, roughness);
vec3 kDiffuse = 1.0 - kSpecular;
kDiffuse *= 1.0 - metallic;

vec3 irradiance = texture(irradianceMap, normal).rgb;
vec3 diffuse = irradiance * baseColor;

// sample both the pre-filter map and the BRDF lut and combine them together
// as per the Split-Sum approximation to get the IBL specular part
vec3 prefilteredColor = textureLod(prefilterMap, reflection, roughness * MAX_REFLECTION_LOD).rgb;
vec2 brdf = texture(brdfLut, vec2(max(dot(normal, viewDir), 0.0), roughness)).rg;
vec3 specular = prefilteredColor * (kSpecular * brdf.x + brdf.y);

vec3 ambient = (kDiffuse * diffuse + specular) * ambientOcclusion;

// ambient = vec3(kSpecular);
FragColor = vec4(ambient, 1.0);
vec3 fragPos = textureLod(gPositionAmbientOcclusion, TexCoords, 0).rgb;
vec3 normal = textureLod(gNormalRoughness, TexCoords, 0).rgb;
vec3 baseColor = textureLod(gBaseColorMetallic, TexCoords, 0).rgb;
float roughness = textureLod(gNormalRoughness, TexCoords, 0).a;
float metallic = textureLod(gBaseColorMetallic, TexCoords, 0).a;

float ssao = textureLod(gSsao, TexCoords, 0).r;
float aoMap = textureLod(gPositionAmbientOcclusion, TexCoords, 0).a;
float ambientOcclusion = mix(ssao, aoMap, 0.5);

// V
vec3 viewDir = normalize(viewPos - fragPos);

// R
vec3 reflection = reflect(-viewDir, normal);

vec3 F0 = vec3(0.04);
F0 = mix(F0, baseColor, metallic);

vec3 kSpecular = FresnelSchlickRoughness(max(dot(normal, viewDir), 0.0), F0, roughness);
vec3 kDiffuse = 1.0 - kSpecular;
kDiffuse *= 1.0 - metallic;

vec3 irradiance = texture(irradianceMap, normal).rgb;
vec3 diffuse = irradiance * baseColor;

// sample both the pre-filter map and the BRDF lut and combine them together
// as per the Split-Sum approximation to get the IBL specular part
vec3 prefilteredColor = textureLod(prefilterMap, reflection, roughness * MAX_REFLECTION_LOD).rgb;
vec2 brdf = texture(brdfLut, vec2(max(dot(normal, viewDir), 0.0), roughness)).rg;
vec3 specular = prefilteredColor * (kSpecular * brdf.x + brdf.y);

vec3 ambient = (kDiffuse * diffuse + specular) * ambientOcclusion;

// ambient = vec3(kSpecular);
FragColor = vec4(ambient, 1.0);
// FragColor = vec4(viewPos, 1.0);
}

vec3 FresnelSchlick(float cosTheta, vec3 F0)
{
return F0 + (1.0 - F0) * pow(clamp(1.0 - cosTheta, 0.0, 1.0), 5.0);
return F0 + (1.0 - F0) * pow(clamp(1.0 - cosTheta, 0.0, 1.0), 5.0);
}

float DistributionGGX(vec3 N, vec3 H, float roughness)
{
float a = roughness*roughness;
float a2 = a*a;
float NdotH = max(dot(N, H), 0.0);
float NdotH2 = NdotH*NdotH;
float a = roughness * roughness;
float a2 = a * a;
float NdotH = max(dot(N, H), 0.0);
float NdotH2 = NdotH * NdotH;

float num = a2;
float denom = (NdotH2 * (a2 - 1.0) + 1.0);
denom = PI * denom * denom;
float num = a2;
float denom = (NdotH2 * (a2 - 1.0) + 1.0);
denom = PI * denom * denom;

return num / denom;
return num / denom;
}

float GeometrySchlickGGX(float NdotV, float roughness)
{
float r = (roughness + 1.0);
float k = (r*r) / 8.0;
float r = (roughness + 1.0);
float k = (r * r) / 8.0;

float num = NdotV;
float denom = NdotV * (1.0 - k) + k;
float num = NdotV;
float denom = NdotV * (1.0 - k) + k;

return num / denom;
return num / denom;
}

float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness)
{
float NdotV = max(dot(N, V), 0.0);
float NdotL = max(dot(N, L), 0.0);
float ggx2 = GeometrySchlickGGX(NdotV, roughness);
float ggx1 = GeometrySchlickGGX(NdotL, roughness);
float NdotV = max(dot(N, V), 0.0);
float NdotL = max(dot(N, L), 0.0);
float ggx2 = GeometrySchlickGGX(NdotV, roughness);
float ggx1 = GeometrySchlickGGX(NdotL, roughness);

return ggx1 * ggx2;
return ggx1 * ggx2;
}

vec3 FresnelSchlickRoughness(float cosTheta, vec3 F0, float roughness)
{
return F0 + (max(vec3(1.0 - roughness), F0) - F0) * pow(clamp(1.0 - cosTheta, 0.0, 1.0), 5.0);
return F0 + (max(vec3(1.0 - roughness), F0) - F0) * pow(clamp(1.0 - cosTheta, 0.0, 1.0), 5.0);
}
51 changes: 23 additions & 28 deletions shaders/pbr/point_light_pass.frag
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ uniform sampler2D gBaseColorMetallic;
uniform PointLight pointLight;

uniform vec2 screenSize;
uniform vec3 viewPos;

vec2 CalcTexCoord()
{
Expand All @@ -40,47 +41,41 @@ void main()
float metallic = textureLod(gBaseColorMetallic, texCoord, 0).a;

// V
vec3 viewDir = normalize(-fragPos);
vec3 viewDir = normalize(viewPos - fragPos);

vec3 F0 = vec3(0.04);
F0 = mix(F0, baseColor, metallic);

vec3 Lo = vec3(0.0);
// I cannot loop over every light...
{
// L
vec3 fragToLightDir = normalize(pointLight.position - fragPos);
// H
vec3 halfwayDir = normalize(fragToLightDir + viewDir);

float distance = distance(pointLight.position, fragPos);
// L
vec3 fragToLightDir = normalize(pointLight.position - fragPos);
// H
vec3 halfwayDir = normalize(fragToLightDir + viewDir);

float attenuation = 1.0 / (distance * distance);
vec3 radiance = pointLight.color * attenuation;
float distance = distance(pointLight.position, fragPos);

// F
vec3 fresnel = FresnelSchlick(max(dot(halfwayDir, viewDir), 0.0), F0);
float normalDistributionFunction = DistributionGGX(normal, halfwayDir, roughness);
float geometry = GeometrySmith(normal, viewDir, fragToLightDir, roughness);
float attenuation = 1.0 / (distance * distance);
vec3 radiance = pointLight.color * attenuation;

vec3 kSpecular = fresnel;
vec3 kDiffuse = vec3(1.0) - kSpecular;
kDiffuse *= 1.0 - metallic;
// F
vec3 fresnel = FresnelSchlick(max(dot(halfwayDir, viewDir), 0.0), F0);
float normalDistributionFunction = DistributionGGX(normal, halfwayDir, roughness);
float geometry = GeometrySmith(normal, viewDir, fragToLightDir, roughness);

// Cook-Torrance BRDF
vec3 numerator = normalDistributionFunction * geometry * fresnel;
// We add a small number to prevent division by 0
float denominator = 4.0 * max(dot(normal, viewDir), 0.0) * max(dot(normal, fragToLightDir), 0.0) + 0.0001;
vec3 specular = numerator / denominator;
vec3 kSpecular = fresnel;
vec3 kDiffuse = vec3(1.0) - kSpecular;
kDiffuse *= 1.0 - metallic;

float normalDotFragToLightDir = max(dot(normal, fragToLightDir), 0.0);
Lo += (kDiffuse * baseColor / PI + specular) * radiance * normalDotFragToLightDir;
// End of imaginary loop here
}
// Cook-Torrance BRDF
vec3 numerator = normalDistributionFunction * geometry * fresnel;
// We add a small number to prevent division by 0
float denominator = 4.0 * max(dot(normal, viewDir), 0.0) * max(dot(normal, fragToLightDir), 0.0) + 0.0001;
vec3 specular = numerator / denominator;

vec3 color = Lo;
float normalDotFragToLightDir = max(dot(normal, fragToLightDir), 0.0);

// color = vec3(brdf, 1.0);
vec3 color = (kDiffuse * baseColor / PI + specular) * radiance * normalDotFragToLightDir;

FragColor = vec4(color, 1.0);
}
Expand Down
8 changes: 1 addition & 7 deletions shaders/shadow_map/depth.vert
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,7 @@ layout (location = 4) in mat4 modelMatrix;

uniform mat4 lightViewProjMatrix;

layout (std140, binding = 0) uniform Matrices
{
mat4 projection;
mat4 view;
};

void main()
{
gl_Position = lightViewProjMatrix * view * modelMatrix * vec4(aPos, 1.0);
gl_Position = lightViewProjMatrix * modelMatrix * vec4(aPos, 1.0);
}
73 changes: 37 additions & 36 deletions shaders/ssao/ssao.frag
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#version 430

const int SAMPLES_COUNT = 64;
const int SAMPLES_COUNT = 32;
const float RANDOM_TEXTURE_SIZE = 4.0;
const float RADIUS = 0.5;
const float BIAS = 0.025;
Expand All @@ -18,43 +18,44 @@ uniform vec2 screenSize;

layout (std140, binding = 0) uniform Matrices
{
mat4 projection;
mat4 view;
mat4 projection;
mat4 view;
};

void main()
{
vec3 fragPos = textureLod(gPositionAmbientOcclusion, TexCoords, 0).rgb;
vec3 normal = textureLod(gNormalRoughness, TexCoords, 0).rgb;

vec2 noiseScale = screenSize / RANDOM_TEXTURE_SIZE;
vec3 randomVec = normalize(textureLod(texNoise, TexCoords * noiseScale, 0).xyz);

vec3 tangent = normalize(randomVec - normal * dot(randomVec, normal));
vec3 bitangent = cross(normal, tangent);
mat3 TBN = mat3(tangent, bitangent, normal);

float occlusion = 0.0;
for (int i = 0; i < SAMPLES_COUNT; i++)
{
// From tangent space to view space
vec3 samplePos = TBN * samples[i];
samplePos = fragPos + samplePos * RADIUS;

vec4 offset = vec4(samplePos, 1.0);
// from view to clip-space
offset = projection * offset;
// perspective divide
offset.xyz /= offset.w;
// transform to range 0.0 - 1.0
offset.xyz = offset.xyz * 0.5 + 0.5;

float sampleDepth = textureLod(gPositionAmbientOcclusion, offset.xy, 0).z;

float rangeCheck = smoothstep(0.0, 1.0, RADIUS / abs(fragPos.z - sampleDepth));
occlusion += (sampleDepth >= samplePos.z + BIAS ? 1.0 : 0.0) * rangeCheck;
}
occlusion = 1.0 - (occlusion / SAMPLES_COUNT);

FragColor = occlusion;
vec3 fragPos = vec3(view * vec4(textureLod(gPositionAmbientOcclusion, TexCoords, 0).rgb, 1.0));
vec3 normal = mat3(view) * textureLod(gNormalRoughness, TexCoords, 0).rgb;

vec2 noiseScale = screenSize / RANDOM_TEXTURE_SIZE;
vec3 randomVec = normalize(textureLod(texNoise, TexCoords * noiseScale, 0).xyz);

vec3 tangent = normalize(randomVec - normal * dot(randomVec, normal));
vec3 bitangent = cross(normal, tangent);
mat3 TBN = mat3(tangent, bitangent, normal);

float occlusion = 0.0;
for (int i = 0; i < SAMPLES_COUNT; i++)
{
// From tangent space to view space
vec3 samplePos = TBN * samples[i];
samplePos = fragPos + samplePos * RADIUS;

vec4 offset = vec4(samplePos, 1.0);
// from view to clip-space
offset = projection * offset;
// perspective divide
offset.xyz /= offset.w;
// transform to range 0.0 - 1.0
offset.xyz = offset.xyz * 0.5 + 0.5;

vec3 sampleFragPos = vec3(view * vec4(textureLod(gPositionAmbientOcclusion, offset.xy, 0).rgb, 1.0));
float sampleDepth = sampleFragPos.z;

float rangeCheck = smoothstep(0.0, 1.0, RADIUS / abs(fragPos.z - sampleDepth));
occlusion += (sampleDepth >= samplePos.z + BIAS ? 1.0 : 0.0) * rangeCheck;
}
occlusion = 1.0 - (occlusion / SAMPLES_COUNT);

FragColor = occlusion;
}
Loading

0 comments on commit ed724fc

Please sign in to comment.