2024.7.26(금) - 15장 쉐도우 매핑
두 단계 렌더링
쉐도우 매핑을 위한 두 단계 알고리즘을 보여주는 그림이다.
(a) 첫 번째 패스는 쉐도우 맵을 생성한다.
(b) 두 번째 패스는 3차원 장면의 점이 광원에서 보이는지 검사하기 위해 쉐도우맵을 사용한다.
쉐도우 매핑 알고리즘은 두 번의 렌더링 패스를 통해 수행된다. 첫 번째 패스에서는 쉐도우맵이라는 특수한 텍스처를 생성한다. 위 그림 (a)를 보면 광원에서 나온 빛이 미치는 표면은 굵은 선으로 표시됐다. 이들 표면을 균일하게 샘플하여, 각 샘플점 p마다 광원까지의 거리를 쉐도우맵에 저장한다.
이 거리를 z로 표기하는데, 이는 광원에서 본 3차원 장면의 깊이다. 따라서, 쉐도우맵은 광원 기준의 깊이맵이라고도 한다.
쉐도우 매핑 알고리즘
실제 렌더링 과정에서는 쉐도우맵을 사용하여 그림자를 생성한다.
(b)를 예시로 들어본다면, 프래그먼트 f1을 처리할 때 이 프래그먼트에 해당하는 월드 공간의 점을 q1이라고 하면, 광원과 q1 사이 거리 d1은 쉐도우맵에 저장된 깊이 값 z1보다 크다. 따라서 q1은 그림자에 속한다. q2의 경우 광원까지의 거리 d2가 쉐도우맵에 저장된 값 z2보다 크므로 빛을 받는 점으로 판정되는 것이다.
쉐도우맵은 텍스처의 한 종류이므로 필터링 방법을 미리 정해야하는데, 근접점 샘플링을 사용한다고 가정한다. (c)의 q1의 경우 쉐도우맵에서 z1을 읽어올 것이며 그림자에 속하는 점으로 판정되지만 이는 잘못된 판정이다. 반면 f1에 인접한 프래그먼트 f2는 빛을 받는다고 옳게 판정이 된다. 이처럼 완전히 빛을 받는 지역임에도 일부 프래그먼트는 빛을 못 받는 것으로 판정되어 (b)처럼 자잘한 그림자가 생성되는 것이다.
쉐도우 매핑의 문제점을 해결하는 법은 간단하다.
두 번째 패스에서 샘플한 점들을 광원 쪽으로 약간 이동시키면 된다. 즉 광원까지의 거리 d에서 일정한 값을 뺴는 것인데, 이 값을 바이어스라고 한다.
쉐도우맵 필터링
근접점 샘플링으로 쉐도우맵을 필터링하면 (b)처럼 거친 윤곽선을 가진 그림자가 생성된다.
→ 네 개의 텍셀 각각에 대해 q의 가시성 결정 후 이를 보간하면 해결 가능하다.
쉐도우맵에서 여러 개 텍셀을 참조하여 이들에 대한 픽셀의 가시성을 결정하고 그 결과를 결합하는 기법을 일반적으로 PCF라고 부른다.
쉐도우 매핑을 위한 GL 프로그램과 쉐이더
첫 번째 패스의 쉐이더이다. 모든 3차원 정점이 월드 변환을 통해 월드 공간으로 변환된 후 카메라 파라미터가 광원 기준으로 설정된다.
위 코드는 정점 쉐이더이다. gl_Position은 래스터라이저로 들어가 원근 나눗셈된다. p는 광원에서 보이는 정점을 나타내는데, 원근 나눗셈 결과 NDC로 표현된 222 크기의 정육면체 뷰 볼륨 안에 놓이게 된다.
두 번째 패스의 쉐이더에서는 실제 카메라 관점에서 통상적인 렌더링을 수행한다.
q를 ‘광원 기준의 클립 공간’으로 변환하여 (x, y, z, w) 좌표를 얻은 다음, 아래 →로 표기한 연산 두 가지를 수행한다.
첫 번째 연산은 원근 나눗셈인데, 그 결과 x/w, y/w, z/w는 모두 [-1, 1] 범위에 놓인다.
두 번째 연산은 이를 [0, 1] 범위로 전환하는 것이다.
위와 같이 고쳐 쓸 수 있다. 첫 번째 연산은 정점 쉐이더, 두 번째 연산은 프래그먼트 쉐이더가 수행할 것이다.
29번 줄에서는 첫 번째 연산에 해당하는 부분이 작성되어 있다.
이 4차원 벡터는 v_shadowCoord라는 이름으로 출력된다.
위 코드는 프래그먼트 쉐이더인데, 코드를 단순하게 만들기 위해 퐁 모델 디퓨즈항만 구현했다.
하드 쉐도우와 소프트 쉐도우
점 광원에서 나오는 빛을 받는 지역, 받지 않는 지역 명확하게 구분되는 모습이다.
이렇게 만들어진 그림자는 하드 쉐도우라고 부르고,
점 광원과 달리 ‘면적’을 가진 광원을 영역 광원이라고 하는데 이는 소프트 쉐도우를 생성한다.
(a)를 보면 부분적으로 그늘진 지역이 있음을 알 수 있다. 이는 반그림자, 영문으로는 penumbra라고 부른다.
반그림자 지역 표면의 각 점에서 영역 광원이 얼마만큼 보이는지 계산한다.
(d)의 그림자 윤곽선은 (b) 및 (c)에 비해 부드럽게 보이지만 이는 소프트 쉐도우가 아니라 앤티에일리어싱 처리된 하드 쉐도우이다.
이미지 출처: [OpenGL ES를 이용한 3차원 컴퓨터 그래픽스 입문]
위 서적을 보고 공부한 내용을 정리함