На одном из слайдов «Рендеринг DirectX 11 в Battlefield 3» в PowerPoint я заметил следующий код:
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 может быть предварительно вычислен на уровне процессора и передан как константа шейдера.
Более того, в результате вы получаете квадратичное затухание света (вместо линейного в первом случае), что даже лучше, поскольку свет IRL показал квадратичный спад.
Спасибо всем за вашу помощь!