Auf einer der Folien aus PowerPoint "DirectX 11-Rendering in Battlefield 3" ist mir der folgende Code aufgefallen:
struct Light {
float3 pos; float sqrRadius;
float3 color; float invSqrRadius;
}
Ich verstehe nicht, warum sie den quadratischen Radius und sogar das inverse Quadrat (von dem ich glaube, dass es einfach ein Quadrat ist) speichern, anstatt einfach den Radius zu speichern? Wie verwenden sie diese Daten in ihren Berechnungen? Und was ist mit Kegel- und Linienlichtern? Diese Struktur muss nur für die Punktlichter sein, ich kann nicht sehen, dass sie für andere Typen funktioniert - es sind nicht genügend Daten vorhanden. Trotzdem würde ich gerne wissen, wie sie dieses Quadrat und invSquare verwenden.
UPDATE: Ok, ich habe es endlich verstanden.
Hier ist die klassische Lichtdämpfungsgleichung, die im Netz leicht zu finden ist:
float3 lightVector = lightPosition - surfacePosition;
float attenuation = saturate(1 - length(lightVector)/lightRadius);
Es ist relativ kostspielig, wie dies length(lightVector)
tatsächlich tut:
length(lightVector) = sqrt(dot(lightVector, lightVector);
Darüber hinaus ist die Aufteilung (/lightRadius)
auch recht kostspielig.
Anstatt die Lichtabschwächung auf diese Weise zu berechnen, können Sie sie folgendermaßen berechnen, was viel schneller wäre:
attenuation = saturate(1 - dot(lightVector, lightVector)*invRadiusSqr);
Dabei kann invRadiusSqr auf CPU-Ebene vorberechnet und als Shader-Konstante übergeben werden.
Darüber hinaus erhalten Sie als Ergebnis eine quadratische Lichtabschwächung (im ersten Fall nicht linear), was sogar noch besser ist, da IRL-Licht eine quadratische Abschwächung aufweist.
Vielen Dank für Ihre Hilfe!