Near 평면으로 투영된 구의 크기 구하기

최근에 구로만 이루어진 장면을 위한 초간단 레이트레이서를 구현할 기회가 있었습니다. 무식한 방법으로 초기 구현을 한 뒤, 최적화를 위해 구를 화면 타일(near 평면을 균일 격자로 나눔)로 미리 분류해놓는 방법을 시도하였습니다. 그러면 각 픽셀에서 광선 추적 시, 그 픽셀이 포함된 타일에 등록된 구들만 조사하면 되니까요. 원근 투영에서 구를 2차원 평면에 투영하는 경우 그 결과가 원이 아니어서, 구현이 생각만큼 간단하지 않더군요. 기하 및 삼각함수 지식을 적용해 투영된 구의 최소 사각 경계를 구할 수 있었습니다. 사각 경계를 얻고 나면, 쉽게 구를 관련 타일들에 등록할 수 있지요.


제가 손수 그린 아래 그림에서 상황 및 관련 기하 매개변수들을 확인할 수 있습니다. 나름 최선을 다한 그림이니 못마땅 하더라도 양해를...;



위 그림은 수직 단면(y축 방향)만을 보여줍니다만, 수평 단면(x축 방향)으로도 마찬가지로 적용할 수 있습니다. 반지름 r의 구를 투영하고 있습니다. Near 평면에 투영되면서 작아지는 r'는 닮은꼴 비례 관계로 쉽게 계산할 수 있습니다(Eq. 1). 아래쪽 확대한 그림에 y축 방향 투영 크기를 구하는데 필요한 변수들이 자세히 나와 있습니다. 종국에 다음과 같이 y방향 범위가 나옵니다.

r'/cos(theta) - Ydown < (Y - projected_sphere_center) < r'/cos(theta) + Yup

여기서, projected_sphere_center는 구 중심을 near 평면으로 투영한 점을 나타냅니다. theta는 시야 벡터와 시점으로부터 투영된 구 중심으로의 벡터 사이의 각도를 말합니다. YupYdown을 구하려면, 역시 닮은꼴 비례 관계를 두 번 활용해야 합니다(파란색 및 보란색 선으로 표시된 비례 관계 참조). 위 그림에서 닮은꼴들을 쉽게 발견할 수 있기를 바랍니다. Eq. 2Eq. 3으로 YupYdown을 구하고나면, Y의 범위는 위 부등식으로 주어집니다(시계 반대 방향으로 theta가 양이라 하면, 구가 시야 벡터 위가 아닌 아래에 있는 경우에도 위 방정식 쌍을 그대로 쓸 수 있습니다). X축 범위도 마찬가지로 구할 수 있습니다. 이렇게 2차원 경계가 나오면, 이 사각 영역과 겹치는 화면 타일들을 바로 찾아낼 수 있습니다.

이렇게 결과를 얻고 나면, 참 간단해 보입니다. 실제 필요한 기하 및 삼각함수 지식도 초보적인 수준이고요. 그래도 그 유도 과정을 이렇게 한 번 정리해 두는 것도 의미가 있다고 생각했습니다. 이 글이 누군가에게 도움이도 되기를 바랍니다. 오류가 있거나 더 나은 방법을 알고 계시면 꼭 댓글로 남겨주시길 부탁 드립니다. ^^


[업데이트] 저의 무지가 드러났습니다; 이 글의 영문 버전에 달린 댓글에 따르면, 타원체의 투영 결과는 타원이라는군요. 따라서, 구의 투영도 (반드시 원은 아니지만) 타원이 되겠습니다. 증명은 이 문서를 참고하세요. 또다른 댓글에 타원체를 기준으로 한 쌍대(duality) 원리에 대한 언급도 나옵니다. 도 알아두면 좋게네요. ^^
저작자 표시
크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback 0 Comment 13

top