Notice
Recent Posts
Recent Comments
Link
반응형
«   2026/01   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

RenderLog

[번역][Nvidia White Paper] Volume Light 본문

Graphics/참고자료

[번역][Nvidia White Paper] Volume Light

scahp 2020. 5. 28. 01:17

개인 공부용으로 번역한 거라 잘못 번역된 내용이 있을 수 있습니다.

또한 원작자의 동의 없이 올려서 언제든 글이 내려갈 수 있습니다.

출처 : http://developer.download.nvidia.com/SDK/10.5/direct3d/Source/VolumeLight/doc/VolumeLight.pdf

 

Nvidia White Paper

Volume Light 

 

Abstract

Volume Light 기술은 실제 세계의 라이트 스케터링(빛의 산란) 효과의 간단한 근사로 볼 수 있습니다. 작은 입자들은, 공기중에 뿌려진, Light 빔(beam)과 상호작용하고 무지개나 Sun shafts 와 같은 여러 효과를 생성해냅니다. Volumetric 효과들은 전통적으로 계산상 무겁다고 생각해왔습니다, 그러나 리얼타임에서는 근사가 가능합니다. 대부분의 경우 설득력 있는 모습이 끊임없이 장면에 통합되는 보기 좋은 효과에 의해 얻어질 수 있습니다. 그래서, Volumetric light는 물리적으로 정확한 시뮬레이션이기 보다는 시각적 효과가 될 것입니다.

 

 

 

 


How Volume Light Works

우리 기술의 최종 목적은 현실의 라이트 스케터링의 Volumetric 모습을 생성하는 것입니다.
우리는 light space의 shadow map과 depth 버퍼를 Volume Light 기술의 입력들로 사용합니다. Near clip 평면에서 시작하여, 우리는 전체 장면을 추적하고 샘플링 값을 누적시킵니다. 각각의 샘플에 대해서 라이트에 의해서 빛을 받는지 아닌지를 판단합니다. (Shadow map 값들의 비교를 기반으로). 주목할 점은, 빛을 받고 있는 샘플들은 픽셀 컬러의 결과에 최종 영향을 줍니다.

 

 

 

 

 


실제로, 우리는 장면 오브젝트와의 첫번째 상호작용까지만 추적 할 필요가 있습니다. 이것을 찾기 위해서, 우리는 장면의 Depth buffer를 사용합니다.
Fullscreen quad를 그리면, 우리는 각각의 Fragment에 대해서 월드 공간의 위치를 아래 코드로 복원할 수 있습니다:

 

 

 

 

장면을 추적하면, 우리는 Shadow map 비교에 기반하여 버퍼에서 빛을 받은 샘플들을 누적합니다.

 

 

 

 

 


빛을 받은 샘플들의 수에 따라서, 우리는 스크린 픽셀의 최종 강도를 계산합니다.
이것으로, 우리는 light shafts visible을 만들 수 있습니다.

 

 

 

 

 


이 기본 구조는 작동합니다, 그러나 우리는 시각적 품질과 퍼포먼트 측면에서 더 나아지도록 만들기 위해서 몇가지 변화를 소개할 필요가 있습니다.
첫 최적화 스텝은 Coarse 해상도인 Whole volume light texture를 렌더링하는 것일 수 있습니다. Volume light shafts는 여러번의 스케터링 이벤트로 인해서 자연적으로 많은 내부 대조(Internal constrast)를 가지고 있지 않습니다. 그래서, 실제로는, 우리는 버퍼를 다운샘플링하고 좋은 품질의 결과를 얻을 수 있습니다. 실제로는, 버퍼는 각 면에 대해서 4배의 다운샘플이 될 수 있습니다. 더 높은 값은 세부사항과 시각적으로 앨리어싱을 만듭니다.

 

Scene Integration

메인장면과 함께 Volume light texture의 다운샘플된 것을 조합하길 원한다면, 우리는 앨리어싱 문제를 만납니다. Coarse texture의 가장자리가 원본장면에서 맞지 않습니다, 그래서 우리는 여기서 몇가지 전처리가 필요합니다.

 

 

 

원본 업샘플된 볼륨 라이트 텍스쳐

 

 


