每次模糊时,我都会遇到条带问题,对体积光照进行径向模糊,我明白了。
所有的代码似乎都是正确的,我看不出为什么它行不通。立体照明效果很好,但是条纹很烦人。
我已经进行了一些研究,发现抖动可能可以解决此问题,但是为了做到这一点,我在代码中一定有做错的地方。下面是您需要的所有代码。
径向模糊片段着色器
#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);