상세 컨텐츠

본문 제목

개념 3D 이해 5.프로젝션 변환

프로그래밍/3D

by ∫2tdt=t²+c 2008. 11. 17. 23:55

본문

전편에 뷰 변환을 통해서 모델 공간에 있는 물체를 뷰 공간으로 변환할수 있었다. 카메라의 입장에서 물체를 볼 수 있게 된것이다. 그러나 모니터에 물체를 띄우려면 아직도 멀고 험한 길이 기다리고 있다.
모니터는 2차원 평면이다. 하지만 3차원 물체는 말 그대로 3차원인데 어떻게 2차원 평면에 나타내나?
정답은 축을 하나 버리는 것이다. 3차원에서 축 하나를 버리면 2차원이 되므로 평면에 그릴수 있다.








1
0
0
0







0
1
0
0
0
0
0
0
0
0
0
1
뷰 변환이 끝난 점들에 이 행렬을 곱해보자.
[x,y,z,1]에 이 행렬을 곱하면 [x,y,0,1]이 된다. 이제 이 x,y값을 가지고 모니터에 그려주면 땡이다.

라고 말하면 회이크다. 이렇게 하면 원근감이 전혀 없는 그야말로 평면적인 모습이 될것이다. 게다가 앞에 있는 것 뒤에 있는 것 구분도 안될것이다.
멀리있는 물체는 작게, 가까이있는 물체는 크게 보여야하고, 멀리 있는 물체는 가까이있는 물체에 가려져야 한다.

깊이감을 위해 일단 z값을 0에서 1사이로 들어오게 해보자. 그러기 위해서는 가장 멀리 볼수 있는 거리와 가장 가까이 볼수 있는 거리를 정해야한다. 가장 먼 거리에 있는 놈에게는 z값을 1로, 가장 가까이에 있는 놈에게는 z값을 0으로준다. 그리고 화면에 물체를 그려줄때 이 값을 기준으로 z값이 큰 것부터 그려준다면 멀리있는 물체가 가까이 있는 물체에게 가려질 것이다.








1
0
  0
 0







0
1
  0
 0
0
0
  Q
 1
0
0
-Q*Zn
 0
Q=Zf/(Zf-Zn)
Zf: 가장 멀리 볼수 있는 거리
Zn: 가장 가까이 볼수 있는 거리
행렬이 조금 복잡해 보일수 있다. 점 몇개를 선택해서 곱해보자.
[x,y,z,1]에 이 행렬을 곱하면
[x,y,Q*z-Q*Zn,z]가 된다.
여기서 z축의 값 Q*z-Q*Zn에 주목해보자.
Q*z-Q*Zn=Q*(z-Zn)=Zf/(Zf-Zn)*(z-Zn)

만약에 z가 Zn이라면
Zf/(Zf-Zn)*(z-Zn)=Zf/(Zf-Zn)*(Zn-Zn)=0 이 되고

만약에 z가 Zf라면
Zf/(Zf-Zn)*(z-Zn)=Zf/(Zf-Zn)*(Zf-Zn)=Zf 가 된다.

어 Zf일때 z값이 1이 되야하는데 이거 뭐가 좀 이상한듯. 물론 아직 끝나지 않았다.
마무리로 [x,y,Q*z-Q*Zn,z]에서 모든 성분을 z로 나누어 네번째 성분을 1로 맞춰주자.
[x/z,y/z,(Q*z-Q*Zn)/z,1]이 된다.

다시 세번째 성분에 주목해보면
Q*(z-Zn)/z=Zf/(Zf-Zn)*(z-Zn)/z이고
z가 Zn일때는 0,
z가 Zf일때는 1이 된다.

게다가 z값이 커질수록 x성분 y성분의 크기가 반비례해서 작아진다.
이것은 멀리 있을수록 크기가 작아진다는 뜻->고로 원근감을 주는 효과가 된다는 말이다.

이 행렬은 프로젝션 변환을 하는데 쓰인다. 번역하자면 투영변환 정도로 할수 있다.
3차원공간의 물체를 2차원 평면에 투영하는 변환이라는 것이다.

한번 시험삼아 계산해보자.
Zn=1, Zf=10이라고 하자.(우리는 z값이 1에서 10사이인 물체들을 볼수 있는 것이다.)
 변환전 [1,1,1,1] [1,1,2,1]
[2,2,2,1]
[4,4,10,1]
 프로젝션 변환후 [1,1,0,1]
[0.5,0.5,0.555,1]
[1,1,0.555,1]
[0.4,0.4,1,1]
점 4개를 한번 변환해보았다.
[1,1,1,1]에 있는 점이나 [2,2,2,1]에 있는 점이나 둘다 x,y성분이 1인것으로 보아 겹쳐보일거다.
근데 z값이 작은 [1,1,1,1]이 더 가까이 있는 것이므로 [1,1,1,1]이 앞에 보인다.

관련글 더보기

댓글 영역