У меня возникали проблемы с полосами при каждом размытии, я выполнял радиальное размытие для объемного освещения, и я получил это ..
весь код кажется правильным, и я не могу понять, почему он не будет работать. Объемная подсветка работает отлично, но полосатость раздражает.
Я провел некоторое исследование и узнал, что дизеринг может решить эту проблему, но должно быть что-то, что я делаю неправильно в коде, чтобы это произошло. Ниже приведен весь код, который вам нужен.
Фрагмент шейдера радиального размытия
#version 330 core
out vec4 FragColour;
in vec2 _texcoord;
uniform float exposure;
uniform float decay;
uniform float density;
uniform float weight;
uniform vec2 lightPositionOnScreen;
uniform sampler2D lightScatterTexture;
const int NUM_SAMPLES = 128;
void main(void)
{
vec2 deltaTextCoord = _texcoord - lightPositionOnScreen.xy;
vec2 textCoo = _texcoord;
deltaTextCoord *= 1.0 / float(NUM_SAMPLES) * density;
float illuminationDecay = 1.0;
vec2 dir = lightPositionOnScreen - textCoo;
dir /= NUM_SAMPLES;
for(int i=0; i < NUM_SAMPLES ; i++)
{
textCoo -= deltaTextCoord;
vec4 sample = texture2D(lightScatterTexture, textCoo );
sample *= illuminationDecay * weight;
FragColour += sample;
textCoo += dir;
illuminationDecay *= decay;
}
FragColour *= exposure;
}
Объемное световое радиальное размытие
// blur pass
glBindFramebuffer(GL_FRAMEBUFFER, _light_scatter_blur_fbo); // bind the gbuffer fbo to start the geometry pass
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // glclear the gbuffer before rendering to it
// bind the radial blur shader
glUseProgram(blur_program);
// get the light position in screenspace
glm::mat4 viewProjectionMatrix = projection * view;
glm::vec4 lightNDCPosition = viewProjectionMatrix * glm::vec4(2.0f, 10.0f, 20.0f, 1);
lightNDCPosition /= lightNDCPosition.w;
glm::vec2 lightScreenPosition = glm::vec2((lightNDCPosition.x + 1) * 0.5, (lightNDCPosition.y + 1) * 0.5);
// set the uniforms for the light scattering
glUniform1f(_u_exposure, 0.6050f);
glUniform1f(_u_decay, 0.9f);
glUniform1f(_u_density, 0.9f);
glUniform1f(_u_weight, 5.0f);
glUniform2f(_u_lightScreenPos, lightScreenPosition.x, lightScreenPosition.y); // TODO: Load this in within the constructer!
// bind the light scatter texture to radial blur
glUniform1i(_u_lightScatterTexture, 0); // TODO: Load this in within the constructer!
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, _light_scatter_texture);
// render the quad
renderQuad();
glBindFramebuffer(GL_FRAMEBUFFER, 0); // unbind the gbuffer, we dont need it anymore
Объемная установка FBO рассеяния света
glGenFramebuffers(1, &_light_scatter_fbo);
glBindFramebuffer(GL_FRAMEBUFFER, _light_scatter_fbo);
glGenTextures(1, &_light_scatter_texture);
glBindTexture(GL_TEXTURE_2D, _light_scatter_texture);
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_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1920, 1080, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _light_scatter_texture, NULL);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
std::cerr << "Error: Unable to create VLS fbo texture!" << std::endl;
glGenFramebuffers(1, &_light_scatter_blur_fbo);
glBindFramebuffer(GL_FRAMEBUFFER, _light_scatter_blur_fbo);
glGenTextures(1, &_light_scatter_blur_texture);
glBindTexture(GL_TEXTURE_2D, _light_scatter_blur_texture);
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_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1920, 1080, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _light_scatter_blur_texture, NULL);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
std::cerr << "Error: Unable to create VLS fbo texture!" << std::endl;
glBindFramebuffer(GL_FRAMEBUFFER, 0);