3d 컴퓨터 그래픽스 기초

66
3D 컴퓨터 그래픽스 기초 이 슬라이드의 내용은 아직 오류나 적절하지 못한 설명을 포함하고 있을 수 있습니다. 최승준

Upload: seung-joon-choi

Post on 17-Aug-2015

752 views

Category:

Technology


1 download

TRANSCRIPT

Page 1: 3D 컴퓨터 그래픽스 기초

3D 컴퓨터 그래픽스 기초

이 슬라이드의 내용은 아직 오류나 적절하지 못한 설명을 포함하고 있을 수 있습니다.

최승준

Page 2: 3D 컴퓨터 그래픽스 기초

벡터

Page 3: 3D 컴퓨터 그래픽스 기초

‘르네 데카르트’ René Descartes 의 라틴식 이름은 Renatus Cartesius 이다. Catesius의 형용사 형태가 Cartesian.

직교 좌표계를 Cartesian coordinate system 이라고도 한다.

숫자 대신에 이름을 쓰는 대수(Algebra)와 기하학이 만나서 해석 기하학(Analytic geometry)을

이루는 쾌거. 덕분에 점과 선을 좌표로, 방정식을 그래프로 시각화해서 표현할 수 있게 됐다.

https://en.wikipedia.org/wiki/Cartesian_coordinate_system#History

Page 4: 3D 컴퓨터 그래픽스 기초

복소수(Complex)는 실수축과 허수축이 있는 2차원 평면상의 점으로 표현할 수 있다.

허수(Imaginary number)의 Imaginary라는 표현 또한 데카르트가 부르기 시작한 것인데,

다루기 어려워서 약간 깔보는 듯한 뉘앙스가 있었다고 한다.

그러다가 오일러 때에 와서야 다양한 방식으로 허수의 활용을 알아냈다.

https://en.wikipedia.org/wiki/Complex_number#History

https://en.wikipedia.org/wiki/Imaginary_number#History

레온하르트 오일러와 오일러의 등식

https://en.wikipedia.org/wiki/Euler%27s_identity

Page 5: 3D 컴퓨터 그래픽스 기초

윌리엄 해밀턴은 복소수는 평면에서의 점으로 표현할 수 있고, 기하학적으로 더하고

곱할 수 있다는 것을 알고 있었다. 이를 3차원 공간에서도 할 수 있는 방법을 고민하다가

(3차원에서의 회전 문제 등을 풀기 위해)

1843년 10월 16일, Dublin(아일랜드의 현재 수도)에 있는 Brougham 다리를 걷다

번뜩이며 떠오른 아이디어를 다리에 새긴다. 바로 사원수(Quaternion)에 관한 것이다.

https://en.wikipedia.org/wiki/History_of_quaternions

https://en.wikipedia.org/wiki/Quaternion

Page 6: 3D 컴퓨터 그래픽스 기초

사원수는 스칼라 부분 a와 i, j, k로 구성된 허수 부분으로 나뉘어 지는데

이 허수 부분을 벡터라고 부르게 됐다.

후대의 그라스만, 헤비사이드, 깁스 등이 이 벡터 해석학을 발전시켰다.

https://en.wikipedia.org/wiki/Vector_space#History

https://en.wikipedia.org/wiki/A_History_of_Vector_Analysis

벡터는 행렬과 통합되고 함께 선형대수(Linear algebra)라는 수학의 장르로

자리잡았다.

Page 7: 3D 컴퓨터 그래픽스 기초

기본적으로 수학은 어떤 특성을 가지는 수에 대해 관심을 가지고 탐구한다.

그리고 그 숫자들을 원소로 하는 집합과 체계에 관심을 가지고 탐구한다.

그런 숫자들의 관계에 대해서도 관심을 가지고 탐구한다.

그 관계가 일정한 규칙을 가지고 있는지, 다른 수의 체계에도 적용 가능한지를 탐구한다.

예를 들어 사칙연산이라는 연산(숫자들 사이의 관계)체계를 확립했다고 하자.

자연수에서 작동하는 것이 실수에서도 작동하는지 탐구할 수 있다.

실수에서 작동하는 방식과 일관성을 가지고 복소수에서도 사용할 수 있는지 탐구할 수 있다.

벡터나, 행렬 같은 수의 체계를 고안했을 때도, 그 체계에서 말이 되는 의미를 가지는

