Directional Light Shadows
2020-02-15 제 538회 Dev Rookie 발표자 이석우
CONCEPT
1
Directional Light
 장면의 모든 위치에서 같은 방향으로 표면에 접촉하는 빛을 말한다.
2
Directional Light
 태양은 거대한 구의 형태이지만 한 점을 확대해 보면 우리 눈에는 평지와 같다.
3
확대
태
양
표
면
따라서 이 점에서 방사되는 빛의 방향은 사실상 같다고 볼 수 있다.
Directional Light
 행성의 관점에서 보자면 남극과 북극의 태양빛의 방향은 다를 수 있다.
4
그러나 장면(Scene)은 사람 혹은 카메라의 시야 범위에 한정되기 때문에 방향이 같은 평행광이 된다.
Directional Light Shadows
 그림자는 빛이 닿지 않는 영역을 말한다.
 즉, Directional Light Shadow는 직접광이 닿지 않는 영역에서 발생한다.
5
Shadow Mapping
 오늘날의 그림자 매핑은 2단계를 거쳐 렌더링한다.
6
Rendering
Shadow Map
Rendering
Scene
깊이 버퍼 그림자 매핑 https://www.slideshare.net/SukwooLee4/20181222-126893802
Shadow Map
 그림자 맵은 깊이 버퍼를 이용해서 생성한다. (깊이 버퍼 그림자 버퍼)
 이때 한 점의 광원 위치로부터 가장 가까운 객체 표면의 거리를 깊이 버퍼에 저장한다.
7
A
B
C
D
0.0
0.5
0.7
0.85
1.0
깊이 버퍼 그림자 매핑 https://www.slideshare.net/SukwooLee4/20181222-126893802
Perspective Projection
 Light Space의 위치를 원근 투영하여 그림자 맵에 저장한다.
8
Perspective Projection
0.0
1.0
Spotlight Shadow, Point Light Shadow에 적용 가능
한 점의 광원에서 빛이 전방위로 방사한다고 가정
Perspective Projection
 Directional Light Shadow Map도 원근 투영해야 할까?
9
Directional Light는 모든 위치에서 빛을 한 방향으로만 방사한다.
Perspective Projection
0.0
1.0
Perspective Projection
 즉, 원근 투영을 하면 논리적인 오류가 발생한다.
10
따라서 이 방식은 Directional Light Shadow에 적용할 수 없다.
Perspective Projection
0.0
1.0
X X X X
O
O
Orthographic Projection
 따라서 Directional Light Shadow Map은 직교투영을 한다.
11
Perspective Projection
0.0
1.0
Orthographic Projection
 한 점이 아닌 near 평면을 기준으로 깊이 값이 계산한다.
12
Orthogonal Projection
 Shadow Map은 Scene을 완전히 포함해야 그림자가 문제없이 보인다.
13
그림자 X
Scene Scene
Good Case Bad Case
DLSM의 문제점(1)
 Camera Scene은 절두체인 반면 Shadow Map은 직육면체이므로 낭비되는 공간이 있다.
14
Shadow Map
Scene
Ideal case
아무리 효율적으로 그림자 맵을 생성해도 비는 공간이 존재
DLSM의 문제점(2)
 카메라와의 거리와 상관없이 그림자의 퀄리티가 동일하다.
15
near far
카메라와 가까운 그림자는 높은 퀄리티를 요구
DLSM의 문제점(2)
 Trade-off
퀄리티 메모리
12
Motive
17
공간 낭비를 최소화하고,
거리에 따라 퀄리티의 차이를
두는 방법은 없을까?
Cascade Shadow Mapping
 두개 이상의 그림자 맵을 이용하여 카메라의 위치에 따라 그림자 맵의 해상도를 달리하는 방법
18
카메라와의 거리가 가까우면, 해상도
멀면, 해상도
Cascade Shadow Mapping
 앞에서는 가장 이상적인 쉐도우 맵 생성을 보여주지만 일반적인 상황에선 보기 힘들다.
