On one of the slides from "DirectX 11 Rendering in Battlefield 3" PowerPoint I noticed the folowing code:
struct Light {
float3 pos; float sqrRadius;
float3 color; float invSqrRadius;
}
I don't understand why would they store the squared radius and even the inverse squared (which I believe is simply 1-squared radius) instead of simply storing the radius? How are they using this data in their computations? Moreover, what about cone and line lights? This struct must be only for the point lights, I can't see it working for other types - there is not enought data. Still I would love to know how they use that square and invSquare.
UPDATE: Ok I finally got it.
Here is the classic light attenuation equation, easily found on the net:
float3 lightVector = lightPosition - surfacePosition;
float attenuation = saturate(1 - length(lightVector)/lightRadius);
It is relatively costly as length(lightVector)
is actually doing this:
length(lightVector) = sqrt(dot(lightVector, lightVector);
moreover division operation (/lightRadius)
is also quite costly.
Instead of computing light attenuation this way, you can compute it the following way, which would be much faster:
attenuation = saturate(1 - dot(lightVector, lightVector)*invRadiusSqr);
where invRadiusSqr can be pre-computed at CPU level and passed as a shader constant.
Moreover, you get a quadratic light attenuation as a result (instead of linear in the former case), which is even better, as IRL light has shown to have quadratic falloff.
Thanks everyone for your help!