더하기, 빼기, 곱하기에 해당하는 것이 무엇이 있는지를 탐구하는 것이다.

이미 탐구를 해서 그 특성을 잘 알게된 수의 체계에 토대를 두거나 거기서 깨달은

방법을 응용하고 확장해 가며 다음 단계로 탐구의 지평을 넓혀간다.

벡터는 실수를 순서쌍(Tuple)으로 나열해서 표현할 수 있는 수의 한 체계이다.

유리수(분수), 무리수, 허수 등과 같이 이름지어 부를 수 있는 수의 체계다.

Page 8: 3D 컴퓨터 그래픽스 기초

벡터를 보통 크기와 방향을 가진 존재라고 표현한다. 화살표 모양으로 손쉽게 시각화 할 수 있다.

벡터를 표현하고자 하는 공간이 2차원이면 숫자 두 개의 순서쌍으로 표현할 수 있고, (x, y)

벡터를 표현하고자 하는 공간이 3차원이면 숫자 세 개의 순서쌍으로 표현할 수 있다. (x, y, z)

직교좌표계의 원점을 기준으로 한다면, 벡터를 표현하는 것은 어떤 점의 위치를 표현하는 것이기도 하다.

그런데 사실 벡터라는 수의 체계를 더 정교하게 짚어나가는데 앞서 중요한 것은

어떤 벡터가 같은 벡터이고 어떤 벡터가 다른 벡터냐 부터 판정하는 것이 중요하다.

(2, 3)

Page 9: 3D 컴퓨터 그래픽스 기초

아래의 벡터들은 서로 같은 벡터일까? 다른 벡터일까?

Page 10: 3D 컴퓨터 그래픽스 기초

이렇게 좌표계를 놓고 보면 아래의 벡터들은 서로 같은 벡터일까? 다른 벡터일까?

Page 11: 3D 컴퓨터 그래픽스 기초

모두 같은 벡터다. 시작 점이 어디있던 같은 크기와 같은 방향을 가지고 있는 벡터들이다.

Page 12: 3D 컴퓨터 그래픽스 기초

그렇다면 벡터는 무엇일까?

벡터는 끝점의 위치에서 시작점의 위치를 뺀 형태로 표현할 수 있다. 이 안에 크기와 방향이 다 들어있다.

벡터 (2 - 0, 3 - 0) = 벡터 (2, 3)

벡터 (5 - 3, 4 - 1) = 벡터 (2, 3)

Page 13: 3D 컴퓨터 그래픽스 기초

벡터의 어원을 살펴보면 ‘carrier’, ‘convey’ 등의 실어 나른다는 의미가 있다.

위 그림을 보면 시작점에 있는 것을 끝점으로 나르는 느낌이 난다.

그런 것이 벡터다. 벡터는 변화를 함의한다.

변화는 차이가 있을 때 생긴다. (앞 장에서 빼기 연산이 등장한 이유)

벡터에는 끝점과 시작점의 차이가 있다.

물론 끝점과 시작점의 차이가 없어 변화를 못 만들어 내는

영(0)벡터라는 것도 있다.

Page 14: 3D 컴퓨터 그래픽스 기초

그렇다면 벡터의 크기는 무엇일까?

벡터 (2, 3)

벡터의 크기는 시작점과 끝점 사이의 거리로 표현할 수 있다.

벡터의 각 성분을 제곱하고 제곱근을 씌워주면 된다. 피타고라스 정리가 등장할 때다.

Page 15: 3D 컴퓨터 그래픽스 기초

벡터의 방향은 무엇일까?

벡터 (2, 3)

의 크기는 이었다.

원래 벡터의 각 성분을 그 크기로 나눠주면 새로운 벡터

가 된다.

다시 이 벡터의 크기를 구하면

1 이 된다. 즉 방향은 원래 벡터와 같게 유지하지만

그 크기는 1인 벡터가 된다. 이렇게 자기 자신의 크기로 각 성분을

나눠 크기가 1인 벡터를 단위 벡터 또는 방향 벡터라고 한다.

거꾸로 단위 벡터에 스칼라 값을 곱해서 어떤 크기를 가지는

벡터를 만들 수도 있다. 앞에서 구한 단위 벡터에 을 곱하면,

원래대로 벡터 (2, 3)이 된다.

단위 벡터 또는 방향 벡터가 바로 벡터의 방향이다.

이렇게 자신의 크기로 나눠서

단위 벡터를 만드는 과정을

Normalize 라고 한다.

Page 16: 3D 컴퓨터 그래픽스 기초

벡터의 내적과 외적 (준비 중)

Page 17: 3D 컴퓨터 그래픽스 기초

카메라 프로젝션

Page 18: 3D 컴퓨터 그래픽스 기초

화면 오른쪽이 +x

화면 위쪽이 +y

화면 앞쪽이 +z

인 보통의 좌표계를

위에서 볼 때,

그림의 좌표계는

화면 오른쪽이 +x

화면 위쪽이 -z

인 좌표계이다.

+x

-z

Page 19: 3D 컴퓨터 그래픽스 기초

(3, 0, -4)

이 때 좌표

(3, 0, -4) 에

한 점이 있다.

+x

-z

Page 20: 3D 컴퓨터 그래픽스 기초

+x

-z이 때 좌표

(-3, 0, 1) 에

카메라가 있다.

이 카메라는

자신을 중심으로한

좌표계를 형성하는데,

그 중심에서

w 쪽을 바라보는

구도를 만든다.

u

w

(-3, 0, 1)

Page 21: 3D 컴퓨터 그래픽스 기초

즉, 카메라 중심으로

생각하면 한 점은

다음의 위치에 있는 것이다.

u

w

Page 22: 3D 컴퓨터 그래픽스 기초

두 좌표계를 병치해 놓고 보면 왼쪽의 월드 좌표계에서 카메라 좌표계로 어떻게 변환이 된 것인지를 잘 살펴 볼 수 있다.

Page 23: 3D 컴퓨터 그래픽스 기초

u

w

+x

-z

벡터 u, w 는 월드 좌표계의 y축을 중심으로 30도 만큼 회전한 것으로 설정했다. 반지름이 1인 단위원으로 생각하면, 30도는

theta = PI / 6

cos(theta) = 0.866

sin(theta) = 0.5

일 때,

u = [0.866, 0, 0.5]

w = [0.5, 0, -0.866]

으로 월드 좌표계에서의 벡터로

표현할 수 있다.

Page 24: 3D 컴퓨터 그래픽스 기초

-z

u

w

(-3, 0, 1)

+x

(3, 0, -4)

[0.866, 0, 0.5]

[0.5, 0, -0.866]

모든 정보를 합쳐보자

두 가지 변환을 섞어서

진행할 수 있다.

1. 방향 (회전)

2. 이동

Page 25: 3D 컴퓨터 그래픽스 기초

-z

u

w

(-3, 0, 1)

+x

[3, 0, -4]

[0.866, 0, 0.5]

[0.5, 0, -0.866]카메라를 월드 좌표의

중심에 임시로 놓으면

점의 좌표 (3, 0, -4) 를

월드 좌표의 원점을

시작점으로 하는

벡터 [3, 0, -4] 로

놓을 수 있다.

u, w는 크기가 1인

단위 벡터이고

어떤 벡터를 단위 벡터에

내적을 하면

사영(그림자)를 얻을 수

있다.

(회전이기도 하다.)

Page 26: 3D 컴퓨터 그래픽스 기초

u

w

(0.598, 0, 4.964)

[0.866, 0, 0.5]

[0.5, 0, -0.866]내적을 풀어서

u, w 좌표 평면에서의

녹색 점의 좌표를

구해보자.

dot([3, 0, -4], [0.866, 0, 0.5]) = 2.598 + 0 + -2 = 0.598

dot([3, 0, -4), [0.5, 0, -0.866]) = 1.5 + 0 + 3.464 = 4.964

Page 27: 3D 컴퓨터 그래픽스 기초

-z

w

[-3, 0, 1]

+x

[0.5, 0, -0.866]카메라 좌표계를 기준으로

했을 때, 카메라가 놓여있던

(-3, 0, 1) 만큼을 다시

카메라의 축에 맞춰서

이동해야지 원래 형태가

된다.

앞의 방식과 똑 같이

할 수 있다.

dot([-3, 0, 1], [0.866, 0, 0.5]) = -2.598 + 0 + 0.5 = -2.098

dot([-3, 0, 1), [0.5, 0, -0.866]) = -1.5 + 0 + -0.866 = -2.366

u [0.866, 0, 0.5]

Page 28: 3D 컴퓨터 그래픽스 기초

-z

u

w

+x

앞에서 구한 두 벡터의

차가 결국 원하는

카메라 좌표계로

변환된 좌표가 된다.

