我正在按照本文http://fabiensanglard.net/shadowmappingVSM/实现方差阴影贴图我正在使用延迟渲染器,目前我已设法使用线性过滤实现vsm。结果还可以,但我似乎无法将高斯滤镜应用于阴影以创建柔和阴影。 以下代码显示了我如何设置阴影框缓冲区:
glBindFramebuffer(GL_FRAMEBUFFER, shadow_fbo_);
for (unsigned int i = 0; i < scene_->getAllSpotLights().size(); i++)
{
SceneModel::SpotLight spotlight = scene_->getAllSpotLights()[i];
if (spotlight.getCastShadow())
{
GLuint shadow_map_tex;
glGenTextures(1, &shadow_map_tex);
glBindTexture(GL_TEXTURE_2D, shadow_map_tex);
SetShadowTextureSettings();
shadow_maps_.insert(std::pair<int, GLuint>(i, shadow_map_tex));
GLuint blurred_map_tex;
glGenTextures(1, &blurred_map_tex);
glBindTexture(GL_TEXTURE_2D, blurred_map_tex);
SetShadowTextureSettings();
blurred_shadow_maps_.insert(std::pair<int, GLuint>(i, blurred_map_tex));
}
}
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, shadow_maps_[0], 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, blurred_shadow_maps_[0], 0);
//rbo depth attatchment
glBindRenderbuffer(GL_RENDERBUFFER, shadow_rbo_);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT32, SHADOW_WIDTH, SHADOW_HEIGHT);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, shadow_rbo_);
ReportErrorInFrameBuffer(framebuffer_status, "Shadow");
SetShadowTextureSettings()函数是:
void SetShadowTextureSettings()
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RG32F, SHADOW_WIDTH, SHADOW_HEIGHT, 0, GL_RG, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
}
我首先从光点开始渲染,然后尝试模糊创建的阴影,然后正常渲染场景。模糊似乎不起作用或对阴影有任何影响。下面显示了高斯着色器。
顶点着色器:
#version 330
layout(location=0) in vec3 vertex_position;
void main(void)
{
gl_Position = vec4(vertex_position, 1);
}
片段着色器:
#version 330
uniform sampler2D sampler_world_shadow;
uniform vec2 blurScale;
out vec4 fragment_colour;
const vec2 gaussianFilter[7] = vec2[]
(
vec2(-3.0, 0.015625),
vec2(-2.0, 0.09375),
vec2(-1.0, 0.234375),
vec2(0.0, 0.3125),
vec2(1.0, 0.234375),
vec2(2.0, 0.09375),
vec2(3.0, 0.015625)
);
void main()
{
vec2 coord = vec2(gl_FragCoord.xy);
vec3 colour = vec3(0.0);
float x = 0.0;
float y = 0.0;
for( int i = 0; i < 7; i++ )
{
x = coord.x + gaussianFilter[i].x * blurScale.x;
y = coord.y + gaussianFilter[i].x * blurScale.y;
colour += texture(sampler_world_shadow, vec2(x, y)) * gaussianFilter[i].y;
}
fragment_colour = vec4(colour,1);
}
以下代码显示了我如何尝试在阴影上进行模糊处理。在两个颜色附件之间切换。
void BlurShadow()
{
int blur_amount = 2;
for (std::pair<int, GLuint> pair : shadow_maps_)
{
//Blur horizontally
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, blurred_shadow_maps_[pair.first], 0);
glDrawBuffer(GL_COLOR_ATTACHMENT1);
glActiveTexture(GL_TEXTURE4);
glBindTexture(GL_TEXTURE_2D, pair.second);
glUniform1i(glGetUniformLocation(shadow_blur_program_, "sampler_world_shadow"), 4);
glm::vec2 blur = glm::vec2((1.0 / SHADOW_WIDTH) * blur_amount, 0.0);
glUniform2fv(glGetUniformLocation(shadow_blur_program_, "blurScale"), 1, glm::value_ptr(blur));
glBindVertexArray(light_quad_mesh_.vao);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
//Blur vertically
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, pair.second, 0);
glDrawBuffer(GL_COLOR_ATTACHMENT0);
glActiveTexture(GL_TEXTURE5);
glBindTexture(GL_TEXTURE_2D, blurred_shadow_maps_[pair.first]);
glUniform1i(glGetUniformLocation(shadow_blur_program_, "sampler_world_shadow"), 4);
blur = glm::vec2(0.0, (1.0 / SHADOW_WIDTH) * blur_amount);
glUniform2fv(glGetUniformLocation(shadow_blur_program_, "blurScale"), 1, glm::value_ptr(blur));
glBindVertexArray(light_quad_mesh_.vao);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}
}
总体步骤:
//SHADOWS render to depth map
glUseProgram(shadow_program_);
glBindFramebuffer(GL_FRAMEBUFFER, shadow_fbo_);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, SHADOW_WIDTH, SHADOW_HEIGHT);
//Cull front face to help with anti aliasing in shadows
glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT);
DrawToShadowDepthMap();
glCullFace(GL_BACK);
//GAUSSIAN BLUR on shadow maps
glUseProgram(shadow_blur_program_);
BlurShadow();
glViewport(0, 0, viewport_size[2], viewport_size[3]);
//other lighting calculations /rendering scene
我的想法是在模糊函数或高斯着色器中出现问题,但我无法弄清楚是什么。如果我将垂直模糊阶段和blit颜色附件1注释掉到屏幕上,就好像阴影刚从颜色附件0中复制一样。
任何帮助都将不胜感激。