기타/DirectX

[DirectX11] 14일차 (타이머 만들기 / 노멀맵 적용하기)

푸쿠이 2021. 3. 5. 18:02
참고 링크

c++ 공부

www.youtube.com/watch?v=18c3MTX0PK0&list=PLlrATfBNZ98dudnM48yfGUldqGD0S4FFb

 

물리기반 렌더러 이론

gamedevforever.com/93

 

이 링크는 이전 6일차 정리에서도 올린 링크이다. (그만큼 좋은 정리 글.)

lifeisforu.tistory.com/category/Physically%20Based%20Rendering

 

타이머 만들기 (프레임 계산)

유니티를 공부할 때, 오브젝트를 움직이려면 습관적으로 Time.DeltaTime을 곱했다.

왜 곱해야 하는지 구글링을 해서 대충 이해하고 있었지만, 이제는 진짜 이해됐다.

 

일단은 CPU 클럭(Clock)을 알아보자.

클럭은 디지털 회로의 전기적 진동 수이다. Hz 헤르츠 단위로 표시한다.

1초에 1Hz면, (0 또는 1) 신호를 한번 준다. (=1비트를 옮긴다는 뜻이다.)

 

윈도우10 기준으로 내 PC->속성에 가보면,  장치 사양을 볼 수 있다.

뭔가 장치 ID, 제품 ID 이런건 가려야 할 것 같다. 뭔진 잘 모르지만..

 

1GHz가 10에 9제곱이니까... 10억번이다.

3.6GHz 라는 것은 36억번이다. (1초에 36억 비트를 옮긴다는 뜻이다. 오우 진짜 빠르다;;;)

 

나는 #include <Windows.h>에서 제공해주는 방법을 사용했다.

원리는 이렇다.

주석을 엄청 길게 달아놓았지만, 내가 이해한 내용 그대로!! 오해할 틈없게 자세하게 적었다.

#include <Windows.h>

int main()
{
	LARGE_INTEGER frequencyCount;
    
	double countsPerSecond;
	__int64 countStart;
    
	// 초당 하드웨어 타이머의 진동 수를 받아온다.
	// 만약 1초당 100번 진동하면, 100 값을 받아온다.
	QueryPerformanceFrequency(&frequencyCount);
	countsPerSecond = (double)(frequencyCount.QuadPart); 

	// 일정 시점에 진동한 진동 수를 받아온다.
	// 초당 100번 진동한다고 가정할 때, 200이라는 값이 나왔다면 프로그램을 시작한지 2초가 지났다는 것임.
	// 타이머를 초기화하는 것까지도 시간이 걸리기 때문에 여기서 0의 값은 나오지 않는다.
	// 200이라는 값을 타이머의 시작 지점으로 잡겠다라는 뜻으로 Start 변수에 저장. 
	// 다음에 이 함수를 실행했을 때 500이면, 500 - 200 = 300. 즉 3초가 지났다는 것. (이런 방식으로 구함.)
	QueryPerformanceCounter(&frequencyCount); 
	countStart = frequencyCount.QuadPart;
}

주석에 단 예시를 보고 이해하면, 프레임 계산도 손 쉽게 될 것이다.

 

프레임마다 카운트 변수를 1씩 증가시킨다.

-> 1초 뒤 FPS가 나옴.

 

1초가 지났는지 어떻게 아나?

-> (현재 프레임 진동 수 - 카운트 변수를 세기 시작했을 때의 진동 수) / 초당 진동 수. 가 1보다 크다면 지난거다.

 

 

 

노멀의 종류

 

정리해야하는데 귀찮당 ㅎㅎ..

 

탄젠트 공간(Tangent space)

물체의 표면을 기준으로 법선 벡터 방향을 Z축으로 놓는 공간.

면을 기준으로 노멀 값.

3개의 벡터를 기준으로 되어있다.

 

T : Tangent vector (접선 벡터)

B : Binormal vector (종법선 벡터)

N : Normal vector (법선 벡터)

 

노멀 매핑 (Normal Mapping)

노멀 맵은 노멀을 그림파일로 만든 것이다.

오브젝트에 존재하는 노멀은 좌표 상, (-1 ~ 1)로 방향을 나타낼 수 있다.

그림파일은 색상이 (0 ~ 1)로 존재하기 때문에, 간단한 수식으로 변환을 해서 사용한다.

 

노멀을 그림파일(노멀 맵)로 변환할 때, -> (-1 ~ 1)에서 * 0.5 + 0.5 하면 (0 ~ 1)

그림파일(노멀 맵)을 노멀로 사용할 때, -> (0 ~ 1)에서 * 2 - 1 하면 (-1 ~ 1)

 

대단한 공식처럼 써놓았는데, 조금 생각해보면 생각해낼 수 있는 공식이다.

변환된다라고 이해하고 있으면 될듯하다.

 

탄젠트 노멀 맵이 파란 이유

탄젠트 노멀은 (x, y, z) 중에 대체적으로  z방향(표면에서 수직인 방향, 앞방향)으로 뻗어나가있다.

 

좌표의 (x, y, z) = 그림파일의 (r, g, b)

좌표의 z값이 그림파일에서 b값이므로, blueblue하게 보이는 것이다.

 

노멀 맵의 장단점

-장점

하이 폴리곤에서 노말 데이터를 얻어오기 때문에, 낮은 폴리곤에서도 하이폴리곤처럼 빛 연산을 할 수 있다.

-단점

빛 연산이기 때문에, Model을 가까이서 보면 낮은 폴리곤이 그대로 보인다. (눈속임이 들킨다.)

 

눈속임이 들키는 것을 개선하기 위해 -> 시차매핑 (Parallax mapping)이 개선안으로 나옴.

한번 더 발전해서 -> 테셀레이션(Tessellation)이 개선안으로 나옴.