1학기 결산-게임엔진프로그래밍활용

이미지
1. 브레젠험 직선 알고리즘 컴퓨터에서 계산이 느린 실수 연산을 사용하지 않고 직선을 그리기 위해 만들이진 알고리즘입니다. 평면을 아래와 같이 8분 면으로 나누어 직선을 그립니다. 링크:  https://sulinep.blogspot.com/2020/05/bresenhams-line-algorithm.html 2. 엔진 기초 수학 여기서는 본격적으로 구현에 들어가기 전 기초 수학 지식을 쌓았습니다.  수학에서의 체는 대수적 구조의 하나로 덧셈, 뺄셈, 곱셈, 나눗셈의 사칙연산을 집합 안에서 소화할 수 있는 집합을 의미합니다. 체를 이루기 위한 조건과 체라는 개념을 알아보았습니다. 처음에 체 라는 개념이 뭔가 머릿속에서 애매했는데 이후 갈로이스 체에 대해 배운 후 조금 더 명확해졌습니다. 스칼라 는 벡터를 정의하기 위한 필수 요소이고 크기만 있고 방향이 없는 성분이다. 벡터는 크기와 방향을 포함하는 표현 도구이다. 겨기서 벡터의 기본 연산자들을 알아보았습니다. 선형성 은 직선처럼 똑바른 도형 또는 그와 비슷한 성질을 가진 대상이라는 뜻으로 함수의 경우 함수가 진행하는 모양이 직선이라는 의미로 사용된다. 선형성을 만족하려면 두 가지 조건을 만족해야 하는데 균질성과 첨가성이다. homogeneity (균질성):   additivity (첨가성): 선형이라고 부르는 수식들은 중첩의 원리 가 적용된다는 특징이 있다. 이때 행렬과 선형 변환의 관계에 대하여도 알아보았었는데 선형 변환과 행렬은 1:1 대응된다. 기저 란 어떤 벡터 공간을 선형 생성하는 선형 독립인 벡터들이다. 각각의 원소들이 다시 벡터 공간을 생성할 수 있어야하고 일차 독립이어야 한다. 표준 기저 는 많은 기저들 중 성분 1개만이 1이고 나머지 성분이 모두 0인 표준 적인 벡터이다. 여기서 벡터 공간 R의 기저를 구성하는 원소의 개수가 해당 공간의 차원 이다. 행렬 은 열기반 행렬과 행기반 행렬 중 어떤 걸 사용하느냐에 따라 계산 방식이 달라진다. 여기서는 벡터의 크기, 회전, ...

카메라 - 투영 보정 매핑

1. 투영 보정 매핑

1) 문제점

앞전에 원근 투영에 대해 알아보았습니다.
하지만 그대로 사용하면 문제가 한 가지 있습니다.
바로 투영된 무게 중심 좌표가 달라지는 문제입니다.

이전에는 선으로만 3D 큐브를 그려서 별로 티는 안났지만 텍스처가 입혀지면 다릅니다.
















스티브의 얼굴이 찌그러져서 매핑된 것을 볼 수 있습니다.


















위의 그림을 보면 프러스텀 각 끝 영역에 걸친 초록색 물체가 투영된 P1, P2의 가운데 위치한 P의 무게 중심 좌표는 0.5입니다.
하지만 초록색 물체를 보면 실제 무게 중심 좌표는 0.5가 아닙니다.
그래서 맨 위의 사진처럼 스티브의 얼굴이 카메라의 각도에 따라 찌그러집니다.
이런 현상을 해결하기 위해서는 실제 물체의 무개 중심 좌표가 필요합니다. 
이러한 역할을 하는게 투영 보정 매핑 (Perspective Correction Mapping)이라고 합니다.



2) 해결 방법 및 원리

일단 현재 알고 있는 것들은
NDC 좌표계로 산출된 무게 중심값 
삼각형의 각 점의 NDC 좌표와 Clip 좌표계의  값 



















NDC 좌표의 중심 좌표를 q라고 보고 실제 중심 좌표를 t 라고 볼때 
q를 기반으로 t의 값을 구하게 됩니다.

우선 한가지 특징을 알고 넘어가야 합니다.
위에서 Clip 좌표계를 NDC 좌표계로 바꿀때 의 값 즉 의 값을 나누어 줍니다.
이것으로 NDC 좌표계는  의 값에 반비례 한다는 것을 알 수 있습니다.

즉 뷰가 커질 수록(물체가 카메라로 부터 멀어짐) NDC의 좌표 값은 작아지고 
뷰가 작아질 수록(물체가 카메라로 부터 가까워짐) NDC 좌표 값은 커집니다.

다음은 그래프로 조금 더 자세하게 알아보겠습니다.

원근 투영 최종 행렬을 곱한 Clip 좌표계를 NDC 좌표계로 바꿀 때,  값을 나누어 주는 과정을 거칩니다.















점  (0,1,2) 와 점  (0,1,6)가 있습니다. 이때 그래프를 보면 이 점들 사이의 중점은 (0,1,4) 입니다.

이를 투영하면 각각 다음과 같이 볼 수 있습니다.

하지만 투영 후의 값으로 보간한다면  이기 때문에 중점 값이 


이 되버립니다. 하지만 위의 값은 실제 무게 중심 값과 틀리게 나옵니다.
따라서 이 내용들을 기반으로 실제 값을 찾아내야 합니다. 


일단 쉽게 두 점에 대하여 생각해보겠습니다.
NDC 좌표 값으로부터 산출된 비율 값으로 보간된 z'를 구하는 식을 적으면 다음과 같습니다.


이를 뷰 좌표계의 실제 비율 t 값으로 구하는 경우에는 다음과 같이 볼 수 있습니다.


이때 위의 수식을 뒤집으면 


가 되고 이 수식은 다음과 같이 볼 수 있습니다.

 

이때 q와 t의 관계를 구하면 먼저  q는




t의 값은 


이제 t의 값을 구하는 수식이 나왔습니다.
하지만 위의 수식은 두개의 점에 대한 것이기 때문에 3개의 점일 경우를 봐야합니다.
이건 간단합니다.

보정 전 산출된 무개 중심값은 와 같습니다. 즉 세점에 대한 보정된 무개 중심 좌표는 다음과 같이 구성됩니다. 





3) 구현

이제 구현 후 스티브의 얼굴이 정상적으로 나오는 것을 볼 수 있습니다.























여담...
처음 직접 구현했을 때는 아래의 구문 밖에서 즉 그리지 않아도 되는 부분에서도 
보정 매핑 연산을 진행했다.
if (((s >= 0.f) && (s <= 1.f)) && ((t >= 0.f) && (t <= 1.f)) && ((oneMinusST >= 0.f) && (oneMinusST <= 1.f)))
하지만 교수님의 코드를 보고 아! 굳이 그려도 되지 않아도 되는 부분은 안 해줘도 되는구나..
라고 생각하고 코드를 바꿨다.
이런 거 하나하나가 최적화에 정말 중요할 것 같고 왜 이론을 잘 알아야 되는지 다시 한번 깨달았다.

댓글

이 블로그의 인기 게시물

[알고리즘] 코헨 서더랜드 알고리즘(Cohen–Sutherland algorithm)

[알고리즘] 브레젠험 직선 알고리즘 (Bresenham's line algorithm)

오일러 각, 로드리게스 회전 공식, 평면의 방정식