In una delle diapositive di "Rendering DirectX 11 in Battlefield 3" PowerPoint ho notato il seguente codice:
struct Light {
float3 pos; float sqrRadius;
float3 color; float invSqrRadius;
}
Non capisco perché dovrebbero memorizzare il raggio quadrato e persino il quadrato inverso (che credo sia semplicemente un raggio di 1 quadrato) invece di memorizzare semplicemente il raggio? Come stanno usando questi dati nei loro calcoli? Inoltre, che dire delle luci a cono e linea? Questa struttura deve essere solo per i punti luce, non riesco a vederlo funzionare per altri tipi - non ci sono abbastanza dati. Mi piacerebbe comunque sapere come usano quel quadrato e invSquare.
AGGIORNAMENTO: Ok finalmente ho capito.
Ecco la classica equazione di attenuazione della luce, facilmente reperibile in rete:
float3 lightVector = lightPosition - surfacePosition;
float attenuation = saturate(1 - length(lightVector)/lightRadius);
È relativamente costoso come length(lightVector)
sta effettivamente facendo questo:
length(lightVector) = sqrt(dot(lightVector, lightVector);
inoltre l'operazione di divisione (/lightRadius)
è anche piuttosto costosa.
Invece di calcolare l'attenuazione della luce in questo modo, puoi calcolarla nel modo seguente, che sarebbe molto più veloce:
attenuation = saturate(1 - dot(lightVector, lightVector)*invRadiusSqr);
dove invRadiusSqr può essere pre-calcolato a livello di CPU e passato come costante shader.
Inoltre, di conseguenza si ottiene un'attenuazione della luce quadratica (anziché lineare nel primo caso), il che è ancora meglio, poiché la luce IRL ha dimostrato di avere un decadimento quadratico.
Grazie a tutti per il vostro aiuto!