높은 강도의 변화가 있는 영역은 기본적으로 장면의 가장자리에서 나타납니다, 그곳은 보통 depth가 불연속(Discontinuities)입니다. 우리는 이 사실을 사용하고 더 좋게 보이도록 할 수 있습니다.
우리는 가장자리를 검출하는데 Sobel 필터를 사용합니다. 이것을 가능한 많은 디테일을 얻기 위해서 원본 depth 버퍼에 적용합니다. Volume light texture 이미지에 앨리어싱을 줄이기 위해서 가장자리를 따라서 업샘플링 합니다.

 

 

5x5 필터 커널. 가장자리 방향은 float2(Gx, Gy)로 정의되어 집니다.
가장자리가 블러 처리된 업샘플링 텍스쳐

 

 


Optimized Tracing

장면을 더 빠르게 탐색하기 위해서, 우리는 가변 샘플링 단계(Step) 크기를 Shadow map의 계층에따라 사용합니다. 우리는 2-Component MIP-level 체인을 만듭니다. 픽셀의 각 Quad에 대해서 우리는 최소와 최대 depth 값과 분리된 텍스쳐에 그들을 저장합니다. Coarse MIP-level을 사용하여, 우리는 같은 텍셀을 참조하는 모든 샘플이 라이트를 받는가 혹은 그림자를 드리우는가 여부를 예측할 수 있습니다.
만약 여러 개의 샘플들이 같은 텍셀을 참조한다면, 우리는 그들의 Light space depth 최대값을 계산할 수 있고 최소값이 저장된 2-Component texture과 비교할 수 있습니다. 만약 최소 값이 텍스쳐에 있는 값보다 작다면, 모든 샘플은 라이트를 받습니다.
그래서, 우리는 간단히 여러 개의 샘플을 한번에 확인할 수 있습니다. 같은 로직을 모든 샘플이 그림자가 드리운지를 결정하는데도 사용할 수 있습니다.

 

 

 

만약 우리가 Coarse step을 수행하고 시작과 끝점들이 최소 깊이 값에 비해 더 작다면, 모든 중간에 있는 샘플 값들 또한 라이트를 받습니다.

 

 

아래의 간단한 코드로 우리가 Coarse step을 할 수 있다면, 우리는 이것을 판단할 수 있습니다.

 

 

 

 


Visual Quality

현재 접근은 볼륨 내부에서 균일한(Uniform) 라이트 스케터링 가정합니다. 그러나 실제 세계에서는 그렇지 않습니다. 입자들의 분포(Distribution)가 균일하지 않습니다, 그리고 여러 스케터링이 라이트 분포 벡터를 따라서 라이트의 강도를 감소시킵니다. 더 나은 효과를 만들기 위해서, 우리는 효과가 더 잘 보이는 곳에서 라이트의 강도를 증가시킬 수 있고 그것들을 열린 공간에서의 Global foggy look 을 피하기 위해서 감소시킬 수 있습니다.

우리는 Light space의 쉐도우맵 버퍼에서 비열견성(Discontinuities)를 찾고 그곳에서 구멍들의 위치를 찾으려 합니다. 구멍을 찾기 위해서, 우리는 많은 패스를 사용합니다. 첫째로, 우리는 경계들로 부터 최소 depth 값 전파에 대해서 여러 드로우콜을 사용합니다, 그래서 만약 구멍이 상대적으로 작다면 그것은 최종적으로 매워집니다. 두번째 단계는 최대 depth 값을 새로운 경계들로 부터 전파하기위해서 사용합니다. 만약 구멍이 완전히 채워지지 않았다면, 그것은 아마 최초의 상태로 남아있을 것입니다. 새로 차폐된 지역을 바라보면서, 우리는 이것들을 원본 쉐도우맵의 구멍들 처럼 다루고 이것들의 강도를 증가시킵니다.

 

Banding Artifacts

정규 샘플링은 시각적 Banding artifacts를 생성할 수 있습니다. 이것들을 피하기 위해서, 우리는 Eye-space depth에서의 초기 샘플링 위치를 약간 이동(Shifting)시키는 Jittering을 사용합니다. 이것들의 실제 양은 미리 계산되어질 수 있고 Noise 텍스쳐에 저장되어질 수 있습니다.

 

 

 

정규 샘플링(왼쪽)과 같은 장면에서 jittering 이 적용된(Right)

 

 

 

주의할점은, 초기 위치에서 이동되어져야 한다는 것입니다, 그래서, 모든 다른 샘플링 위치들이 사용되어질때 퍼포먼스 불이익이 없습니다.

반응형