WinCNT

변환 파이프라인 본문

게임 프로그래밍(학습 내용 정리)/게임 수학

변환 파이프라인

WinCNT_SSS 2022. 1. 4. 15:08

로컬 좌표계(= OpenGL에서는 모델 좌표계)

오브젝트의 좌표계

 

월드 좌표계

3차원 공간 좌표에 오브젝트들을 배치

오브젝트를 배치하기 위한 월드 행렬

각각의 오브젝트마다 필요하다

 

변환행렬(TM)이 없으면 각각의 오브젝트는 원점에 겹쳐서 보일 것이다

변환행렬을 각각의 오브젝트마다 적용해서 월드 좌표에 배치할 수 있다

 

월드 행렬이라고도 하고 Transform 행렬(TM)이라고도 한다

월드 좌표계로 보내기 위한 TM이 필요함

 

카메라 좌표계

월드 좌표계에 카메라 행렬을 곱하면 나오는 좌표계

그것을 보기 위한 카메라가 필요하다

(실제 렌더링에는 하나의 카메라만 작동)

 

카메라의 변환 행렬(View 행렬이라고도 함)은 월드 행렬의 역변환으로 구할 수 있다

(카메라 행렬 - 카메라를 원점으로 위치시키는 행렬)

 

카메라 행렬은 월드 좌표계의 카메라의 위치를 원점으로 바꾸는 행렬과,

카메라의 위치가 원점으로 바뀜에 따라 월드 좌표계를 변환시키는 행렬의 곱으로 정의된다

 

상용 엔진 등의 영향으로, 여기서 카메라를 오브젝트로 착각할 수 있지만

월드 좌표계에 실제로 카메라라는 오브젝트는 필요 없다

카메라의 위치와 카메라가 향하는 벡터가 필요할 뿐

카메라 행렬(뷰 행렬, 뷰 변환 행렬)은 설정한 카메라를 원점으로 하고 싶을 경우,

월드 좌표계를 어떻게 선형 변환시키면 되는가에 대한 행렬이다

 

변환 파이프라인을 보면 

Vc = Vw(월드 좌표계, 월드 버텍스) X Mv(뷰 변환 행렬)

로 정의되어 있다.

즉, 카메라 좌표계는 월드 좌표계를 변환시키는 것이다.

카메라를 이동시킨다는 것은 개념을 위한 비유일 뿐이고,

실제로는 월드 좌표계를 선형 변환시키는 것이다

 

참고 사이트)

https://blog.naver.com/PostView.naver?blogId=destiny9720&logNo=221411770100&categoryNo=22&parentCategoryNo=22&from=thumbnailList# 

 

25. 벡터의 외적(Cross Product)

지난 시간에 3D 공간의 트랜스폼과 회전에 대해 알아보았다. 이번에도 3D 공간의 회전에 대해서 다루어보...

blog.naver.com

 

카메라 위치가 있고 벽면에  3차원 공간에서 4 X 4 행렬을 사용한다

x, y, z, w

w의 값에 따라 행렬이 벡터가 되기도 하고 버텍스가 되기도 한다

w가 0일 때는 벡터, w가 1일 때는 버텍스

w가 0일 때는 이동 행렬에 집어넣어도 이동을 하지 않는다

(w가 1일 때는 이동함)

회전 행렬은 둘 다 적용된다

 

카메라의 위치와 물체의 좌표가 있으면 거리 벡터를 구할 수 있다(빼기로)

카메라의 상방 벡터가 있으면

 

카메라(뷰) 변환 유도

카메라는 가만히 있으면서 나머지 공간을 변환시킴(역변환)

함수에 필요한 것은 p(타겟 좌표), c(카메라 좌표), up(상방 벡터)

 

 

투영 좌표계

2가지 존재한다

 

직교 투영 좌표계

거리 값이 계산이 안 되는 좌표계

블렌더 등에서 사용하기도 한다

혹은 3D 그래픽스로 2D 게임을 만들 때

 

원근 투영 좌표계

원근감이 필요한 3D게임 등에 사용되는 투영 좌표계

 

절두체(Frustum)란 것이 존재한다

절투체를 정의하기 위해서는 총 6장의 평면(Plane)이 필요함

near, far, left, bottmo, right, top의 6개의 Plane

 

모든 오브젝트들은 프러스텀 범위 안에 있는 것만 그려야 한다

near 플레이 앞에 있는 것도 안 그려짐

물리와는 상관 없다(!!) 오로지 그리냐 마냐의 문제

그릴 때는 행렬 연산이 필요한데 그릴 필요가 없는 것은 연산에서 배제해야 한다

이것이 컬링(혹은 컬링 아웃)이다

 

행렬 계산 전에 프러스텀을 체크해서 미리 제외시키면

원근 투영 변환에서는 깊이 z 값은 0~1로 바뀜

카메라와 near 사이에 오브젝트가 있어도 그려지지 않음

 

depth값

far 플레임의 값을 프로그래머가 줄 수 있다

far가 depth(0~1)의 1에 대응되도록 바뀜

 

일반적으로 far plane의 값을 1000으로 준다

왜냐면은 너무 클 수록 계산의 정밀도가 떨어지기 때문이며

Z-fighting 현상이 발생할 수 있다

 

 

번외) 평면

P0에서 P로 향하는 벡터(P-P0)와 법선 벡터가 항상 90도인 점들의 집합

노말이랑 내적을 해서 0이 나오는 점의 집합

 

모든 평면에는 법선 벡터가 존재한다

결과값 의미
점이 평면 위에 있다.
점이 평면 앞에 있다.
점이 평면 뒤에 있다.

 

점을 임의의 평면에 넣어 본다

양수면 그리기, 음수면 안 그리기로 컬링을 구현할 수 있다

 

물론 버텍스를 전부 계산하면 시간이 너무 걸기 때문에

오브젝트를 감싸는 구(스피어) 등을 넣어서 계산한다

이것을 바운딩 스피어 - 경계구라고 한다

 

바운딩 지오메트리

구가 가장 계산하기 쉬우며

상자(Box), 원통(실린더)는 계산이 더 어렵다

하지만 캐릭터의 경우는 원통이나 박스가 좀 더 자연스러움

 

바운딩 스피어, 박스, 실린더가 절두체에 조금이라도 걸치면 그리기 처리를 한다

 

평면과 바운딩 스피어의 충돌 처리

평면의 방정식에 원의 중심을 넣고 반지름을 더한다

그 때 양수이면 그리고 음수이면 그리지 않는다

 

키워드 정리

클리핑

삼각화 - 픽셀를 그릴 때 삼각형으로 그리기 때문에 필요함

Scan Line

위의 것들은 Rasterizer의 역할(D3D, OpenGL이 요즘엔 해줌)

 

프로그래머는 레이터라이저 위에서 엔진을 만드는 게 일

(D3D, OpenGL을 Rasterizer라 부르는 사람들도 있음)

 

Lay Tracing(광선 추적)

빛 포톤(광자) 물체에 반사(색)

시신경 - 픽셀로 인지

빛에 해당하는 소스를 추적해가면 결국 무엇을 그려야할지 알 수 있다

몇 번 반사하냐도 정할 수 있다

 

Backward Tracing

실제 광자가 많다고 해도 실제로 눈에 들어오는 광선은 일부분

그래서 반대로 눈에서 역추적해서

실제로 그려질 것만 추적하면 연산을 줄일 수 있다

(대부분은 Backward Tracing으로 처리할 수 있다)

 

하지만 안 되는 부분도 있음(Caustics, 화점)

따라서 Lay Tracing과 Backward Tracing은 섞어서 쓴다

 

Caustics를 위해 한 때 나왔던 기법이 photon mapping

요즘에는 Lay Tracing으로 다 됨

 

SSS

'게임 프로그래밍(학습 내용 정리) > 게임 수학' 카테고리의 다른 글

조명 처리  (0) 2022.01.11
계층 구조와 애니메이션 보간 기초  (0) 2022.01.11
좌표계  (0) 2021.12.28
행렬  (0) 2021.12.21
삼각비와 삼각 함수  (0) 2021.11.09