레이 트레이싱 (6)

그림자

2020년 12월 20일

그림자

그림자는 물체와 광원 사이에 다른 물체가 있어 빛을 가로막거나 빛의 일부만 도달했을 때 생깁니다. 물체와 광원 사이에 다른 물체가 있는지, 있다면 얼마만큼의 빛을 가로막고 통과시키는지 알 수 있다면 그림자를 구현할 수 있습니다.





Shadow ray

색을 구하고자 하는 물체 표면의 한 점을 PP, 광원을 LL 이라고 하겠습니다. PP 에 닿는 빛의 방향 벡터는 LP\overline{LP} 라 할 수 있습니다. 만약 직선 LP\overline{LP} 사이에 다른 물체가 있다면 빛이 PP 에 도달하지 못하고 LP\overline{LP} 사이의 물체에 의해 가로막히게 됩니다. 이 때 PP 에 그림자가 생긴다고 판정할 수 있습니다. 물체와 광원 사이에 끼인 물체가 있는지 판단하는 방법은 광선과 물체의 부딪힘 판단에서 힌트를 얻을 수 있습니다. 광선의 자취에 관한 식을 상기해 보겠습니다.

p=e+tdp = e + td

카메라의 위치 ee, 광선의 진행 방향 벡터 dd, 카메라로부터 떨어진 거리 tt 로 이루어진 위 식은 물체와 광원 사이에 끼인 물체가 존재하는지 판단하는 방법에도 사용됩니다.

부딪힘 판단 그림자
출발점 ee PP
진행방향 dd PL\overline{PL}

추적 역할을 했던 광선의 요소가 ee, dd 였다면 그림자의 경우 PP, 정규화한 벡터 PL\overline{PL} 이 그 역할을 담당합니다. 광선과 비슷한 요소를 갖추고 있어 이를 shadow ray 라 부릅니다. 이후 구, 원뿔, 원기둥, 평면에 대해 각각의 부딪힘을 판단하는 식을 이용해 미지수 tt 를 구합니다.

만약 거리 ttPP 와 광원과의 거리인 PL\parallel \overline{PL} \parallel 보다 작은 양수라면 PP 와 광원사이에 물체가 있다고 할 수 있습니다. 만약 물체가 투명도 속성을 가지고 있지 않다면 PP 의 색을 단순히 검은색으로 지정하고, 투명도가 있다면 이를 반영해 색을 계산합니다. 예를 들어 PP 와 광원 사이에 위치한 물체의 투명도가 20%라면, 빛의 80%는 가로막히고 20%는 통과한다는 의미입니다. 따라서 Phong reflection 에 의해 계산한 PP 의 RGB 벡터 각각의 요소에 0.2 를 곱해줍니다.

만약 여러 물체가 shadow ray 와 부딪힌다면 물체의 투명도들을 모두 곱한 결과를 이용할 수 있습니다. 예를 들어 PP 와 광원 사이에 물체 AA, BB 가 있고 각각의 투명도가 20%, 10% 라면 20% 의 빛 중 10% 의 빛만 통과하므로 0.2×0.1=0.020.2 \times 0.1 = 0.02 를 RGB 벡터의 각각의 요소에 곱한 결과가 점 PP 의 색이 됩니다. shadow ray 를 이용해 그림자가 표현된 이미지를 렌더해 보겠습니다.

렌더된 결과에 전체적으로 노이즈가 있어 그림자는 커녕 물체의 색도 온전히 보이지 않습니다. 물체 표면의 점 PP 가 부동소수점 오차로 인해 정확한 좌표 PP 를 가리키지 않기 때문입니다.





Bias 의 필요성

위 그림과 같이 물체 위의 점 PP 가 오차로 인해 물체의 표면보다 아주 조금 아래에 있다면 PP 에서 출발해 광원을 향하는 shadow ray 는 출발 지점의 물체와 부딪힙니다. 이전의 렌더 결과에서 노이즈가 발생한 이유는 바로 이것 때문입니다. 물체 위의 점 PP 를 물체 표면 조금 위의 위치로 이동시키면 이를 해결할 수 있습니다. 이동방향은 PP 에서의 법선벡터 nn 방향이고 이동시킨 점은 아래와 같이 쓸 수 있습니다.

P=P+Bias nP' = P + Bias\text{ }n

이 때 Bias 는 법선벡터 방향으로의 거리이고 0.0001 과 같이 아주 작은 값으로 설정합니다. Bias 가 적용된 결과를 렌더해 보겠습니다.

Phong reflection 에 이어 그림자 역시 법선벡터를 이용해 해결할 수 있었습니다. 다음 포스트에서는 레이 트레이싱의 꽃인 반사와 굴절을 알아보겠습니다.





출처 및 참고