19
아무리 CSM을 사용해도 필연적으로 공간이 낭비되는 부분이 존재한다.
Directional Light
Cascade Shadow Mapping
 그래도 이것보단 낫다…
20
Directional Light
CSM 구현
21
Shadow Map Aliasing Problem
 구현에 앞서 고려해야할 사항이 있다.
 바로 쉐도우 맵을 사용할 경우 반드시 발생하는 엘리어싱 문제이다.
22
Shadow Map Aliasing Problem
 장면이 렌더링 되는 백버퍼는 카메라를 기준으로 3차원 데이터를 투영한다.
 반면 쉐도우 맵은 빛을 기준으로 투영하기 때문에 이에 따른 엘리어싱 문제가 발생한다.
23
Back Buffer
Shadow Map
Shadow Map Aliasing Problem
 따라서 엘리어싱을 고려하여 쉐도우 맵을 분할해야 한다.
24
𝑑𝑝
𝑑𝑠
=
1
𝑡𝑎𝑛∅
×
𝑑𝑧
𝑧𝑑𝑠
×
𝑐𝑜𝑠∅
𝑐𝑜𝑠𝜃
Projective
Aliasing
Perspective
Aliasing
Practical Split Scheme
 아래 그림은 카메라 프러스텀의 분할 방법을 보여준다.
 그림 (a) 는 단순히 균등하게 나눈다. 그러나 이 방식은 카메라 가까운 프러스텀에 대한
쉐도우 맵이 엘리어싱 문제가 상대적으로 두드러져 퀄리티가 떨어진다.
25
Practical Split Scheme
 그림 (b)는 로그 함수를 이용하여 분할한다.
 로그 분할의 경우 가까운 프러스텀에 대한 쉐도우 맵의 퀄리티가 좋아지지만 멀리있는
프러스텀의 쉐도우 맵 퀄리티가 너무 떨어질 수 있다.
26
Practical Split Scheme
 그림 (c)는 균등 분할과 로그 분할을 선형 보간하여 (a)와 (b)의 단점을 보완한다.
27
Practical Split Scheme
 그렇다고 무조건 (c)가 옳은 건 아니다. 때론 아트의 감으로 적당히 분할하는 게 더 나을 수도
있다. 그러나 상용 엔진에서 그런 미세한 조정까진 지원 안해줄 듯? ㅋ
28
Rendering Process
29
Rendering
Shadow Map
Rendering
Scene
Rendering Shadow Map
30
Light View
Transformation
Orthographic
Projection
Cascade
Transformation
Light View Transformation
 월드 공간의 위치를 (광원 기준) 시야 공간으로 변환
31
한가지 특이한 점은 World Center를 기준으로 뷰 매트릭스를 생성하였다.
이렇게 하는 이유는 Directional Light의 위치를 특정하기 어렵기 때문이다.
Light View Transformation
 월드 공간의 위치를 (광원 기준) 시야 공간으로 변환
32
Eye position
World Center
Directional light vector
Look at
Orthographic Projection
 다음으로 직교 투영을 하기 위해선 먼저 카메라 뷰 프러스텀이 월드 공간에서 차지 하는
영역을 알아야 한다.
33
그래야 쉐도우 맵이 차지하는 영역을 정할 수 있다.
Orthographic Projection
 계산을 최소화 하기 위해 카메라 중심에서 가장 먼 위치를 구한다.
34
Orthographic Projection
 Extract Frustum Bound Sphere
35
Eye position
Bound Center
Bound Radius
Bound Sphere
Orthographic Projection
 이제 최대 거리를 이용해 직교투영 행렬을 생성한다.
36
World Center가 중심이기 때문에 zn 값이 음수 이다.
Orthographic Projection
 Radius를 이용한 직교 투영
