# TBN matrix construction in geometry shader

I accidentally clicked somewhere on opengl.org homepage and this NVidia presentation came up http://nvidia.fullviewmedia.com/GPU2009/0930-gold-1407.html.

The point I was quite interested about is the TBN reconstruction within geometry shaders.

Has anyone tried to do something like that? Does it work acceptably from the performance standpoint?

I’m calculating it inside the frag-shader, and isn’t a major performance bottleneck

The idea sounds cool and should work much faster than Ilian’s approach.
However, I advice to supply full tangent space basis instead of a normal per vertex (either normal+tangent or a single quaternion).
Firstly, it more control of your tangent space.
Secondly, one day 3D editors will supply us with tangents along with normals, which can differ from the ones you calculate, what will result in the incorrect rendering.

My reasoning for shoving the calculation in the frag-shader, is for easier balancing of the load. (making the load fairly constant, regardless of scene complexity). [ variates usually up to 8x minimum load ] . Making triangles and vertices as cheap as possible, while making visible pixels (fragments that will contribute) expensive. Provided that there’s a z-pass, of course.
My whole idea could be rendered useless and impractical with occlusion-queries for nice culling.

I see your point. I’m using many geometry passes as well trying to minimize the vertex processing cost.
However passing a quaternion or normal+tangent to a fragment shader (if not deriving in VS/GS) is free comparing to generation TBN in FS. You need the correct normal anyway, so I don’t see any advantages.
(I’m not going deep into each way issues for now)

I use a GS to generate a per-triangle tangent basis for debugging purposes (visualizing T/B as two lines in the center of the triangle), so I do not really use the GS-calculated TBN for lighting (yet), but I propose the following:
Provide a vertex normal as usual, calculate tangent/bitangent in the GS and align T/B to the vertexnormal of each input vertex. In the Fragmentshader, transform L and H into your tangent basis (or transform the normalmap-normal into the other space). And do the lighting.
This has the advantage that you don’t need to do expensive precalculation of T/B which takes care of a) correctly averaging T/B and b) fixing texture mirror seams; which in turn also saves duplicates vertices.