Gaussian Blur никогда не работает правильно

Изображение проблемы

По какой-то причине каждый раз, когда я делаю размытие, получается вот так, и я действительно путаюсь, почему это так. Что касается цветения, то размытие было все пиксельным, и все равно, как каждый раз, когда я делаю размытие, это происходит. Я действительно понятия не имею, в чем проблема.

Вот весь код для размытия карт теней дисперсии, которые вам нужны.

GaussianBlurВертикальный фрагментный шейдер ..

#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);
}

GuassianBlurГоризонтальный фрагментный шейдер ..

#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

Решение

В общем, ваш гауссовский размытый шейдер работает, но вы используете его неправильно.

Газовым шейдером размытия в вашем вопросе является двухпроходный шейдер. 1-й проход размывает вертикальный, а 2-й проход размывает горизонтальный.
Для этого нужны 2 целевые текстуры. Вертикальный проход размытия читает исходную текстуру и записывает в «промежуточную» текстуру. Горизонтальное размытие читает «промежуточную» текстуру и записывает в целевую текстуру.

Создайте 2 кадровых буфера и 2 текстурных вложения, так же, как вы сделали это в своем вопросе. Конечно, можно использовать 1 кадровый буфер с 2 текстурными вложениями и переключать текстурные вложения также между проходами. Фактически, текстурное вложение одного кадрового буфера также может быть изменено между проходами.
В своем ответе я решил создать 2 кадровых буфера, потому что код вашего вопроса можно использовать повторно полностью.

Создать объект мошенничества _intermediateshadowmap_fbo и прикрепленный объект текстуры _intermediate_shadowmap как ты это сделал для _filteredshadowmap_fbo а также _filtered_shadowmap в вопросе:

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

glGenTextures(1, &_intermediate_shadowmap);

.....

И создайте 2-й объект мошенничества _filteredshadowmap_fbo и 2-й объект текстуры _filtered_shadowmap:

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

glGenTextures(1, &_filtered_shadowmap);

.....

Чтобы создать размытую текстуру, необходимо сделать следующее:

  • установить размер области просмотра для текстуры
  • связать мошенника _intermediateshadowmap_fbo
  • сделать вертикальное размытие с исходной текстурой _shadowmap
  • связать мошенника _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);
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]