37
Eye position
Bound Center
Shadow Map
zn = - r
zf = r
Orthographic Projection
38
w h
light
zn
zf
2/𝑤 0 0 0
0 2/ℎ 0 0
0 0 1/(𝑧𝑓 − 𝑧𝑛) 0
0 0 𝑧𝑛/(𝑧𝑛 − 𝑧𝑓) 1
Cascade Transformation
 카메라 이동에 따른 그림자의 외곽의 깜빡거림(flickering) 처리 코드와 케스케이드 변환
코드가 섞여 있다.
39
Cascade Transformation
 이동과 스케일링
40
Cascade Transformation
 Translation
41
z
x
Cascade space
Translation
Translation
Light space
(Shadow space)
Cascade Transformation
 Scaling
42
y
x
Light space
(Shadow space)
Cascade space
Scaling
z 방향으로는 스케일링 하지 않았다.
CPU & GPU Process
43
Update Light
View Matrix
Update
Projection Matrix
Update
World Matrix
World
Transformation
Light View
Transformation
Projection
Transformation
CPU
GPU
Geometry Shader
Texture Array
 텍스처 배열
 Direct10 부터 지원하는 기능.
 텍스처 배열을 렌더 타겟 뷰로 지정한다.
 텍스쳐 배열과 지오메트리 쉐이더를 이용하여 1 드로우 콜이 가능하다.
443 draw call
1 2 3
1 draw call
Texture Array
Geometry Shader
45
텍스처 배열 인덱스
모든 쉐도우 맵에 대해여 삼각형 버텍스를 출력
Geometry Shader
46
 지오메트리 쉐이더 코드를 보면 하나의 삼각형에 대한 3개의 버텍스를 모든 쉐도우 맵에 출력
한다.
 이는 해당 쉐도우 맵 위치에 없는 것도 출력한다는 것을 의미한다.
 물론 하드웨어가 알아서 클리핑해주긴 하지만 굉장히 비효율적으로 보인다.
 직접 코드를 작성하여 컬링할 수도 있는데 왜 이렇게 처리하는 것일까?
 그 이유는 컬링 계산에 대한 비용이 만만치 않기 때문이다.
 여기선 하드웨어가 클리핑하도록 냅두고 있지만 시간 남아도는 사람만 컬링 테스트 해보도록
하자.
Rendering Scene
47
Vertex Shader Pixel Shader
Pixel Shader
48
DL 조명 계산
49
DL 그림자 계산
 먼저, 현재 위치를 Light Space(Shadow Space)로 변환한다.
 다음으로, 모든 캐스케이드 공간으로 변환한 후 각각 저장한다.
50
DL 그림자 계산
 그 중 카메라와 가장 가까이 있는 케스케이드 공간으로 변환한 위치를 선택한다.
51
DL 그림자 계산
 UV 좌표로 변환한 후 텍스처 배열에서 데이터를 로드한다.
52
UV좌표 배열 인덱스
CSM IN ENGINE
53
CSM in UE4
 Scene에 Directional light를 추가한 후 레벨에서 선택하면 디테일 탭에서 CSM을 설정할 수 있다.
54
CSM in UE4
 Dynamic Shadow Distance StationaryLight
55
카메라 위치를 기준으로 CSM의 범위를 설정한다.
(0이면 off, 그 외 값이면 on )
Shadow Map
Scene
Dynamic Shadow Distance
CSM in UE4
 사용할 쉐도우맵 개수 설정
56
CSM을 몇 개로 쪼갤지 정한다.
1
2
3
참고자료
 HLSL 프로그래밍 – 중첩된 셰도우 맵
 소스 코드 : http://www.acornpub.co.kr/book/hlsl-cookbook
 GPU Gem3 Chapter 10. Parallel-Split Shadow Maps on Programmable GPUs :
https://developer.nvidia.com/gpugems/gpugems3/part-ii-light-and-shadows/chapter-10-
parallel-split-shadow-maps-programmable-gpus
 언리얼 엔진 가이드 CSM :
https://docs.unrealengine.com/ko/Resources/ContentExamples/DynamicSceneShadows/index.html
57

Cascade Shadow Mapping

  • 1.
    Directional Light Shadows 2020-02-15제 538회 Dev Rookie 발표자 이석우
  • 2.
  • 3.
    Directional Light  장면의모든 위치에서 같은 방향으로 표면에 접촉하는 빛을 말한다. 2
  • 4.
    Directional Light  태양은거대한 구의 형태이지만 한 점을 확대해 보면 우리 눈에는 평지와 같다. 3 확대 태 양 표 면 따라서 이 점에서 방사되는 빛의 방향은 사실상 같다고 볼 수 있다.
  • 5.
    Directional Light  행성의관점에서 보자면 남극과 북극의 태양빛의 방향은 다를 수 있다. 4 그러나 장면(Scene)은 사람 혹은 카메라의 시야 범위에 한정되기 때문에 방향이 같은 평행광이 된다.
  • 6.
    Directional Light Shadows 그림자는 빛이 닿지 않는 영역을 말한다.  즉, Directional Light Shadow는 직접광이 닿지 않는 영역에서 발생한다. 5
  • 7.
    Shadow Mapping  오늘날의그림자 매핑은 2단계를 거쳐 렌더링한다. 6 Rendering Shadow Map Rendering Scene 깊이 버퍼 그림자 매핑 https://www.slideshare.net/SukwooLee4/20181222-126893802
  • 8.
    Shadow Map  그림자맵은 깊이 버퍼를 이용해서 생성한다. (깊이 버퍼 그림자 버퍼)  이때 한 점의 광원 위치로부터 가장 가까운 객체 표면의 거리를 깊이 버퍼에 저장한다. 7 A B C D 0.0 0.5 0.7 0.85 1.0 깊이 버퍼 그림자 매핑 https://www.slideshare.net/SukwooLee4/20181222-126893802
  • 9.
    Perspective Projection  LightSpace의 위치를 원근 투영하여 그림자 맵에 저장한다. 8 Perspective Projection 0.0 1.0 Spotlight Shadow, Point Light Shadow에 적용 가능 한 점의 광원에서 빛이 전방위로 방사한다고 가정
  • 10.
    Perspective Projection  DirectionalLight Shadow Map도 원근 투영해야 할까? 9 Directional Light는 모든 위치에서 빛을 한 방향으로만 방사한다. Perspective Projection 0.0 1.0
  • 11.
    Perspective Projection  즉,원근 투영을 하면 논리적인 오류가 발생한다. 10 따라서 이 방식은 Directional Light Shadow에 적용할 수 없다. Perspective Projection 0.0 1.0 X X X X O O
  • 12.
    Orthographic Projection  따라서Directional Light Shadow Map은 직교투영을 한다. 11 Perspective Projection 0.0 1.0
  • 13.
    Orthographic Projection  한점이 아닌 near 평면을 기준으로 깊이 값이 계산한다. 12
  • 14.
    Orthogonal Projection  ShadowMap은 Scene을 완전히 포함해야 그림자가 문제없이 보인다. 13 그림자 X Scene Scene Good Case Bad Case
  • 15.
    DLSM의 문제점(1)  CameraScene은 절두체인 반면 Shadow Map은 직육면체이므로 낭비되는 공간이 있다. 14 Shadow Map Scene Ideal case 아무리 효율적으로 그림자 맵을 생성해도 비는 공간이 존재
  • 16.
    DLSM의 문제점(2)  카메라와의거리와 상관없이 그림자의 퀄리티가 동일하다. 15 near far 카메라와 가까운 그림자는 높은 퀄리티를 요구
  • 17.
  • 18.
    Motive 17 공간 낭비를 최소화하고, 거리에따라 퀄리티의 차이를 두는 방법은 없을까?
  • 19.
    Cascade Shadow Mapping 두개 이상의 그림자 맵을 이용하여 카메라의 위치에 따라 그림자 맵의 해상도를 달리하는 방법 18 카메라와의 거리가 가까우면, 해상도 멀면, 해상도
  • 20.
    Cascade Shadow Mapping 앞에서는 가장 이상적인 쉐도우 맵 생성을 보여주지만 일반적인 상황에선 보기 힘들다. 19 아무리 CSM을 사용해도 필연적으로 공간이 낭비되는 부분이 존재한다. Directional Light
  • 21.
    Cascade Shadow Mapping 그래도 이것보단 낫다… 20 Directional Light
  • 22.
  • 23.
    Shadow Map AliasingProblem  구현에 앞서 고려해야할 사항이 있다.  바로 쉐도우 맵을 사용할 경우 반드시 발생하는 엘리어싱 문제이다. 22
  • 24.
    Shadow Map AliasingProblem  장면이 렌더링 되는 백버퍼는 카메라를 기준으로 3차원 데이터를 투영한다.  반면 쉐도우 맵은 빛을 기준으로 투영하기 때문에 이에 따른 엘리어싱 문제가 발생한다. 23 Back Buffer Shadow Map
  • 25.
    Shadow Map AliasingProblem  따라서 엘리어싱을 고려하여 쉐도우 맵을 분할해야 한다. 24 𝑑𝑝 𝑑𝑠 = 1 𝑡𝑎𝑛∅ × 𝑑𝑧 𝑧𝑑𝑠 × 𝑐𝑜𝑠∅ 𝑐𝑜𝑠𝜃 Projective Aliasing Perspective Aliasing
  • 26.
    Practical Split Scheme 아래 그림은 카메라 프러스텀의 분할 방법을 보여준다.  그림 (a) 는 단순히 균등하게 나눈다. 그러나 이 방식은 카메라 가까운 프러스텀에 대한 쉐도우 맵이 엘리어싱 문제가 상대적으로 두드러져 퀄리티가 떨어진다. 25
  • 27.
    Practical Split Scheme 그림 (b)는 로그 함수를 이용하여 분할한다.  로그 분할의 경우 가까운 프러스텀에 대한 쉐도우 맵의 퀄리티가 좋아지지만 멀리있는 프러스텀의 쉐도우 맵 퀄리티가 너무 떨어질 수 있다. 26
  • 28.
    Practical Split Scheme 그림 (c)는 균등 분할과 로그 분할을 선형 보간하여 (a)와 (b)의 단점을 보완한다. 27
  • 29.
    Practical Split Scheme 그렇다고 무조건 (c)가 옳은 건 아니다. 때론 아트의 감으로 적당히 분할하는 게 더 나을 수도 있다. 그러나 상용 엔진에서 그런 미세한 조정까진 지원 안해줄 듯? ㅋ 28
  • 30.
  • 31.
    Rendering Shadow Map 30 LightView Transformation Orthographic Projection Cascade Transformation
  • 32.
    Light View Transformation 월드 공간의 위치를 (광원 기준) 시야 공간으로 변환 31 한가지 특이한 점은 World Center를 기준으로 뷰 매트릭스를 생성하였다. 이렇게 하는 이유는 Directional Light의 위치를 특정하기 어렵기 때문이다.
  • 33.
    Light View Transformation 월드 공간의 위치를 (광원 기준) 시야 공간으로 변환 32 Eye position World Center Directional light vector Look at
  • 34.
    Orthographic Projection  다음으로직교 투영을 하기 위해선 먼저 카메라 뷰 프러스텀이 월드 공간에서 차지 하는 영역을 알아야 한다. 33 그래야 쉐도우 맵이 차지하는 영역을 정할 수 있다.
  • 35.
    Orthographic Projection  계산을최소화 하기 위해 카메라 중심에서 가장 먼 위치를 구한다. 34
  • 36.
    Orthographic Projection  ExtractFrustum Bound Sphere 35 Eye position Bound Center Bound Radius Bound Sphere
  • 37.
    Orthographic Projection  이제최대 거리를 이용해 직교투영 행렬을 생성한다. 36 World Center가 중심이기 때문에 zn 값이 음수 이다.
  • 38.
    Orthographic Projection  Radius를이용한 직교 투영 37 Eye position Bound Center Shadow Map zn = - r zf = r
  • 39.
    Orthographic Projection 38 w h light zn zf 2/𝑤0 0 0 0 2/ℎ 0 0 0 0 1/(𝑧𝑓 − 𝑧𝑛) 0 0 0 𝑧𝑛/(𝑧𝑛 − 𝑧𝑓) 1
  • 40.
    Cascade Transformation  카메라이동에 따른 그림자의 외곽의 깜빡거림(flickering) 처리 코드와 케스케이드 변환 코드가 섞여 있다. 39
  • 41.
  • 42.
    Cascade Transformation  Translation 41 z x Cascadespace Translation Translation Light space (Shadow space)
  • 43.
    Cascade Transformation  Scaling 42 y x Lightspace (Shadow space) Cascade space Scaling z 방향으로는 스케일링 하지 않았다.
  • 44.
    CPU & GPUProcess 43 Update Light View Matrix Update Projection Matrix Update World Matrix World Transformation Light View Transformation Projection Transformation CPU GPU Geometry Shader
  • 45.
    Texture Array  텍스처배열  Direct10 부터 지원하는 기능.  텍스처 배열을 렌더 타겟 뷰로 지정한다.  텍스쳐 배열과 지오메트리 쉐이더를 이용하여 1 드로우 콜이 가능하다. 443 draw call 1 2 3 1 draw call Texture Array
  • 46.
    Geometry Shader 45 텍스처 배열인덱스 모든 쉐도우 맵에 대해여 삼각형 버텍스를 출력
  • 47.
    Geometry Shader 46  지오메트리쉐이더 코드를 보면 하나의 삼각형에 대한 3개의 버텍스를 모든 쉐도우 맵에 출력 한다.  이는 해당 쉐도우 맵 위치에 없는 것도 출력한다는 것을 의미한다.  물론 하드웨어가 알아서 클리핑해주긴 하지만 굉장히 비효율적으로 보인다.  직접 코드를 작성하여 컬링할 수도 있는데 왜 이렇게 처리하는 것일까?  그 이유는 컬링 계산에 대한 비용이 만만치 않기 때문이다.  여기선 하드웨어가 클리핑하도록 냅두고 있지만 시간 남아도는 사람만 컬링 테스트 해보도록 하자.
  • 48.
  • 49.
  • 50.
  • 51.
    DL 그림자 계산 먼저, 현재 위치를 Light Space(Shadow Space)로 변환한다.  다음으로, 모든 캐스케이드 공간으로 변환한 후 각각 저장한다. 50
  • 52.
    DL 그림자 계산 그 중 카메라와 가장 가까이 있는 케스케이드 공간으로 변환한 위치를 선택한다. 51
  • 53.
    DL 그림자 계산 UV 좌표로 변환한 후 텍스처 배열에서 데이터를 로드한다. 52 UV좌표 배열 인덱스
  • 54.
  • 55.
    CSM in UE4 Scene에 Directional light를 추가한 후 레벨에서 선택하면 디테일 탭에서 CSM을 설정할 수 있다. 54
  • 56.
    CSM in UE4 Dynamic Shadow Distance StationaryLight 55 카메라 위치를 기준으로 CSM의 범위를 설정한다. (0이면 off, 그 외 값이면 on ) Shadow Map Scene Dynamic Shadow Distance
  • 57.
    CSM in UE4 사용할 쉐도우맵 개수 설정 56 CSM을 몇 개로 쪼갤지 정한다. 1 2 3
  • 58.
    참고자료  HLSL 프로그래밍– 중첩된 셰도우 맵  소스 코드 : http://www.acornpub.co.kr/book/hlsl-cookbook  GPU Gem3 Chapter 10. Parallel-Split Shadow Maps on Programmable GPUs : https://developer.nvidia.com/gpugems/gpugems3/part-ii-light-and-shadows/chapter-10- parallel-split-shadow-maps-programmable-gpus  언리얼 엔진 가이드 CSM : https://docs.unrealengine.com/ko/Resources/ContentExamples/DynamicSceneShadows/index.html 57