The general idea is calculate light in “tangent bitangent normal” (TBN) space.
It lets us avoid transformation of normals to worl space in fragment shader:
- calculate TBN matrix
- calculate inverse matrix from TBN
- transform lightDir and viewDir to TBN space
- we can calculate all stuff in TBN space having transformed lightDir and viewDir.
Full description located here.
The question is:
I’m using several light sources: sun, several point light and several spot lights.
Is there a method to provide variable number of light parameters from VS to FS?
Especially if my engine using ‘deferred shading’, so I’m must provide lights info through textures or SSBO.
Thanks for any help!
Fragment shader inputs can be arrays, but the array must be explicitly sized. The vertex and fragment shaders can write and read a dynamic subset of entries, but all entries will be interpolated. Alternatively, you can re-compile the shader program if the array size changes.
From a performance standpoint, if you have multiple lights you’d probably be better off just passing the T,B,N vectors from the vertex shader to the fragment shader and transforming the values from the normal map into world space. If you only have one light, surface-space lighting means that you only need to interpolate two vectors rather than three. World-space lighting also enables the use of lighting maps for static lights.
GClements, seems you prevented me waste a some time for a bad improvement.
One more reason is ‘Deferred shading’: too many VS calls on ‘g-buffer render pass’ and not many FS calls on ‘screen render pass’.
Thank you a lot!