In my simple renderer, I have 2 FBOs one that contains diffuse, normals, instance ID and depth in that order and one that I use store the ssao result. The textures I use for the first FBO are RGB8, RGBA16F, R32I and GL_DEPTH_COMPONENT32F for the depth. For the second FBO I use an R16F texture. My rendering process is to first render to everything I mentioned in the first FBO, then bind depth and normals textures for reading for the ssao pass and write to the second FBO. After that I bind the second FBO's texture for reading in my blur shader and bind the first FBO for writing. What I intend to do is to write the blurred ssao value to the alpha component of the Normals texture.
Here are where the problems start. First of all, I use shading language 3.3, which my graphics card does support. I manage ouputs in my shaders using layout(location = #). Now, the normals texture should be bound to color attachment 1, but when I use 1, it seems to write to my diffuse texture which should be in color attachment 0. When I instead use layout(location = 0), it gets correctly written to my normals texture. Besides this, my instance ID texture also gets resets after running the blur shader which is weird because if I use a float texture and write to it instanceID / nInstances, the texture doesn't get reset after the blur shader has ran.
Here is how I prepare my first FBO:
bool CGBuffer::Init(unsigned int WindowWidth, unsigned int WindowHeight){
//Create FBO
glGenFramebuffers(1, &m_fbo);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo);
//Create gbuffer and Depth Buffer Textures
glGenTextures(GBUFF_NUM_TEXTURES, &m_textures[0]);
glGenTextures(1, &m_depthTexture);
//prepare gbuffer
for(unsigned int i = 0; i < GBUFF_NUM_TEXTURES; i++){
glBindTexture(GL_TEXTURE_2D, m_textures[i]);
if(i == GBUFF_TEXTURE_TYPE_NORMAL) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, WindowWidth, WindowHeight, 0, GL_RGBA, GL_FLOAT, NULL);
else if(i == GBUFF_TEXTURE_TYPE_DIFFUSE) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, WindowWidth, WindowHeight, 0, GL_RGB, GL_FLOAT, NULL);
else if(i == GBUFF_TEXTURE_TYPE_ID) glTexImage2D(GL_TEXTURE_2D, 0, GL_R32I, WindowWidth, WindowHeight, 0, GL_RED_INTEGER, GL_INT, NULL);
else{
std::cout << "Error in FBO initialization" << std::endl;
return false;
}
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, m_textures[i], 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
}
//prepare depth buffer
glBindTexture(GL_TEXTURE_2D, m_depthTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, WindowWidth, WindowHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_depthTexture, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
GLenum DrawBuffers[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2};
glDrawBuffers(GBUFF_NUM_TEXTURES, DrawBuffers);
GLenum Status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if(Status != GL_FRAMEBUFFER_COMPLETE){
std::cout << "FB error, status 0x" << std::hex << Status << std::endl;
return false;
}
//Restore default framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, 0);
return true;
}
where I use an enum defined as,
enum GBUFF_TEXTURE_TYPE{
GBUFF_TEXTURE_TYPE_DIFFUSE,
GBUFF_TEXTURE_TYPE_NORMAL,
GBUFF_TEXTURE_TYPE_ID,
GBUFF_NUM_TEXTURES
};
Am I missing some kind of restriction? Does the color attachment of the FBO's textures somehow gets reset i.e. I'm using a re-size function which re-sizes the textures of the FBO but should I perhaps call glFramebufferTexture2D again too?
EDIT: Here is the shader in question:
#version 330 core
uniform sampler2D aoSampler;
uniform vec2 TEXEL_SIZE; // x = 1/res x, y = 1/res y
uniform bool use_blur;
noperspective in vec2 TexCoord;
layout(location = 0) out vec4 out_AO;
void main(void){
if(use_blur){
float result = 0.0;
for(int i = -1; i < 2; i++){
for(int j = -1; j < 2; j++){
vec2 offset = vec2(TEXEL_SIZE.x * i, TEXEL_SIZE.y * j);
result += texture(aoSampler, TexCoord + offset).r; // -0.004 because the texture seems to be a bit displaced
}
}
out_AO = vec4(vec3(0.0), result / 9);
}
else out_AO = vec4(vec3(0.0), texture(aoSampler, TexCoord).r);
}