Trên một trong các slide từ "DirectX 11 Rendering trong Battlefield 3" PowerPoint tôi nhận thấy mã folowing:
struct Light {
float3 pos; float sqrRadius;
float3 color; float invSqrRadius;
}
Tôi không hiểu tại sao họ sẽ lưu trữ bán kính bình phương và thậm chí cả bình phương nghịch đảo (mà tôi tin chỉ đơn giản là bán kính 1 bình phương) thay vì chỉ đơn giản là lưu trữ bán kính? Làm thế nào họ sử dụng dữ liệu này trong tính toán của họ? Hơn nữa, những gì về đèn hình nón và đèn đường? Cấu trúc này phải chỉ dành cho đèn điểm, tôi không thể thấy nó hoạt động cho các loại khác - không có đủ dữ liệu. Tuy nhiên, tôi rất muốn biết làm thế nào họ sử dụng hình vuông và invSapes.
CẬP NHẬT: Ok cuối cùng tôi đã nhận được nó.
Dưới đây là phương trình suy giảm ánh sáng cổ điển, dễ dàng tìm thấy trên mạng:
float3 lightVector = lightPosition - surfacePosition;
float attenuation = saturate(1 - length(lightVector)/lightRadius);
Nó tương đối tốn kém như length(lightVector)
thực sự làm điều này:
length(lightVector) = sqrt(dot(lightVector, lightVector);
hơn nữa hoạt động phân chia (/lightRadius)
cũng khá tốn kém.
Thay vì tính toán suy giảm ánh sáng theo cách này, bạn có thể tính toán theo cách sau, sẽ nhanh hơn nhiều:
attenuation = saturate(1 - dot(lightVector, lightVector)*invRadiusSqr);
trong đó invRadiusSqr có thể được tính toán trước ở mức CPU và được truyền dưới dạng hằng số shader.
Hơn nữa, kết quả là bạn bị suy giảm ánh sáng bậc hai (thay vì tuyến tính trong trường hợp trước), điều này thậm chí còn tốt hơn, vì ánh sáng IRL đã cho thấy có sự sụp đổ bậc hai.
Cảm ơn mọi người đã giúp đỡ!