I have been reading up on deferred rendering and I am trying to implement a renderer using the Sponza atrium model, which can be found here, as my sandbox.Note I am also using OpenGL 3.3 and GLSL. I am loading the model from a Wavefront OBJ file using Assimp. I extract all geometry information including tangents and bitangents. For all the aiMaterials,I extract the following information which essentially comes from the sponza.mtl file.

  • Ambient/Diffuse/Specular/Emissive Reflectivity Coefficients(Ka,Kd,Ks,Ke)

  • Shininess

  • Diffuse Map

  • Specular Map

  • Normal Map

    I understand that I must render vertex attributes such as position ,normals,texture coordinates to textures as well as depth for the second render pass. A lot of resources mention putting colour information into a g-buffer in the initial render pass but do you not require the diffuse,specular and normal maps and therefore lights to determine the fragment colour? I know that doesnt make since sense because lighting should be done in the second render pass.

In terms of normal mapping, do you essentially just pass the tangent,bitangents, and normals into g-buffers and then construct the tangent matrix and apply it to the sampled normal from the normal map.

Ultimately, I would like to know how to incorporate this material information into my deferred renderer.

  • 2
    \$\begingroup\$ No... you do not cram the TBN matrix into your G-Buffer. You have to sample the normal in tangent-space and then transform it to world/view-space before you write it to the G-Buffer. This is why many deferred rendering engines talk about the merits of storing normals in world or view-space. I prefer world-space, as do CryTek and Epic. In any case, lighting absolutely cannot be done in tangent-space in a deferred engine, you lack too much information to transform everything into that coordinate space and writing the matrix necessary would waste ridiculous amounts of storage / bandwidth. \$\endgroup\$ May 6, 2014 at 19:30
  • \$\begingroup\$ Ok so if I understand correctly,do I need to then transform the tangent, bitangent, and vertex normals to view space and then construct the TBN matrix using these vectors? Using that then, do I simply just say "vec3 finalNormal = TBN * texture(NormalSampler,TexCoord).xyz;" to get the final "bumped" normal to store in my G-Buffer? \$\endgroup\$
    – John
    May 7, 2014 at 23:07
  • 2
    \$\begingroup\$ Yes, that will transform the normals out of tangent-space and into a different space. The term TBN is pretty vague though, by itself that matrix transforms into object-space, but a lot of people will multiply the matrix by their ModelView matrix to make it transform straight into view-space. \$\endgroup\$ May 7, 2014 at 23:09

1 Answer 1


Each parameter necessary to the final color of a fragment must be saved in the so called "G-Buffer". So you would have one Render Target for each of those parameters: Diffuse, Specular, Normals, Position (or depth), UVs and so on. This is the reason why deferred rendering is so memory intensive. And, in my opinion, it is only viable if the hardware has support for MRT (Multiple Render Targets). Otherwise you would have to do one pass to each of those parameters anyway.

Take a look at the tutorials on OGLDev. These are probably the most popular ones out there. I think you can get a solid understanding of the technique from there.


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .