본문 바로가기

프로그래밍/DirectX

Light / Rendering

실용 Direct3D 11 렌더링 & 계산 이라는 책을 보고 있다.


처음 Resource와 View, Device, Context와 같은 DirectX11에 관한 내용들이 자세하게 설명되어 있다


그런데 번역을 너무 정직(?)하게 해놓으셔서 실무에서 쓰는 용어들로 다시 해석을 해야하는 경우가 많다


예를 들어 Semantic을 시맨틱말고 의미소로 써있다던지, World 행렬을 세계 행렬이라고 써있다던지..


이런 번역들 덕에 읽다가 집중이 깨지는 경우가 종종 있는 거 같다


오늘은 조명 부분을 읽었는데 Deferred Rendering과 밀접한 연관이 있어서 자세하게 보고 있다


지금 3D 포트폴리오를 제작할 때 Forward Rendering과 Deferred Rendering을 같이 사용해야하기 때문에 더 유심히 봐야할 거 같다


Render Target View : 렌더링 파이프라인의 출력을 받을 자원을 연결하는데 쓰인다
Depth Stencil View : 렌더링 파이프라인의 출력을 받는 자원을 위한 것이다.
렌더타겟 뷰는 색상 값들을 담는 버퍼를 위한 것이고, 깊이 스텐실 뷰는 깊이와 스텐실 값들을 담는 버퍼를 위한 것이다

조명(Light)
: 특정 지점에서의 표면 기하구조가 반사하는 빛의 세기와 색을 계산하는 과정
조명의 처리 과정
한 픽셀이 주어졌을 때, 그 픽셀에 적용해야 할 빛들을 광원의 종류와 감쇠 속성에 기초해서 결정한다
Albedo, Normal, Position, 픽셀에 적용되는 각 광원의 속성을 이용해서 Bidirectional Reflection Distribution Function(양방향 반사 분포 함수)를 평가한다
2의 계산 결과를 가시성 판정 결과에 따라 픽셀이 그림자 안에 있는지 여부에 따라 적절히 적용한다
이렇게 처리하는 과정을 보통 Forward Rendering이라고 부른다

Forward Rendering에서는 정점 특성 data와 텍스처 및 상수 버퍼에 담긴 여러 표면 속성들을 이용해서 기하구조를 래스터화한다
그런 다음 하나 이상의 광원에 대해, 래스터화된 각 픽셀마다 Material 자료를 이용해서 조명 공식을 적용한다
조명 공식을 구한 결과가 해당 픽셀의 출력이다.
그 출력을 렌더 타겟에 이미 들어있던 것과 혼합하기도 한다

Point Light
: 모든 방향으로 동일하게 기여하는 빛으로, 기여도는 광원과 빛을 받는 표면 사이의 거리에 비례해서 감소한다. 따라서 빛이 영향을 미치는 영역은 Sphere형태이다

Spot Light
: 특정 방향에 기여하는 빛으로, 기여도는 표면과 빛의 방향 사이의 각도에 의존한다. 따라서 효과 영역은 원뿔 형태이다

Directional Light
: 빛의 기여도를 계산할 때 광원과의 거리를 고려하지 않는다. 빛의 광원이 위치 없이 방향만 있는 '전역'광원이기 때문이다
Forward Rendering의 단점
광원의 적용이 렌더링할 장면 기하구조의 Granularity(낟알 모양, 입도)에 의존적이다. 즉, Draw 호출에서 어떤 한 광원을 활성화시키면, 그 광원은 이 호출에서 래스터화되는 모든 기하구조에 무조건 적용된다
-> 광원이 많아지면 계산, CPU의 작업 양이 많아진다
셰이더 프로그램이 복잡해진다. Material 속성과 빛의 종류가 서로 다른 여러가지 광원을 사용하다 보면 필요한 Shader Permutation들의 수가 기하급수적으로 늘어나게 된다. 셰이더 프로그램이 많을수록 메모리 사용량이 많이지고 셰이더 프로그램 사이의 전환 비용도 커진다
Deferred Rendering 과정
Scene의 기하구조를 하나의 GBuffer에 렌더링한다
조명을 적용한다. 픽셀에 영향을 주는 광원마다, 화면에서 그 광원이 영향을 주는 영역의 기하구조를 렌더링한다.
래스터화된 픽셀마다 GBuffer에서 추출한 정보와 해당 광원의 속성을 이용해서 조명 값을 계산하고 결합해서 해당 픽셀의 최종적인 색상을 결정한다
Deferred Rendering의 장점
조명과 그림자 계산을 개별적인 셰이더 프로그램으로 옮길 수 있기 때문에 Shader Permutation의 수가 크게 줄어든다
Scene 기하구조를 렌더링 할 때 조명 매개변수들이 필요하지 않으므로, 한 Mesh의 여러 Instance들을 렌더링할 때 반드시 활성 광원들이 동일해야 할 필요가 없다.
조명을 Multi-pass로 처리하는 것이 아니므로 Scene 기하구조를 한번만 렌더링하면 된다
빛의 효과 영역을 대표하는 Bounding Volume 또는 Screen-Space 사각형을 렌더링하면 된다. Depth Stencil 판정을 이용해서 셰이더 실행 횟수를 줄이는 것도 가능하다
조명과 기하구조가 분리되었기 때문에, 필요한 셰이더 프로그램과 전체적인 렌더링 프레임워크가 단순해진다
Deferred Rendering의 단점
GBuffer의 생성과 Sampling에 많은 양의 메모리와 Bandwidth가 소비된다. 한 픽셀의 조명을 계산하는데 필요한 모든 정보를 GBuffer에 담아야 하기 때문이다
각 Subsample마다 조명 계산을 수행해야 하는데, 그러면 계산 부담이 커질 수 있다.
Alpha처리가 되어있는 기하구조는 다른 방식으로 처리해야 한다. GBuffer는 하나의 표면을 위한 속성들만 담을 수 있는데, Alpha처리된 기하구조를 렌더링하면 겹쳐 그려지는 픽셀에 대해 조명을 여러번 계산해서 그 결과들을 결합해야 한다.

'프로그래밍 > DirectX' 카테고리의 다른 글

DirectX 11 기초  (0) 2019.03.28
3D 애니메이션 이론 2  (0) 2019.03.26
Directx11 렌더링 파이프라인  (0) 2019.03.22
3D Animation 이론 1  (0) 2019.03.22
Rasterizer  (0) 2019.03.04