高斯模糊永远无法正常工作
Gaussian Blur never works correctly
出于某种原因,每次我做模糊处理时,结果都是这样,我真的很困惑为什么会这样。对于绽放,模糊都是像素化的,而且每次我做模糊时都会发生这种情况。我真的不知道问题是什么。
这是您需要的所有用于模糊方差阴影贴图的代码。
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);
}
GuassianBlurHorizontal 片段着色器..
#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);
一般来说,你的高斯模糊着色器是可以工作的,但是你用错了。
您问题中的高斯模糊着色器是一个 2 pass 着色器。第 1 遍模糊垂直,第 2 遍模糊水平。
为此,需要 2 个目标纹理。垂直模糊通道读取源纹理并写入 "intermediate" 纹理。水平模糊读取 "intermediate" 纹理并写入目标纹理。
创建 2 个帧缓冲区和 2 个纹理附件,方法与您提出问题时的方法相同。当然,也可以使用带有 2 个纹理附件的 1 个帧缓冲区,并在通道之间切换纹理附件。事实上,一个帧缓冲区的纹理附件也可以在通道之间更改。
在我的回答中,我决定创建 2 个帧缓冲区,因为你的问题的代码可以完全重用。
创建一个 frambuffer 对象 _intermediateshadowmap_fbo
和一个附加的纹理对象 _intermediate_shadowmap
,就像您在问题中为 _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
- 绑定默认帧缓冲区
- 设置默认帧缓冲区的视口大小 (window)
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);
出于某种原因,每次我做模糊处理时,结果都是这样,我真的很困惑为什么会这样。对于绽放,模糊都是像素化的,而且每次我做模糊时都会发生这种情况。我真的不知道问题是什么。
这是您需要的所有用于模糊方差阴影贴图的代码。
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);
}
GuassianBlurHorizontal 片段着色器..
#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);
一般来说,你的高斯模糊着色器是可以工作的,但是你用错了。
您问题中的高斯模糊着色器是一个 2 pass 着色器。第 1 遍模糊垂直,第 2 遍模糊水平。
为此,需要 2 个目标纹理。垂直模糊通道读取源纹理并写入 "intermediate" 纹理。水平模糊读取 "intermediate" 纹理并写入目标纹理。
创建 2 个帧缓冲区和 2 个纹理附件,方法与您提出问题时的方法相同。当然,也可以使用带有 2 个纹理附件的 1 个帧缓冲区,并在通道之间切换纹理附件。事实上,一个帧缓冲区的纹理附件也可以在通道之间更改。
在我的回答中,我决定创建 2 个帧缓冲区,因为你的问题的代码可以完全重用。
创建一个 frambuffer 对象 _intermediateshadowmap_fbo
和一个附加的纹理对象 _intermediate_shadowmap
,就像您在问题中为 _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
- 绑定默认帧缓冲区
- 设置默认帧缓冲区的视口大小 (window)
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);