Em um dos slides do PowerPoint "Renderização do DirectX 11 no Battlefield 3", observei o código a seguir:
struct Light {
float3 pos; float sqrRadius;
float3 color; float invSqrRadius;
}
Não entendo por que eles armazenariam o raio ao quadrado e até o inverso ao quadrado (que acredito ser apenas um raio ao quadrado) em vez de simplesmente armazenar o raio? Como eles estão usando esses dados em seus cálculos? Além disso, e as luzes de cone e linha? Essa estrutura deve ser apenas para as luzes de ponto, não consigo vê-la funcionando para outros tipos - não há dados suficientes. Ainda assim, eu gostaria de saber como eles usam esse quadrado e o invSquare.
ATUALIZAÇÃO: Ok, finalmente entendi.
Aqui está a equação clássica de atenuação da luz, facilmente encontrada na rede:
float3 lightVector = lightPosition - surfacePosition;
float attenuation = saturate(1 - length(lightVector)/lightRadius);
É relativamente caro, pois length(lightVector)
está realmente fazendo isso:
length(lightVector) = sqrt(dot(lightVector, lightVector);
além disso, a operação de divisão (/lightRadius)
também é bastante cara.
Em vez de calcular a atenuação da luz dessa maneira, você pode calculá-la da seguinte maneira, o que seria muito mais rápido:
attenuation = saturate(1 - dot(lightVector, lightVector)*invRadiusSqr);
onde invRadiusSqr pode ser pré-calculado no nível da CPU e passado como uma constante de sombreador.
Além disso, você obtém uma atenuação quadrática da luz como resultado (em vez de linear no primeiro caso), o que é ainda melhor, pois a luz IRL demonstrou ter queda quadrática.
Obrigado a todos por sua ajuda!