На одному із слайдів PowerPoint "DirectX 11 Rendering in Battlefield 3" я помітив наступний код:
struct Light {
float3 pos; float sqrRadius;
float3 color; float invSqrRadius;
}
Я не розумію, чому б вони зберігали радіус квадрата і навіть зворотний квадрат (який я вважаю просто радіусом 1 квадрата), а не просто зберігати радіус? Як вони використовують ці дані у своїх розрахунках? Більше того, що з конусними та лінійними фарами? Ця структура повинна бути тільки для точкових вогнів, я не можу бачити, як вона працює для інших типів - немає обґрунтованих даних. Ще я хотів би знати, як вони використовують цю площу та invSquare.
ОНОВЛЕННЯ: Добре, я нарешті зрозумів.
Ось класичне рівняння загасання світла, яке легко знайти в мережі:
float3 lightVector = lightPosition - surfacePosition;
float attenuation = saturate(1 - length(lightVector)/lightRadius);
Це порівняно дорого, як length(lightVector)
це відбувається насправді:
length(lightVector) = sqrt(dot(lightVector, lightVector);
до того ж, операція відділення (/lightRadius)
також досить дорога.
Замість обчислення ослаблення світла таким чином, ви можете обчислити його наступним чином, що було б набагато швидше:
attenuation = saturate(1 - dot(lightVector, lightVector)*invRadiusSqr);
де invRadiusSqr можна заздалегідь обчислити на рівні процесора і передати як константу шейдера.
Більше того, ви отримуєте квадратичне загасання світла в результаті (замість лінійного в колишньому випадку), що ще краще, оскільки світло ІРЛ показав квадратичне випадання.
Дякую всім за допомогу!