0.598 - (-2.098) = 2.696

4.964 - (-2.366) = 7.33

Page 29: 3D 컴퓨터 그래픽스 기초

두 좌표계를 병치해 놓고 보면 왼쪽의 월드 좌표계에서 카메라 좌표계로 어떻게 변환이 된 것인지를 잘 살펴 볼 수 있다.

(3, 0, -4)

(2.696, 0, 7.33)

+x

-z

u

w

Page 30: 3D 컴퓨터 그래픽스 기초

이 과정을 정리해 보자.

3차원 월드 좌표계는 3개의 방향벡터 x, y, z 로 이뤄져 있다. 여기서 x: [1, 0, 0], y: [0, 1, 0], z: [0, 0, 1] 로 각각 3차원 방향(단위) 벡터이다.

카메라는 월드 좌표계의 어떤 좌표 (eyex, eyey, eyez) 에 위치해 있다. 그리고 그 카메라가 바라보는 방향벡터 u, v, w 도

역시 월드 좌표계를 기준으로 한 3차원 방향벡터로 표현할 수 있다.

월드 좌표계에 점 p가 (px, py, pz) 가 있다고 하자. 이 점을 카메라 좌표계를 기준으로 하는 p’ 은 (pu, pv, pw) 로 변환하는 것이

카메라 프로젝션(투영)의 목적이다.

먼저 u, v, w와 [px, py, pz]의 내적을 구한다. (점의 좌표를 월드 좌표의 원점을 기준으로 하는 벡터로 간주했다)

이를 카메라 좌표계 u, v, w 상의 벡터 [ru, rv, rw] 라고 놓자.

ru = dot( [ux, uy, uz], [px, py, pz] ) = ux * px + uy * py + uz * pz

rv = dot( [vx, vy, vz], [px, py, pz] ) = vx * px + vy * py + vz * pz

rw = dot( [wx, wy, wz], [px, py, pz] ) = wx * px + wy * py + wz * pz

카메라의 월드 좌표 (eyex, eyey, eyez) 에 대해서도 똑같이 해준다. 이를 카메라 좌표계 상의 벡터 [tu, tv, tw] 라고 놓자.

tu = dot( [ux, uy, uz], [eyex, eyey, eyez] ) = ux * eyex + uy * eyey + uz * eyez

tv = dot( [vx, vy, vz], [eyex, eyey, eyez] ) = vx * eyex + vy * eyey + vz * eyez

tw = dot( [wx, wy, wz], [eyex, eyey, eyez] ) = wx * eyex + wy * eyey + wz * eyez

Page 31: 3D 컴퓨터 그래픽스 기초

ru = dot( [ux, uy, uz], [px, py, pz] ) = ux * px + uy * py + uz * pz

rv = dot( [vx, vy, vz], [px, py, pz] ) = vx * px + vy * py + vz * pz

rw = dot( [wx, wy, wz], [px, py, pz] ) = wx * px + wy * py + wz * pz

tu = dot( [ux, uy, uz], [eyex, eyey, eyez] ) = ux * eyex + uy * eyey + uz * eyez

tv = dot( [vx, vy, vz], [eyex, eyey, eyez] ) = vx * eyex + vy * eyey + vz * eyez

tw = dot( [wx, wy, wz], [eyex, eyey, eyez] ) = wx * eyex + wy * eyey + wz * eyez

월드 좌표계에 점 p가 (px, py, pz) 가 카메라 좌표계로 변환한 (pu, pv, pw) 는

pu = ru - tu

pv = rv - tv

pw = rw - tw

가 된다.

[ux, uy, uz]는 u로 표기하고, (v, w도 마찬가지)

[eyex, eyey, eyez]는 eye로 표기할 수 있다고 하자.

그러면 이 계산과정에 3차원에서 차원을 하나 더 확장한 4x4 행렬로 깔끔하게 표현할 수 있다.

pu = ux uy uz -dot(u, eye) px

pv = vx vy vz -dot(v, eye) py

pw = wx wy wz -dot(w, eye) pz

1 = 0 0 0 1 1

Page 32: 3D 컴퓨터 그래픽스 기초

pu = ux uy uz -dot(u, eye) px

pv = vx vy vz -dot(v, eye) py

pw = wx wy wz -dot(w, eye) pz

1 = 0 0 0 1 1

이렇게 카메라 프로젝션을 4x4 행렬로 표현하면 퍼스펙티브 프로젝션 및 다른 회전, 스케일, 이동 변환과

같은 형태가 되며 다양한 변환을 일관성 있게 4x4 행렬의 곱하기 문제로 다룰 수 있게 된다.

Page 33: 3D 컴퓨터 그래픽스 기초

퍼스펙티브 프로젝션

Page 34: 3D 컴퓨터 그래픽스 기초

Clip space 와 NDC

Page 35: 3D 컴퓨터 그래픽스 기초

(-1, 1 ) ( 1, 1 )

(-1, -1 ) ( 1, -1 )

OpenGL은 보여줄 사물을 구성하는 점들을 2차원 Clip space 안에 투영한다.

Clip space 안에 들어가면 보여주고, 넘어가면 경계선 밖은 보여주지 않는다.

Page 36: 3D 컴퓨터 그래픽스 기초

(-1, 1, -1 ) ( 1, 1, -1 )

(-1, -1, -1 ) ( 1, -1, -1 )

Clip space 안에 투영된 2차원 점들은 화면 가까이 올수록 -1의 깊이를 가지고,

화면 뒤로 멀어질 수록 +1의 깊이를 가지며 그 사이의 영역을 넘어가면 보이지 않는다.

이를 NDC (Normalzied Device Coordinates) 라고 한다.

OpenGL과 여기에 등장하는 수학이 하는 일은 3차원 상의 점들을 2차원에 투영하고 NDC 안에 놓는 일이다.

(-1, 1, 1 ) ( 1, 1, 1 )

(-1, -1, 1 ) ( 1, -1, 1 )

Page 37: 3D 컴퓨터 그래픽스 기초

Local space → World space사물을 구성하는 점들의 위치를 원점에 대한 좌표로 표현하는 공간

Page 38: 3D 컴퓨터 그래픽스 기초

다음과 같이 정육면체를 화면에 그리고자 할 때 가장 먼저 생각해야 하는 것은,

정육면체를 구성하는 점들의 좌표를 정의하는 것이다.

Page 39: 3D 컴퓨터 그래픽스 기초

정육면체는 3차원 공간 상의 좌표 (0, 0, 0) 을 중심으로 있다. 이 때 정육면체를 구성하는 점들의 좌표는 다음과 같다.

이 때 화면 밖으로 나오는 쪽을 +z 방향으로 놓는다. NDC와 비교했을 때 z 방향이 다름을 주의하자.

v0: ( 1, 1, -1 )

v1: ( 1, -1, -1 )

v2: (-1, -1, -1 )

v3: (-1, 1, -1 )

v4: ( 1, 1, 1 )

v5: ( 1, -1, 1 )

v6: (-1, -1, 1 )

v7: (-1, 1, 1 )

사물을 표현할 때는 오른손 좌표계로 놓기로 약속했을 뿐이다. 오른손에서 검지가 향하는 방향을 화면 오른쪽으로 놓고,

중지가 향하는 방향을 화면 위쪽으로 놓으면, 엄지가 향하는 방향은 화면 밖으로 향하는 방향이 된다.

처음에 그렇게 정한 것이 이어져 왔을 뿐이다. 정육면체의 중심점과 원점이 일치하니까 Local 과 World space는 같다.

이 World space를 기준으로 하면 View space (카메라 좌표계)는 다음과 같이 생각할 수 있다.

Page 40: 3D 컴퓨터 그래픽스 기초

World space → View space눈 또는 카메라를 중심으로 놓고 생각하는 공간.

사물의 좌표는 View space에 맞게 변환한다.

View space는 Eye space 또는 Camera space 라고도 한다.

Page 41: 3D 컴퓨터 그래픽스 기초

World space 에서

카메라의 위치는 좌표 (0, 0, 10) 이고 정육면체의 중심인 (0, 0, 0)을

바라보도록 놓자. 이 때 카메라는 +y 방향으로 서있다.

Field of view (FOV y, 화각)는 60도이고,

Near plane은 0.1

Far plane은 100

으로 설정했다. 여기서 Near plane과 Far plane은 뭘까?

FOV y 에서 y는 +y 방향으로 서있을 때의 화각을 의미한다.

Page 42: 3D 컴퓨터 그래픽스 기초

Near plane과 Far plane은 시야의 한계를 설정하고 (그 둘 사이에 있어야만 보인다)

이후 Near plane은 NDC의 z축 -1에, Far plane은 NDC의 z축 +1에 대응하게 된다.

