高斯模糊永远不会正常工作

时间:2018-06-13 15:42:43

标签: c++ opengl blur shadows gaussianblur

Image of the problem

由于某种原因,每次我模糊都会发现这样,我真的很困惑为什么会这样。对于绽放,模糊是所有像素化,仍然是每次我模糊这种情况发生。我真的不知道问题是什么。

以下是模糊您需要的方差阴影贴图的所有代码。

GaussianBlurVertical片段着色器..

#version 330 core

out vec4 FragColor; //fragment shader output

in vec2 _texcoord;  //input interpolated texture coordinate

uniform sampler2D textureMap; //the input image to blur

//constant kernel values for Gaussian smoothing
const float kernel[]=float[21] (0.000272337,  0.00089296, 0.002583865, 0.00659813,  0.014869116,
                                0.029570767, 0.051898313, 0.080381679, 0.109868729, 0.132526984, 
                                0.14107424,  0.132526984, 0.109868729, 0.080381679, 0.051898313, 
                                0.029570767, 0.014869116, 0.00659813,  0.002583865, 0.00089296, 0.000272337);

void main()
{ 
    //get the inverse of texture size
    vec2 delta = 1.0 / textureSize(textureMap,0);
    vec4 color = vec4(0);
    int  index = 20;

    //go through all neighbors and multiply the kernel value with the obtained 
    //colour from the input image
    for(int i =- 10; i <= 10; i++) {                
        color += kernel[index--] * texture(textureMap, _texcoord + (vec2(0, i * delta.y)));
    } 

    //return the filtered colour as fragment output
    FragColor =  vec4(color.xy,0,0);    
}

GuassianBlurHorizo​​ntal片段着色器..

#version 330 core

out vec4 FragColor; //fragment shader output

in vec2 _texcoord;  //input interpolated texture coordinate

//uniform
uniform sampler2D textureMap;   //the input image to blur

//constant kernel values for Gaussian smoothing
const float kernel[]=float[21] (0.000272337,  0.00089296, 0.002583865, 0.00659813,  0.014869116,
                                0.029570767, 0.051898313, 0.080381679, 0.109868729, 0.132526984, 
                                0.14107424,  0.132526984, 0.109868729, 0.080381679, 0.051898313, 
                                0.029570767, 0.014869116, 0.00659813,  0.002583865, 0.00089296, 0.000272337);

void main()
{ 
    //get the inverse of texture size
    vec2 delta = 1.0 / textureSize(textureMap, 0);
    vec4 color = vec4(0);
    int  index = 20;

    //go through all neighbors and multiply the kernel value with the obtained 
    //colour from the input image
    for(int i =- 10; i <= 10; i++) {                
        color += kernel[index--] * texture(textureMap, _texcoord + (vec2(i * delta.x, 0)));
    }

    //return the filtered colour as fragment output
    FragColor =  vec4(color.xy, 0, 0);  
}

模糊舞台......

glBindFramebuffer(GL_FRAMEBUFFER, _filteredshadowmap_fbo);

glUseProgram(_program_blurH);
glUniform1i(_u_texture_map_h, 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, _shadowmap);
renderQuad();

glUseProgram(_program_blurV);
glUniform1i(_u_texture_map_v, 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, _shadowmap);
renderQuad();

glBindFramebuffer(GL_FRAMEBUFFER, 0);

初始化模糊fbo ..

// shadowmap blurring
        glGenFramebuffers(1, &_filteredshadowmap_fbo);
        glBindFramebuffer(GL_FRAMEBUFFER, _filteredshadowmap_fbo);

        glGenTextures(1, &_filtered_shadowmap);

        glBindTexture(GL_TEXTURE_2D, _filtered_shadowmap);

        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_CLAMP_TO_BORDER);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);

        glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);

        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, SHADOW_QUALITY, SHADOW_QUALITY, 0, GL_RGBA, GL_FLOAT, NULL);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _filtered_shadowmap, 0);

        GLenum status2 = glCheckFramebufferStatus(GL_FRAMEBUFFER);
        status2 != GL_FRAMEBUFFER_COMPLETE ? std::cerr << "Unable to create FBO" << std::endl : std::cout << "FBOs Were successful" << std::endl;

        glBindFramebuffer(GL_FRAMEBUFFER, 0);

1 个答案:

答案 0 :(得分:1)

一般情况下,高斯模糊着色器有效,但您使用的方式不对。

你问题中的高斯模糊着色器是一个2遍着色器。第1道次垂直模糊,第2道次横向模糊 要做到这一点,需要2个目标纹理。垂直模糊传递读取源纹理并写入&#34;中间&#34;质地。水平模糊读取&#34;中间&#34;纹理并写入目标纹理。

创建2个帧缓冲区和2个纹理附件,方法与您的问题相同。当然,也可以使用带有2个纹理附件的1帧缓冲区,并在通道之间切换纹理附件。事实上,一个帧缓冲的纹理附加也可以在通道之间改变 在我的回答中,我决定创建2个帧缓冲区,因为你的问题的代码可以完全重用。

在问题中为_intermediateshadowmap_fbo_intermediate_shadowmap创建一个frambuffer对象_filteredshadowmap_fbo和附加的纹理对象_filtered_shadowmap

glGenFramebuffers(1, &_intermediateshadowmap_fbo);
glBindFramebuffer(GL_FRAMEBUFFER, _intermediateshadowmap_fbo);

glGenTextures(1, &_intermediate_shadowmap);

.....

创建第二个frambuffer对象_filteredshadowmap_fbo和第二个纹理对象_filtered_shadowmap

glGenFramebuffers(1, &_filteredshadowmap_fbo);
glBindFramebuffer(GL_FRAMEBUFFER, _filteredshadowmap_fbo);

glGenTextures(1, &_filtered_shadowmap);

.....

要创建模糊纹理,必须执行以下操作:

  • 设置纹理的视口大小
  • 绑定frambuffer _intermediateshadowmap_fbo
  • 使用源纹理_shadowmap
  • 执行垂直模糊
  • 绑定frambuffer _filteredshadowmap_fbo
  • 使用源纹理_intermediate_shadowmap
  • 执行垂直模糊
  • 绑定默认的帧缓冲区
  • 设置默认帧缓冲区(窗口)的视口大小


glViewport( 0, 0, SHADOW_QUALITY, SHADOW_QUALITY );
glBindFramebuffer(GL_FRAMEBUFFER, _intermediateshadowmap_fbo);

glUseProgram(_program_blurH);
glUniform1i(_u_texture_map_h, 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, _shadowmap);
renderQuad();

glBindFramebuffer(GL_FRAMEBUFFER, _filteredshadowmap_fbo);

glUseProgram(_program_blurV);
glUniform1i(_u_texture_map_v, 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, _intermediate_shadowmap);
renderQuad();

glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, window_width, window_height);