7. 3D Picking
● 오브젝트가 화면에 그려지기 까지의 좌표 변환
● 렌더링 파이프라인
로컬 좌표 → 월드행렬 곱 → 뷰 행렬 곱 → 투영 행렬 곱 → w나누기 → NDC공
간 → Window 좌표로 변환
8. 3D Picking
● 뷰 행렬 곱 → 투영 행렬 곱 → w나누기 → NDC공간 → Window 좌표로 변환
월드 스페이스 뷰 스페이스 NDC 공간 스크린 스페이스
9. 3D Picking
● 뷰 행렬 곱
카메라 로컬 좌표 * 월드 행렬 = 월드 스페이스 상의 카메라 좌표
반대로, 카메라 월드 좌표 * 월드 역행렬 = 카메라의 로컬 좌표
10. 3D Picking
● 투영 행렬 곱
- 상태를 변환하기 위한 행렬이 아니라, 투영하기 좋게 만드는 순수 연산을 위한 행렬
- D3DXMatrixPerspectiveFovLH (&결과, fovY, Aspect, near, far)
- fovY : 높이 각도 (field of view : 60도 정도로 준다.)
- Aspect : 윈도우 사이즈 비율 (WinCX / WinCY)
- near : 실제 뷰 스페이스 상의 원점에서 최소 영역
(z나누기를 하기 때문에 0이 아닌 0.1정도로 준다.)
- far : 실제 뷰 스페이스 상의 최대 영역 (500~1000)
11. 3D Picking
● 투영 행렬 곱 (1열, 2열)
x, y 값을 시야각에 따라 늘리거나 줄인다.
시야각이 90도가 아닐 경우 보여주는 정점들을 90도에 맞춰 늘리거나 줄인다
● (x || y) * 1/tan (fov/2) 값이
90도일 때, tan(45)는 1이므로 본래의 x, y값이 나오게 된다.
60도일 때, tan(30)은 1/√3 이므로 x/√3,y/√3이 나온다.
120도일 때, tan(60)은 √3 이므로
Fov가 60도일 경우 x가 양수일 때 커지고 음수일때 작아진다.
12. 3D Picking
● 투영 행렬 곱 (1열, 2열)
Aspect(윈도우 사이즈 비율)로 나눠주지 않으면 늘어난다...
13. 3D Picking
● 투영 행렬 곱 (3열)
z’의 값을 도출해준다.
z == near 일 때 z’는 0의 값이 나온다.
z == far 일 때 z’는 1의 값이 나온다.
14. 3D Picking
● 투영 행렬 곱 (4열), z(w)나누기
투영행렬 하기 이전의 값인 뷰스페이스의 Z값을 w에 담아준다.
w에 담아주는 이유는 z를 z로 나누면 1이기 때문에 다시 깊이를 되돌릴 수 없다.
결론 : 투영행렬을 곱해서 (x’,y’,z’,w)의 값을 구하고,
투영 행렬 변환 이전의 z값인 w로 나눠준다.
투영 행렬을 곱함으로써 z값은 0~1 범위의 값을 가지게 된다.
15. 3D Picking
● NDC공간 → Window 좌표로 변환
NDC공간의 (-1,1) ~ (1, -1)을 (0, 0) ~ (WinCX, WinCY)로 바꾼다.
16. 3D Picking
● 마우스 피킹을 하기 위해서는 2D 윈도우 화면의 마우스 좌표를 3차원 공간으
로 옮기는 작업을 해야한다.
● 렌더링 파이프라인을 역순으로 한다면 윈도우에서 마우스 좌표를 월드 좌표까
지, 더 나아가 해당 오브젝트의 로컬 좌표까지 끌고 갈 수 있다!
17. 3D Picking
● 윈도우 좌표 → NDC 공간(투영 스페이스) 좌표
● NDC 공간의 좌표
X 값 : 피킹한 점 위치 / (WINCX * 0.5) - 1
Y 값 : 피킹한 점 위치 / (-WINCY * 0.5) + 1
Z 값 : 0 (near의 값)
W 값 : 1 (w나누기가 진행된 상태의 값)
윈도우 좌표 (600, 200)
X : 600 / (800 * 0.5) - 1 = 0.5
Y : 200 / (-600 * 0.5) + 1 = 0.33..
Z : 0
W : 1
18. 3D Picking
● NDC 공간(투영 스페이스) 좌표 → 뷰 스페이스 좌표
● 뷰 스페이스 상의 Z로 곱해주고 투영 행렬의 역행렬을 곱해준다.
투영 행렬의 역을 구하면 뷰 스페이스 1/Z 값이 W 값에 저장됨!
따라서 투영 행렬의 역행렬을 곱해주면 W를 곱해주는 역할도 같이 해준다.
19. 3D Picking
● 뷰 스페이스 :: 레이와 near위치
카메라 위치 - near평면의 위치를 빼면 뷰 스페이스 상의 마우스의 레이를 구할
수 있다.
20. 3D Picking
● 각 오브젝트의 폴리곤 정점들을 마우스의 정보가 있는 뷰 스페이스로 전부 변
환하는 것 보단
레이의 방향벡터의 시작점(카메라 위치)을 각 오브젝트의 로컬 좌표로 변환 하
는 것이 연산이 줄어든다. (당연한 말..)
뷰 스페이스 월드 스페이스 로컬 스페이스
21. 스터디 피드백
● 투영 역행렬 곱하는 과정 까지를 압축해서 값으로 만들어두면 연산량이 줄어
든다.
● GPU에서만 사용하는 마우스 피킹 방식도 있다.
- 해당 오브젝트를 해쉬 값을 만들어 렌더 타겟(스텐실버퍼)에 저장 후 마우스
를 찍은 위치의 픽셀이 어느 해쉬 값인지로 판단
(대신 GPU에서 계산하는 것이라 값을 가져오거나 하지는 못함,
https://gamedevforever.com/261)