컴퓨터는 무한을 다루기에 적합하지 않다. 때문에 필요한 만큼을 잘 표현할 수 있는

유한한 공간을 만들기 위해 Near, Far plane이 필요하다.

Near가 0이 아니라 어떤 작은 값을 가져야 하는 이유는 0으로 나누지 않기 위함인데,

이는 나중에 다시 설명하도록 한다.

Page 43: 3D 컴퓨터 그래픽스 기초

카메라를 중심 (0, 0, 0)으로 놓는 좌표공간을 생각하면?

정육면체를 구성하는 점들은 Word space의 -z축 방향으로

놓이게 된다.

이 때 점들의 좌표는 어떻게 될까?

60도의 화각

FOV y

Page 44: 3D 컴퓨터 그래픽스 기초

카메라의 좌표는 (0, 0, 0)

정육면체의 중심 좌표는 (0, 0, -10) 이 되고,

따라서 각 점들은 다음과 같이 바뀐다.

v0: ( 1, 1, -1 ) → ( 1, 1, -11 )

v1: ( 1, -1, -1 ) → ( 1, -1, -11 )

v2: (-1, -1, -1 ) → (-1, -1, -11 )

v3: (-1, 1, -1 ) → (-1, 1, -11 )

v4: ( 1, 1, 1 ) → ( 1, 1, -9 )

v5: ( 1, -1, 1 ) → ( 1, -1, -9 )

v6: (-1, -1, 1 ) → (-1, -1, -9 )

v7: (-1, 1, 1 ) → (-1, 1, -9 )

Page 45: 3D 컴퓨터 그래픽스 기초

View space → Clip space카메라를 중심으로 놓고 생각한 사물을 구성하는 3차원 점의 좌표를

2차원 Clip space에 투영하기

Page 46: 3D 컴퓨터 그래픽스 기초

알베르히트 뒤러(Albrecht Durer)의 류트 그리기

가까이 있는 것은 화면 중심에서 멀게,

멀리 있는 것은 화면 중심에 가깝게

Page 47: 3D 컴퓨터 그래픽스 기초

v0: ( 1, 1, -11 ) → ( 1/11, 1/11 ) → ( 0.09, 0.09 )

v1: ( 1, -1, -11 ) → ( 1/11, -1/11 ) → ( 0.09, -0.09 )

v2: (-1, -1, -11 ) → (-1/11, -1/11 ) → (-0.09, -0.09 )

v3: (-1, 1, -11 ) → (-1/11, 1/11 ) → (-0.09, 0.09 )

v4: ( 1, 1, -9 ) → ( 1/9, 1/9 ) → ( 0.11, 0.11 )

v5: ( 1, -1, -9 ) → ( 1/9, -1/9 ) → ( 0.11, -0.11 )

v6: (-1, -1, -9 ) → (-1/9, -1/9 ) → (-0.11, -0.11 )

v7: (-1, 1, -9 ) → (-1/9, 1/9 ) → (-0.11, 0.11 )

각 점의 x, y 좌표를 (반전되지 않도록) -z 성분으로 나눠주면

카메라에서 멀리 있는 점이 화면 중심에 더 가까이 온다.

Page 48: 3D 컴퓨터 그래픽스 기초

화각(FOV y)의 적용-z 성분으로 나눠주는 것 만으로도 원근의 효과를 얻었지만,

화각까지 고려해 보자.

Page 49: 3D 컴퓨터 그래픽스 기초

ABCDABCD

사물이 3차원의 World space에 있다가,

View space로 변환되고, 2차원 Clip space에

투영될 때, (정면에서 보기 편하게 좌, 우로 배치)

위 그림에서 B, C의 높이는

Clip space의 +y 방향의 경계인 +1이 되어야 한다.

시야 안에 사물이 얼마만큼 들어오냐를

화각이 결정한다. (FOV y 를 반으로 나눈 각도)

눈으로 부터 B, C의 거리는 다르지만

투영된 높이는 같다 .

60도의 화각

FOV y

Page 50: 3D 컴퓨터 그래픽스 기초

직각삼각형 ABC에서 선분의 길이의 비 CD : CB = FG : FE = IJ : IH 는 모두 같다.

점 A에서의 각도를 θ 로 놓으면

