Compare commits
4 Commits
2a661daf3e
...
163d413f9c
Author | SHA1 | Date | |
---|---|---|---|
163d413f9c | |||
da460af0b1 | |||
8c5b04ad97 | |||
b4e0cefbe7 |
@ -59,6 +59,11 @@ vec2 get_parallax_offset_uv(vec2 uv, vec3 view_direction) {
|
|||||||
return current_uv;
|
return current_uv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return a linear interpolation (0..1) of value between low and high, or 0.0 / 1.0 if value is below / above the bounds
|
||||||
|
float linear_step(float low, float high, float value) {
|
||||||
|
return clamp((value - low) / (high - low), 0.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
float get_shadow(vec4 fragPosLightSpace, vec3 normal) {
|
float get_shadow(vec4 fragPosLightSpace, vec3 normal) {
|
||||||
// perform perspective divide
|
// perform perspective divide
|
||||||
mediump vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w;
|
mediump vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w;
|
||||||
@ -72,17 +77,20 @@ float get_shadow(vec4 fragPosLightSpace, vec3 normal) {
|
|||||||
vec2 moments = texture(shadowMap, projCoords.xy).rg;
|
vec2 moments = texture(shadowMap, projCoords.xy).rg;
|
||||||
|
|
||||||
// get closest depth value from light's perspective (using [0,1] range fragPosLight as coords)
|
// get closest depth value from light's perspective (using [0,1] range fragPosLight as coords)
|
||||||
mediump float closestDepth = texture(shadowMap, projCoords.xy).r;
|
mediump float closestDepth = moments.r;
|
||||||
// get depth of current fragment from light's perspective
|
// get depth of current fragment from light's perspective
|
||||||
mediump float currentDepth = projCoords.z;
|
mediump float currentDepth = projCoords.z;
|
||||||
// check whether current frag pos is in shadow
|
// check whether current frag pos is in shadow
|
||||||
float p = step(projCoords.z, moments.x);
|
float p = step(projCoords.z, moments.x);
|
||||||
|
|
||||||
// We divide by this later, so make sure it's not exactly 0
|
// We divide by this later, so make sure it's not exactly 0
|
||||||
// It seems like it should always be 0.0, but due to interpolation it's not -- it increases with the deviation!
|
// It seems like it should always be 0.0, but due to interpolation it's not -- it increases with the deviation!
|
||||||
float variance = max(moments.y - moments.x * moments.x, 0.00002);
|
// A larger second parameter to max() means more blur (but also more light bleeding)
|
||||||
|
float variance = max(moments.y - moments.x * moments.x, (-0.01 + (currentDepth - closestDepth) * 0.7) * 0.1);
|
||||||
|
|
||||||
float d = projCoords.z - moments.x * 1.0; // bias should be "compare", what is that?
|
float d = projCoords.z - moments.x * 1.0;
|
||||||
float p_max = variance / (variance + d * d);
|
// Use linear_step to prevent light bleeding
|
||||||
|
float p_max = linear_step(0.2, 1.0, variance / (variance + d * d));
|
||||||
|
|
||||||
// If this pixel is exactly in the light, p is 1, so make sure we return that in that case
|
// If this pixel is exactly in the light, p is 1, so make sure we return that in that case
|
||||||
// min() to make sure that it doesn't get greater than 1.0
|
// min() to make sure that it doesn't get greater than 1.0
|
||||||
|
@ -35,7 +35,7 @@ void main() {
|
|||||||
vec3 N = normalize(mat3(model) * aNormal);
|
vec3 N = normalize(mat3(model) * aNormal);
|
||||||
mat3 TBN = transpose(mat3(T, B, N));
|
mat3 TBN = transpose(mat3(T, B, N));
|
||||||
|
|
||||||
vs_out.TangentLightDir = light_direction;
|
vs_out.TangentLightDir = TBN * -light_direction;
|
||||||
vs_out.TangentViewPos = TBN * viewPos;
|
vs_out.TangentViewPos = TBN * viewPos;
|
||||||
vs_out.TangentFragPos = TBN * vs_out.FragPos;
|
vs_out.TangentFragPos = TBN * vs_out.FragPos;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
#version 430
|
#version 430
|
||||||
|
|
||||||
|
out vec4 FragColor;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// The mean and the mean squared, which we need to calculate the variance
|
// The mean and the mean squared, which we need to calculate the variance
|
||||||
gl_FragColor = vec4(gl_FragCoord.z, gl_FragCoord.z * gl_FragCoord.z, 0.0, 0.0);
|
FragColor = vec4(gl_FragCoord.z, gl_FragCoord.z * gl_FragCoord.z, 0.0, 0.0);
|
||||||
}
|
}
|
@ -10,28 +10,6 @@ class DirectionalLight {
|
|||||||
public:
|
public:
|
||||||
glm::vec3 direction;
|
glm::vec3 direction;
|
||||||
|
|
||||||
DirectionalLight() : shadow_shader(Gedeng::Shader("Shader/shadow.vs", "Shader/shadow.fs")) {
|
|
||||||
// Configure depth map
|
|
||||||
glGenFramebuffers(1, &depth_map_fbo);
|
|
||||||
|
|
||||||
// Create depth texture
|
|
||||||
glGenTextures(1, &depth_map);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, depth_map);
|
|
||||||
// R and G with 32 bit floats: stores mean and variance
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RG32F, SHADOW_WIDTH, SHADOW_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
|
||||||
|
|
||||||
// Attach depth texture as FBO's depth buffer
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, depth_map_fbo);
|
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, depth_map, 0);
|
|
||||||
glDrawBuffer(GL_NONE);
|
|
||||||
glReadBuffer(GL_NONE);
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit DirectionalLight(glm::vec3 direction)
|
explicit DirectionalLight(glm::vec3 direction)
|
||||||
// TODO: Avoid all this duplication
|
// TODO: Avoid all this duplication
|
||||||
: direction(direction), shadow_shader(Gedeng::Shader("Shader/shadow.vs", "Shader/shadow.fs")) {
|
: direction(direction), shadow_shader(Gedeng::Shader("Shader/shadow.vs", "Shader/shadow.fs")) {
|
||||||
@ -41,8 +19,7 @@ class DirectionalLight {
|
|||||||
// Create depth texture
|
// Create depth texture
|
||||||
glGenTextures(1, &depth_map);
|
glGenTextures(1, &depth_map);
|
||||||
glBindTexture(GL_TEXTURE_2D, depth_map);
|
glBindTexture(GL_TEXTURE_2D, depth_map);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, SHADOW_WIDTH, SHADOW_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RG32F, SHADOW_WIDTH, SHADOW_HEIGHT, 0, GL_RGB, GL_FLOAT, NULL);
|
||||||
NULL);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||||
@ -50,9 +27,7 @@ class DirectionalLight {
|
|||||||
|
|
||||||
// Attach depth texture as FBO's depth buffer
|
// Attach depth texture as FBO's depth buffer
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, depth_map_fbo);
|
glBindFramebuffer(GL_FRAMEBUFFER, depth_map_fbo);
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth_map, 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, depth_map, 0);
|
||||||
glDrawBuffer(GL_NONE);
|
|
||||||
glReadBuffer(GL_NONE);
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,10 +92,10 @@ class ShadowDemo : public Gedeng::Application {
|
|||||||
void dynamic_update(double delta) override {
|
void dynamic_update(double delta) override {
|
||||||
// Shadows
|
// Shadows
|
||||||
light.clear_shadows();
|
light.clear_shadows();
|
||||||
|
light.render_shadow(quad_mesh);
|
||||||
light.render_shadow(mesh1);
|
light.render_shadow(mesh1);
|
||||||
light.render_shadow(mesh2);
|
light.render_shadow(mesh2);
|
||||||
light.render_shadow(mesh3);
|
light.render_shadow(mesh3);
|
||||||
light.render_shadow(quad_mesh);
|
|
||||||
|
|
||||||
glViewport(0, 0, 1920, 1080);
|
glViewport(0, 0, 1920, 1080);
|
||||||
glClearColor(0.1, 0.1f, 0.1, 1.0f);
|
glClearColor(0.1, 0.1f, 0.1, 1.0f);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user