Hi there,
I’m using OpenGL 3.3 core profile and lately created a deferred renderer which tries to output data to depth texture and 3 GL_RGBA16F textures at once. Unfortunately I’m having some issues…
- When I attach depth as a renderbuffer to the FBO, all 3 GL_RGBA16F targets are rendering without any problem. But because I need depth as a texture, so…
- I attached depth as a texture to the FBO, and suddenly all I can do is watch the depth buffer and first color attachment rendered correctly, but the second and third are completely black…
My question - Is it correct to assume that I can mix those textures types (GL_DEPTH_COMPONENT with GL_RGBA16F) as attachments for the same FBO?
PS. I know from a doc posted about Starcraft 2 shading that guys from blizzard used 4 MRT, all RGBA FP16… Starcraft 2 is a Windows and Mac release, so I assume that Windows part is DX code, but Mac is OpenGL based, thus there must be a way to do this, but the question is how? Any ideas, directions?
PS.2. I’m using Windows 7 x64 with Nvidia GTX 280, and latest drivers (280.26).
PS.3. The way I create the FBO
glGenFramebuffers(1, &_frame_id);
// First RGBA16F
glGenTextures(1, &tex_id1);
glBindFramebuffer(GL_FRAMEBUFFER, _frame_id);
glBindTexture(GL_TEXTURE_2D, tex_id1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, _width, _height, 0, GL_RGBA, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex_id1, 0);
// Second RGBA16F
glGenTextures(1, &tex_id2);
glBindFramebuffer(GL_FRAMEBUFFER, _frame_id);
glBindTexture(GL_TEXTURE_2D, tex_id2);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, _width, _height, 0, GL_RGBA, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, tex_id2, 0);
// Depth
glGenTextures(1, &tex_id3);
glBindFramebuffer(GL_FRAMEBUFFER, _frame_id);
glBindTexture(GL_TEXTURE_2D, tex_id3);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, _width, _height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, tex_id3, 0);
PS.4. vert & frag shaders
// Vertex shader
#version 330 core
#define POSITION 0
#define NORMAL 1
#define TEXCOORD 2
#define TANGENT 4
layout(location = POSITION) in vec4 Position;
layout(location = NORMAL) in vec3 Normal;
layout(location = TEXCOORD) in vec2 Texcoord;
layout(location = TANGENT) in vec4 Tangent;
uniform mat4 MVP;
uniform mat3 NM;
out block
{
vec2 Texcoord;
mat3 TBN;
} Out;
void main(void)
{
Out.Texcoord = Texcoord;
vec3 _normal = normalize(NM * Normal);
vec3 _tangent = normalize(NM * Tangent.xyz);
vec3 _binormal = normalize(-Tangent.w * cross(Normal, Tangent.xyz));
Out.TBN = mat3(_tangent.x, _binormal.x, _normal.x,
_tangent.y, _binormal.y, _normal.y,
_tangent.z, _binormal.z, _normal.z);
gl_Position = MVP * Position;
}
// Fragment shader
#version 330 core
#define POSITION 0
#define TEXCOORD 2
#define FRAG_COLOR 0
uniform sampler2D Diffuse;
uniform sampler2D Parallax;
in block
{
vec2 Texcoord;
mat3 TBN;
} In;
layout(location = FRAG_COLOR, index = 0) out vec4 outputColor[2];
void main(void)
{
vec4 normalMap = texture2D(Parallax, In.Texcoord);
vec3 n = normalize(2.0f * normalMap.rgb - 1.0f);
vec3 normal = n * In.TBN;
outputColor[0] = texture2D(Diffuse, In.Texcoord);
outputColor[1] = vec4(normalize(normal) * 0.5f + 0.5f, 1.0f);
}