임을 알 수 있다. IH의 길이가 1인 IJ : IH 비율이 CD : CB 와 같으므로, CD / (AC * tan(θ)) 가 Clip space에서 y방향 경계가 1일 때, 그 안에 들어오는

물체의 높이가 투영된 것임을 알 수 있다. 즉, 사물이 Clip space에 투영되는 것은 화각이 만드는 높이에 대한 비율(얼마나 높은지)인 셈이다.

Page 51: 3D 컴퓨터 그래픽스 기초

60도의 화각

FOV y

( z, y )

점의 z좌표와 y좌표를 알면, 화각 안에 놓이는

View space의 3차원 좌표를 2차원 Clip space로

투영할 수 있다. -z인 이유는 앞에서와 마찬가지로

각 점들의 좌표가 눈의 좌표로 부터 음의 z값을 가지고

있기 때문에 이를 양수로 바꿔주고 x, y를 나눠줘야

x, y의 부호가 바뀌지 않기 때문이다.

화각의 기준이 되는 기울기(비율)은 tan(fovy / 2) 이다.

* FOV y 를 수식 안에서는 fovy로 놓았다.

Page 52: 3D 컴퓨터 그래픽스 기초

Clip space 화면의 +y 방향에 가득차도록 투영된

물체의 높이는 1이다. 어떤 물체의 높이가 이 높이보다

높으면 화면 위 쪽의 잘린 부분은 나오지 않고,

낮으면 1보다 낮은 값으로 투영된다.

FOV y가 60도(PI/3) 일 때, tan(fovy) = 0.577 이다.

어떤 점의 View space 상의 좌표가

z가 -10이고 y는 5.77 정도 일 때, 현재 화각으로

Clip space에 투영된 y는 1이 된다.

60도의 화각

FOV y

( z, y )

Page 53: 3D 컴퓨터 그래픽스 기초

View space (x, 5.77, -10) 은 투영되어

Clip space (x’, 1) 이 되었다면,

View space (x, 5, -10)의 투영된 Clip space 좌표는

무엇인가? y 값을 -z tan(fovy / 2) 로 나눠주면 된다.

z가 -10이고 tan(fovy / 2) 가 0.577 일 때

-z tan(fovy / 2) = 5.77 이므로,

5 / 5.77 = 0.866 정도로 1보다 작아진다.

이는 5.77 : 1 = 5 : y 의 비례식을 푸는 것과 같다.

60도의 화각

FOV y

( z, y )

Page 54: 3D 컴퓨터 그래픽스 기초

v0: ( 1, 1, -11 ) → ( 0.16, 0.16 )

v1: ( 1, -1, -11 ) → ( 0.16, -0.16 )

v2: (-1, -1, -11 ) → (-0.16, -0.16 )

v3: (-1, 1, -11 ) → (-0.16, 0.16 )

v4: ( 1, 1, -9 ) → ( 0.19, 0.19 )

v5: ( 1, -1, -9 ) → ( 0.19, -0.19 )

v6: (-1, -1, -9 ) → (-0.19, -0.19 )

v7: (-1, 1, -9 ) → (-0.19, 0.19 )

View space 에 있는 각 점의 x, y 좌표를

-z tan(fovy / 2) 로 나눠주면

Page 55: 3D 컴퓨터 그래픽스 기초

Clip space 에서 화면비(Aspect ratio) 보정Clip space를 화면비에 맞춰서 펼쳐주기 위한 준비가 필요하다.

Page 56: 3D 컴퓨터 그래픽스 기초

Clip space 인 -1 ~ 1 사이의 영역에서 그려보면 이렇게 된다.

이를 화면 비가 16:9 인 화면에 맞추면 어떻게 될까?

Page 57: 3D 컴퓨터 그래픽스 기초

이렇게 물체가 찌그러지게 된다.

이를 보정하기 위해서 x 좌표를 화면비(16 / 9) 만큼 나눠준다.

Page 58: 3D 컴퓨터 그래픽스 기초

그리고 다시 화면비(16/9)에 맞춰서 펼쳐주면 비율이 맞는 그림이 된다.

이렇게 하는 이유는 OpenGL을 -1~1 이라는 편리한 공간에 그리면

실제 (잠재적)픽셀로 표현할 때(Rasterization) 화면 크기가 몇 픽셀이던 손 쉽게 렌더링 할 수 있기 때문이다.

Page 59: 3D 컴퓨터 그래픽스 기초

View space

(x, y, z)

aspect 는 화면비

Clip space

