具有方差阴影贴图的高斯模糊

时间:2016-04-03 15:59:06

标签: c++ opengl

我正在按照本文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中复制一样。

任何帮助都将不胜感激。

0 个答案:

没有答案