Na jednym ze slajdów z „DirectX 11 Rendering in Battlefield 3” PowerPoint zauważyłem następujący kod:
struct Light {
float3 pos; float sqrRadius;
float3 color; float invSqrRadius;
}
Nie rozumiem, dlaczego mieliby przechowywać kwadratowy promień, a nawet odwrotny kwadrat (który moim zdaniem jest po prostu promieniem 1-kwadratowym) zamiast po prostu przechowywać promień? Jak wykorzystują te dane w swoich obliczeniach? A co z lampkami stożkowymi i liniowymi? Ta struktura musi być tylko dla świateł punktowych, nie widzę, aby działała dla innych typów - nie ma wystarczającej ilości danych. Nadal chciałbym wiedzieć, jak używają tego kwadratu i invSquare.
AKTUALIZACJA: Ok, w końcu to rozumiem.
Oto klasyczne równanie tłumienia światła, które można łatwo znaleźć w sieci:
float3 lightVector = lightPosition - surfacePosition;
float attenuation = saturate(1 - length(lightVector)/lightRadius);
Jest to stosunkowo kosztowne, ponieważ length(lightVector)
faktycznie robi to:
length(lightVector) = sqrt(dot(lightVector, lightVector);
ponadto operacja podziału (/lightRadius)
jest również dość kosztowna.
Zamiast obliczać tłumienie światła w ten sposób, możesz obliczyć go w następujący sposób, co byłoby znacznie szybsze:
attenuation = saturate(1 - dot(lightVector, lightVector)*invRadiusSqr);
gdzie invRadiusSqr można wstępnie obliczyć na poziomie procesora i przekazać jako stałą modułu cieniującego.
Ponadto uzyskuje się w ten sposób kwadratowe tłumienie światła (zamiast liniowego w poprzednim przypadku), co jest jeszcze lepsze, ponieważ światło IRL wykazuje kwadratowy spadek światła.
Dziękuję wszystkim za pomoc!