x’ = x / (-z * aspect * tan(fovy / 2))

y’ = y / (-z * tan(fovy / 2))

f = 1 / tan(fovy / 2) 로 놓으면,

x’ = x * f / (-z * apsect)

y’ = y * f / (-z)

분모의 -z가 나중에 중요한 역할을 한다.

여기까지 내용을 정리하면,

Page 60: 3D 컴퓨터 그래픽스 기초

Clip space → NDCNear, Far plane을 설정했던 이유, Clip space 상의 어떤 점이 더 앞에 있는지를

판별하는 Depth buffer를 구성할 준비, w의 등장

Page 61: 3D 컴퓨터 그래픽스 기초

Clip space에 그려질 점들의 x, y 좌표를 NDC로 확장하려면 각 점들의 좌표에 깊이 값을 알아야 한다.

View space의 Near plane에서 Far plane 사이에 있는 점의 z좌표는 NDC에서는 -1 ~ 1 사이에 있게 된다.

View space의 z는 음의 방향이므로

Near: 0.1

Far: 100

이라면

-Near: -0.1

-Far: -100

로 -0.1 ~ -100

사이가 되는 것이다.

Page 62: 3D 컴퓨터 그래픽스 기초

어떤 수의 범위 z를, 다른 범위 z’으로 맵핑(Mapping)은

z에 어떤 수 A를 곱하고, 거기에 다시 B를 더하는 형태로 할 수 있다.

예를 들어 z: 0 ~ 1 의 범위이다. 이것을 z’: -1 ~ 1 의 범위로 바꾸려면

z에 2를 곱하고 -1을 더해주면 된다.

그래프 상의 선의 크기를 늘리거나 줄이고, 이동하는 상을 잡으면 쉽다.

아래의 경우 A: 2 이고, B: -1 이다.

z’ = A * z + B

Page 63: 3D 컴퓨터 그래픽스 기초

View space 상의 점은 -Near plane 에서 -Far plane 상에 있을 것이다.

Near: 0.1

Far: 100

인 경우, View space 상의 -0.1 ~ -100 사이에 있는 어떤 점의 z좌표를 NDC 상의 z’ 좌표 -1 ~ 1 에 맵핑하고자 한다.

z가 -Near인 -0.1에 있을 때 z’은 -1이 되고,

z가 -Far인 -100에 있을 때 z’은 1이 된다.

이를 만족하는 A, B는 무엇일까? A, B를 Near와 Far로 표현해 보자.

z’ = A * z + B

A * (-Near) + B = -1

A * (-Far) + B = 1

Page 64: 3D 컴퓨터 그래픽스 기초

[1] A * (-Near) + B = -1

[2] A * (-Far) + B = 1

[1] 에서 [2] 를 빼면 B를 소거할 수 있다.

[3] A * (-Near + Far) = -2

[4] A = 2 / (Near - Far)

[4] 를 [1]에 대입하면,

[5] 2 * (-Near) / (Near - Far) + B = -1

[6] B = -1 + 2 * Near / (Near - Far)

[7] B = (-(Near - Far) + 2 * Near) / (Near - Far)

[8] B = (Near + Far) / (Near - Far)

Page 65: 3D 컴퓨터 그래픽스 기초

Near는 0.1 이고 Far는 100 일때 Near - Far는 -99.9 이고, Near + Far는 100.1 이다.

z가 -Near인 -0.1 에 있으면 -1, -Far인 -100 에 있으면 1이 된다. 이를 그래프로 그려보자.

이 그래프를 볼 때 한 가지 문제가 생긴다. OpenGL에서 깊이 버퍼에는 보통 16비트가 사용되는데,

이는 65536단계에 불과하다. 그러다 보니 분명 차이가 있지만 같은 깊이를 가지게 되어

Z-fighting 이라고 불리는 겹침 현상이 나타날 가능성이 높아진다.

때문에 Near plane에 가까울 수록 더 많은 비트를 할당하는 다른 방법이 필요하다.

z’ = (2 * z + 100.1) / (-99.9)

https://en.wikipedia.org/wiki/Z-fighting

Page 66: 3D 컴퓨터 그래픽스 기초

z 대신에 1 / z 를 활용해서 z-fighting도 해결하고 1/(-z)를 공통으로 묶어줘서

4x4 동차(homogeneous) 좌표계를 구성하는 4x4 행렬을 만드는 부분은

아직 슬라이드를 만들지 않았음