그림자는 컴퓨터 그래픽을 더욱 현실감 있게 만드는 요소다. 이때 필요한 개념이 바로 쉐도우 매핑이고, 간단하게 설명하면 다음과 같다.
1. 쉐도우 매핑(Shadow Mapping) 은 그림자를 처리하기 위해 Vertex Shader 에서 light source 로부터 각 surface 점까지의 깊이값과 visibility 값을 저장하는 기법을 의미한다.
2. Pass 1 에서는 각 표면까지의 깊이값 z 를, Pass 2 에서는 실제 점까지의 거리 d 를 저장하여, 이를 비교해서 Shadow 여부를 결정한다. Nearest Sampling 과 Bilinear Interpolation 둘 다 별 도움은 되지 않으므로, PCF(Percentage Closer Filtering) 기법을 사용하여 Visibility 를 수치값으로 표현한다.
3. Vertex Shader 에서 만든 Shadow Map 은 Output Merger 가 Z-buffering 을 하는 과정에서 활용되어 그림자가 출력되게 된다.
Pass 1에서는 광원이 닿을 수 있는 점들을 렌더링한다. Shadow Map에는 광원에 대한 깊이값만 저장한다.
Pass 2로 와서 카메라 관점에서 렌더링을 하게 된다.
각 픽셀마다, 광원까지의 거리를 d라고 할 때, d > z인 경우 그림자가 생긴다. 여기까지 하면 기본적인 그림자가 생성이 되지만, 아직 부족한 점이 있다.
그대로 쉐도우 매핑을 적용할 경우 위의 사진처럼 완전하게 빛을 받는 지역에서도 자잘한 그림자가 석이게 된다.
왜냐하면 모든 점들에 대해 렌더링되는 것이 아니라 일정 단위 간격으로 Shadow Mapping이 이뤄지고 있기 때문이다.
이 문제를 해결하기 위한 방법은 의외로 간단하다.
Pass 2에서 샘플한 점들을 광원 쪽으로 offset을 설정해주면 된다. 이때의 값을 Bias라고 한다.
Surface에서 광원까지의 거리를 d1이라고 할 때 bias라는 값을 빼서 d1`의 거리를 잡고 샘플링하면 된다. 이후 이를 z1과 비교를 했을 때, d1`이 z1 보다 작으므로 샘플된 점을 빛을 받는 것으로 판정된다.
쉐도우 매핑에서는 이 Bias의 값을 적절하게 설정하는 것이 중요한데, 너무 작을 경우 불필요한 그림자를 완벽히 제거할 수 없고, 너무 크면 그림자가 과도하게 축소될 수 있다.
앞서 본 쉐도우 매핑은 근접점 샘플링을 통해 완전히 빛을 받거나 완전히 그늘지거나 둘 중 하나의 결과가 나온다. 때문에 모자이크화 되는 그림자가 발생할 수 있다.
이를 보완하기 위해 겹선형 보간을 사용하여 필터링을 해야 한다.
우선 그림자가 지는 지점 q를 둘러 싼 네 개 텍설의 깊이 값을 보간하여 q의 깊이값과 비교하게 되는데, q의 깊이가 더 크다면 그늘 진 것으로 판정한다.
이후 q의 가시성을 결정한 후 이를 보간한다. 각 텍셀의 가시성을 보간하여 나온 값을 통해 빛을 얼마나 받고 있는지를 확인할 수 있는데 0이면 빛을 받지 않는 것이고 1이면 빛을 받고 있는 것이다.
보간 후 값을 통해 그림자를 비율로 조절하여 그림자의 윤곽선을 좀 더 부드럽게 만들 수 있다.
'프로그래밍 > 공부' 카테고리의 다른 글
[Graphics] 키프레임 애니메이션 (0) | 2023.06.28 |
---|---|
[Graphics] 포워드 렌더링 and 디퍼드 렌더링 (0) | 2023.06.27 |
[Graphics] 노멀매핑 & 탄젠트 공간 (0) | 2023.06.24 |
[Graphcis] 스키닝 애니메이션 (0) | 2023.06.22 |
[DirectX3D] 광원 효과 - (1) (1) | 2023.06.08 |
댓글