When I try to render a framebuffer to a texture to use it in a post-process shader, I get a black screen.
Here’s how I initialize my framebuffers (called once at the beginning of the program):
//Init shadow buffer stuff
glGenFramebuffers(2,fbufId);
glGenTextures(2,&texId[15]);
glBindFramebuffer(GL_FRAMEBUFFER,fbufId[0]);
glActiveTexture(GL_TEXTURE5);
glBindTexture(GL_TEXTURE_2D,texId[15]);
glTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT32,1024,1024,0,GL_DEPTH_COMPONENT,GL_FLOAT,0);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_COMPARE_FUNC,GL_LEQUAL);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_COMPARE_MODE,GL_COMPARE_R_TO_TEXTURE);
glFramebufferTexture(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,texId[15],0);
glDrawBuffer(GL_NONE);
glBindFramebuffer(GL_FRAMEBUFFER,fbufId[1]);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,texId[16]);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,1024,1024,0,GL_RGBA,GL_UNSIGNED_BYTE,0);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
glFramebufferTexture(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,texId[16],0);
glDrawBuffer(GL_COLOR_ATTACHMENT0);
Here’s how I render my scene:
//Setup shadow pass
glBindFramebuffer(GL_FRAMEBUFFER,fbufId[0]);
glViewport(0,0,1024,1024);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glUseProgram(prgId[0]);
glm::mat4 view = glm::lookAt(u_LightDir+p->Position,p->Position,glm::vec3(0,1,0));
glm::mat4 proj = glm::ortho(-20.f,20.f,-20.f,20.f,0.f,1000.f);
//Render objects to shadow map
//...
//Setup normal pass
glBindFramebuffer(GL_FRAMEBUFFER,fbufId[1]);
glViewport(0,0,1024,1024);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glUseProgram(prgId[1]);
glUniform3f(texId[6],u_LightDir.x,u_LightDir.y,u_LightDir.z);
glUniform3f(texId[7],u_CameraPos.x,u_CameraPos.y,u_CameraPos.z);
glm::mat4 u_ViewProj = u_Projection*u_View;
glUniformMatrix4fv(texId[9],1,GL_FALSE,&u_ViewProj[0][0]);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glEnableVertexAttribArray(4);
//Render objects to screen
//...
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
glDisableVertexAttribArray(6);
glDisableVertexAttribArray(7);
//Setup post-process pass
glBindFramebuffer(GL_FRAMEBUFFER,0);
glViewport(0,0,WindowWidth,WindowHeight);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glUseProgram(prgId[2]);
glUniform1f(texId[11],1);
glUniform1f(texId[12],0);
glUniform4f(texId[13],1,1,1,1);
glBindBuffer(GL_ARRAY_BUFFER,vboId[0]);
glBufferData(GL_ARRAY_BUFFER,48,trVertexBuffer,GL_STATIC_DRAW);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,0);
glBindBuffer(GL_ARRAY_BUFFER,vboId[4]);
glBufferData(GL_ARRAY_BUFFER,32,trUVBuffer,GL_STATIC_DRAW);
glVertexAttribPointer(4,2,GL_FLOAT,GL_FALSE,0,0);
glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_SHORT,trIndexBuffer);
glUniform1f(texId[11],0);
//Render texrects
//...
glDisableVertexAttribArray(4);
glEnableVertexAttribArray(6);
glEnableVertexAttribArray(7);
//Swap buffers
glutSwapBuffers();
Here’s my post process shader:
VERTEX:
#version 330 core
layout(location=0) in vec3 a_Position;
layout(location=4) in vec2 a_UV;
layout(std140) uniform u_VertexShaderData
{
mat4 u_PositionMtx;
mat4 u_NormalMtx;
mat4 u_ShadowBias;
mat4 u_Bones[28];
mat4 u_NormalBones[28];
};
uniform vec3 u_CameraPosition;
out vec4 o_Position;
out vec2 o_UV;
out vec3 o_ViewDir;
void main()
{
o_Position = vec4(a_Position,1.0);
o_UV = a_UV;
o_ViewDir = a_Position-((u_PositionMtx*vec4(u_CameraPosition,1.0)).xyz);
}
FRAGMENT:
#version 330 core
in vec4 o_Position;
in vec2 o_UV;
in vec3 o_ViewDir;
const float u_EnvSize = 7.0;//9.0;
uniform vec2 u_Resolution;
uniform samplerCube u_Radiance;
uniform sampler2D u_Albedo;
uniform float u_EnvMapFactor;
uniform float u_EnvMapRoughness;
uniform vec4 u_FadeColor;
out vec4 o_FragColor;
vec3 sampleHDR(vec4 c)
{
return vec3(c.rgb*exp2((c.a*255.0)-128.0));
}
void main()
{
o_FragColor = texture(u_Albedo,o_UV);
}
I have verified that my code works correctly when I omit the third shader pass (that is, I replace fbufId[1]
with 0
, and cut out everything in regards to the post-process pass, except for attribute enable/disable commands).