“Battlefield 3의 DirectX 11 렌더링”PowerPoint의 슬라이드 중 하나에서 다음 코드를 발견했습니다.
struct Light {
float3 pos; float sqrRadius;
float3 color; float invSqrRadius;
}
왜 반경을 저장하는 대신 왜 제곱 반지름과 심지어 제곱 반지름 (단순히 제곱 반지름이라고 생각하는지)을 저장해야하는지 이해할 수 없습니까? 그들은이 데이터를 어떻게 계산에 사용합니까? 또한 콘 및 라인 라이트는 어떻습니까? 이 구조체는 포인트 라이트 전용이어야합니다. 다른 유형에서는 작동하지 않습니다. 데이터가 충분하지 않습니다. 아직도 나는 그들이 그 광장과 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은 CPU 레벨에서 사전 계산되어 쉐이더 상수로 전달 될 수 있습니다.
또한, 결과적으로 (이전의 경우 선형 대신) 2 차 광 감쇠가 발생하는데, IRL 광이 2 차 감쇠를 갖는 것으로보다 우수합니다.
도와 주셔서 감사합니다!
답변
이것은 단순히 invSqrRadius = 1/SqrRadius
빛을 캐싱 할 때마다 각 조명에 대해 반 제곱 반경을 계산하는 대신 곱셈과 비교할 때 적어도 나눗셈이 “느린”연산이기 때문에 일종의 최적화 입니다.
이 최적화는 특히 다음과 관련이 있습니다.
- 각 조명에 대해 작업이 많이 수행되면 값을 캐싱하면 추가 CPU / GPU주기가 해제됩니다.
- 그리고 값을 읽는 데 필요한 메모리 액세스 시간이 실제로는 다시 계산하는 것보다 빠르다고 가정하십시오.
그것이 어떻게 사용되는지에 관해서는, 나는 그들의 특정 구현에 대해서는 확신하지 못하지만에 관해서 1/sqrRadius
는 단순히 빛 감쇠, 감쇠 및 컬링에 사용됩니다. 방향성 및 스포트라이트와도 관련이 있습니다. 스포트라이트의 경우 유일한 차이점 은 감쇠를 적용한 후 스포트라이트 계수를 계산해야한다는 것 입니다. 태양과 같은 방향성 조명과 관련하여 일반적으로 감쇠 또는 감쇠가 없으므로 무시됩니다.
[편집] 더 자세히 설명하기 위해 관련성이없는 데이터 는 아닙니다 . 빛의 조도는 다음 방정식을 사용하여 계산할 수 있습니다.
E = Phi / 4 * pi * rSqr;
어디
E 는 플럭스의 면적 밀도입니다.
Phi 는 래디언스 플럭스입니다.
4 * pi * rSqr 은 구의 표면적입니다.
이 방정식은 수신 된 에너지의 양이 제곱 거리로 떨어지는 이유를 설명합니다.
또 다른 요점은 특정 정점에 대한 빛의 기여도를 계산하기 위해 정점과 빛 사이의 거리를 계산해야한다는 것입니다 (이 값은 캐시되지 않을 것입니다). 정점은 빛의 범위 내외부에서 다음 지점으로 인도 할 수 있습니다 어디 Radius Square
컬링 유용합니다.
라이트 폴 오프 및 컬링을 계산하기위한 실제적인 예를 원한다면, 이는 타일 기반 지연 렌더러에서 특히 유용합니다. 여기에 하나의 예가 있습니다.
답변
invSqrRadius는 1이 아닙니다-sqrRadius; 1 / sqrRadius입니다.
이는 sqrRadius로 나누지 않고 invSqrRadius를 곱할 수 있음을 의미합니다 (나눗셈은 곱셈보다 훨씬 비쌉니다).
답변
여기에있는 다른 대답은 역 제곱 반경을 다루었지만 대신 제곱 반경을 살펴 보겠습니다 (concept3d가 터치했지만 추가 토론이 필요하다고 생각합니다).
유용한 제곱은 거리 비교입니다. 우리는 두 점 사이의 거리를 계산하는 데 제곱근이 포함되며, 제곱근은 계산 비용이 많이 들지만, 원하는 경우 거리를 비교 하는 것입니다 하는 것입니다 (어느거나 더 작은 것을 찾기 위해 결과) 우리는 제곱근을 버릴 수 있습니다.
sqrt (x)> sqrt (y)이면 x> y의 경우이기도합니다.
라이트의 경우, 제곱 반경은 라이트의 중심과 최대 범위 사이의 거리와 동일합니다. 물론 제곱입니다.
조명 계산의 경우 초기 사례에 사용할 수 있습니다. 조명하고있는 점과 조명의 중심 (제곱) 사이의 거리가 제곱 반경보다 크면 점이 빛을받지 않으므로 나머지 계산을 실행할 필요가 없습니다. 그러므로 이것은 단지 최적화 일뿐입니다 (비교적입니다). 우리는 제곱 반경을 사용하여 값 비싼 제곱근없이 거리를 비교하고 뺄셈과 내적의 대가를 치를 수 있습니다.
물론 이것이 BF3가 그것을 사용하고 있는지 정확히 알지 못하지만 마크에서 너무 멀지 않을 것으로 기대합니다.