Recently been trying to implement volumetric lighting. The alphaness texture comes out perfectly on Renderdoc, however a strange glitch occurs whenever I either try to directly render the texture through a quad to the screen, or through multiplying the alphaness component with my regular texture. A strange static pattern (as shown in the image below) appears on the texture. The texture also periodically turns completely black, and in some frames the image comes out perfectly.
The volumetric lighting texture is rendered to a framebuffer with the settings below:
' Configure God Rays Buffer
' -------------------------
godRaysFramebuffer = GL.GenFramebuffer()
' Create color buffers
GL.BindFramebuffer(FramebufferTarget.Framebuffer, godRaysFramebuffer)
currentFrameTex = GL.GenTexture()
GL.ActiveTexture(TextureUnit.Texture0)
GL.BindTexture(TextureTarget.Texture2D, currentFrameTex)
GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1)
GL.TexParameterI(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, All.MirroredRepeat)
GL.TexParameterI(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, All.MirroredRepeat)
GL.TexParameterI(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, All.Nearest)
GL.TexParameterI(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, All.Nearest)
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.R16f, resolutionWidth,
resolutionHeight, 0, PixelFormat.Red, PixelType.Float, IntPtr.Zero)
GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0,
TextureTarget.Texture2D, currentFrameTex, 0)
Dim attachments() As Integer = {FramebufferAttachment.ColorAttachment0}
GL.DrawBuffers(attachments.Length, attachments)
The alphaness texture, from Renderdoc, is shown below:
The fragment shader which samples from the god rays texture (my HDR shader) is shown below. When I comment out the * texture(godRaysTex, TexCoords).r
it renders perfectly, however without the god rays.
#version 440 core
out vec4 out_color;
in vec2 TexCoords;
in vec3 vPos;
uniform sampler2D hdrBuffer;
uniform sampler2D godRaysTex;
uniform float exposure;
void main() {
const float gamma = 1.8;
vec3 hdrColor = texture(hdrBuffer, TexCoords).rgb * texture(godRaysTex, TexCoords).r;
// Exposure tone mapping
vec3 mapped = vec3(1.0) - exp(-hdrColor * exposure);
// Gamma correction
mapped = pow(mapped, vec3(1.0 / gamma));
out_color = vec4(mapped, 1.0);
}
Here is my volumetric lighting shader:
#version 440 core
uniform vec2 lightPositionOnScreen;
uniform sampler2D occlusionTex;
const int NUM_SAMPLES = 100;
const float exposure = 0.45;
const float decay = 0.98;
const float density = 0.9;
const float weight = 0.07;
in vec2 TexCoords;
in vec3 vPos;
layout (location = 0) out vec4 FragColor;
void main() {
vec2 textureCoords = TexCoords;
vec2 deltaTexCoords = vec2(textureCoords.xy - lightPositionOnScreen.xy);
deltaTexCoords *= 1.0 / float(NUM_SAMPLES) * density;
float illuminationDecay = 1.0;
// Evaluate summation from Equation 3 ( see https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_ch13.html) NUM_SAMPLES iterations.
for(int i = 0; i < NUM_SAMPLES; ++i) {
textureCoords.x = clamp(textureCoords.x, 0.0, 1.0);
textureCoords.y = clamp(textureCoords.y, 0.0, 1.0);
textureCoords -= deltaTexCoords;
vec4 occlusionSample = texture(occlusionTex, textureCoords);
float alpha = occlusionSample.r;
occlusionSample.r = 0.0;
occlusionSample.a = alpha;
occlusionSample *= illuminationDecay * weight;
FragColor += occlusionSample;
illuminationDecay *= decay;
}
FragColor *= exposure;
float alpha = clamp(1.0 - FragColor.a, 0.0, 1.0);
FragColor.a = 0.0;
FragColor.r = alpha;
}