We usually have vertex format that contains position, texture, normal and tangent (sometimes even bitangent). And we also have object matrix and a normal matrix (inverse transpose).
This seems very excessive.
Wouldn't it be better to just have tangent and bitangent and have only regular position matrix? Then normal can be calculated as cross product of transformed tangent and bitangent. No need for storing vertex normal and having that extra inversed transposed matrix per object.
Or even better, if we don't use skew in the matrix transformations (but we do non-uniform scale), we can just use regular matrix but in the fourth column just store squared inverse matrix scale vector which is multiplied via normal before it is transformed with regular matrix (to double compensate for the wrong non-uniformn scaling). This can also be improved by dividing scale with one of the scaling component (like Z) and then we only have to store two scale factor X/Z and Y/Z in the fourth column and we are left with two extra spare places in the 4x4 matrix ( 34 and 44 element) which can be used for storing some color or some custom object information.
One other thing: why are we even using 4x4 matrices? We only need them from projection and that can be done via a single MAD command if projection data is stored in a float4((tanX, tanY, zn, 1) vector: float4 Project(float3 p) { return mad(p.xyzz, float4(_vProj.xy, 0, 1), float4(0,0,_vProj.z,0)); }
So my question is: why are all the samples all over the internet using inefficient vertex formats and normal matrices? Or did I get something wrong?