본문 바로가기
학원

DirectX 3D Camera

by Srff5123 2023. 10. 25.
728x90

게임 수학 벡터 개념

 

Vector는 특정 축에서의 힘과 방향을 뜻함

Scala 방향이 없는 힘만 뜻함

 

표현 방법으로는 (x, y, z) 사용하고 좌표로도 많이씀

벡터 연산

 

벡터 A(1, 2) 벡터B(2,1)

그래프로 그렸을 시

 

벡터의 덧셈

각항 끼리더해줌  A+B = C(3,3)

3,3을 그래프로 표현을 해주면 이런식으로 나오는데

C(3,3)은

A에서 B만큼 갔을 경우의 거리가 나온다 이것을 봤을대 벡터의 덧셈은 교환법칙이 적용이 되는데

이것을 게임에서 사용을 한다면

간단한예시로는

내 위치에서 장애물사이를 갈 방향을 구할때 사용할수있다.

두 벡터를 더하면 그래프를 보면 가운데로 가는방향이 나오게 된다. 이런식으로 응용이 가능하다

특정방향을 구할때 사용이 가능

 

벡터의 뺄셈

덧셈과 비슷하게 각항끼리 빼주면 된다.

A-B = C(-1,1)

그래프로 표현하면

이런식으로 나오는데 A에서 B로가는 거리가 나온다.

예시로는 내 위치에서 장애물 까지의 벡터를 구하고싶을 경우 사용 많이 쓰임

 

유의할 점으로는

뒤에서 앞으로 가리키는 것이기에 B 에서 A로 가는것이라는 점과

뺼셈은 교환법칙이 적용이 안된다는점이 있다.

 

벡터끼리는 곱셈이 없는데

벡터와 스칼라 곱은 가능하다.

예시

A벡터에 Scala2를 곱해주면 각항에 2를 곱해주면 되는데

A = (2,4)

그래프로 표현을 해주면

같은 방향인데 힘만 2배로 길어준다고 생각하면 된다.

나누기도 사용가능

벡터와 스칼라 곱은 속도 조절에 많이 사용한다.

 

벡터는 단위 행렬이 있는데 크기로 각항끼리 나누어 1로 정규화 할수있다.

벡터의 힘을 1로 만듬 <--- 중요

 

내적과 외적(매우 중요)

 

내적(Dot)으로 표현

내적의 공식

결과값은 Scala값으로 나옴 수치값

절대값아님 크기를 뜻함

벡터의 크기는 삼각함수를 사용한다

아까 A를 예시로 들면 (1,2) = 루트5가 된다

 

다르게 표현하는 방법도 있는데

A(x,y,z), B(a,b,c)라면 3차원일 경우

내적의 공식은 (x*a) + ( y * b) + (z * c) 가된다.

 

같은 벡터끼리 내적을 하면 

이렇게 나온다

벡터의 크기를 비교할때 같은 벡터의 내적이 많이 쓰인다

 

내적공식을 쓰는것이 직접 크기를 구하는 것보다 내부적으로 연산속도가 빠르다.

 

외적

 

2차원 x 3차원만 가능

z값 양수 음수를 이용하면 평면 기준으로 쓸수는 있음.

 

A(x,y,z) B(a,b,c)

 

외적 식

x = y * c - z * b

y = x * c - z * a

z = x * b - y * a

외적으로 할수있는 것은 물체가 오른쪽에 있는지 왼쪽에 있는지 판별을할때 쓸수있다.

값이 양수면 캐릭터의 오른쪽,음수면 캐릭터의 왼쪽에 있음을 알수있다.

 

카메라 만들기

Framework폴더에 Environment 폴더에서 Camera 헤더파일 추가

부모로는 Transform을 상속받아 회전과 움직임을 구현

 

뷰세팅을 위한 

    MatrixBuffer* viewBuffer;
    Matrix view 설정

 

카메라 이동 속도와 각도 변경 속도 설정

 

마우스로 이용하기위해 이전 좌표를 기억해줄

prevMousePos 설정

 

 

다음 cpp 파일로 이동하여

생성자에서는 viewBuffer를만들어주고

viewBuffer는 바로 세팅하는 것이 안정적이기에 SetVS 1번으로 바로 세팅

mousePos 설정

 

소멸자에서는 할당된 viewBuffer 지워주기

 

GUIRender에서

Imgui의 TreeNode로 묶고

카메라 옵션에서 

이동 속도 조절

회전 속도 조절

Treepop을 해준다.

 

다음 SetVIew로 이동하여

view에 XMMatrixInverse함수 사용하여 world의 역행렬 받고

viewBuffer 에는 view 행렬 세팅

viewBuffer 에 세팅

 

다음 Vector3 헤더에서 함수로 이동값 넣어주기

 

다음 FreeMode 에서

 

 Vector3 delta = mousePos - prevMousePos;
 prevMousePos = mousePos;

설정하여 이전값 저장

 

if조건문 사용하여 Key Press값을 받아 버튼으로 카메라 이동 및 각변화 설정

 

다음 Envionmnet 헤더로 이동하여 camera가 여러개 사용할수도 있기 때문에

mainCamera 만들어주고  view관련된 것들 지우면서 정리 

 

 

 

다음 cpp파일에서 카메라 생성 및 delete

maincamera  Update와 Render , Setting 해주기

 

다음 d3d cpp파일로 이동하여 마우스 움직임 구현

및 Framework헤더에 추가

 

실행하면 카메라가 잘 작동하게 됌

 

Transform에는 많은 정보가 들어있음

단위 행렬 기준으로 

객체의 위치 각도 다 가지고있음

Right Vector

Up Vector

Forward Vector

 

41 42 43은 월드상의 위치 값을 나타냄

 

Transform 헤더로 이동하여 벡터 추가 

value의 주소값 반환할 함수 만들어주기

 

 

다음 cpp로 UpdateWorld로 이동하여

값 뽑아주기

XMStoreFloat4x4 이용하여 world 행렬을 matworld 행렬로 바꿔주고

right, up, forward 값 설정

 

XMMatrixDecompose 이용하여 글로벌 position 과 scale,  Rotation값 뽑아주기

 

vector 헤더에는 Normalize 정규화 함수 추가 1로 만듬 

 

transform헤더에서 추가 

카메라가 자유롭게 움직임이 구현이 가능하게됌

 

빛 연산 

3d는 빛을 이용하여 물체의 음영을 통하여 입체감을 준다. 빛이 없으면 단순 흰색의 맵에높이를 설정을 해주어도

이런식으로 나오게 된다.

 

Light는 직접광과 간접광으로 나뉘어지고 

직접광은 난반사와 정반사로 나뉘어진다.

여기서 난반사란  빛의 반사를 통하여 빛이 고르게 분포하는것을 의미

Diffuse Light

어느정도를 어둡게 할것인지를 해야되는데 물체 마다 

법선이 있어 폴리곤의 수직이 되는데 구같은 경우에는

이런식으로 나오게 된다 그렇기에 각도에 따른 cos 세타 를 이용한다.

가운데는 cos 0 으로 1을받아 빛을 전부 받는다고 보면 된다

 

그렇기에 옆부분은 cos 90으로 0값이 나와 빛을 받지못해 어둡게 나오게된다.

이런식으로 점점 어둡게 표현을 하여 음영효과를 준다.

 

그러면 이것을 코드로 나타내어 보자

 

Shaders폴더에 Light폴더를 만들어주고 DifuuseLight.hlsl파일(꼭지점 쉐이더)을 만들어준다

Tutorial.hlsl를 복사하여 넣어주고

 

Vertexinput에 법선 추가

법선 = Normal

 

PixelInput에 Diffuse를 넣어주고

 

LightBuffer 만들어주고 10번으로 설정

받는 값은 flaot3로 lightDirection 

상수버퍼는 16의 배수로 받아야하기 떄문에

나중에 float4로 하고 하나 버려줌

 

normal값과 정규화

light 또한 정규화를 해줌

 

두벡터 사이의 cos값을 구해야 하기 때문에

내적공식을 사용함

 

내적함수 dot을 이용하는데 두개의 벡터가 마주보기 때문에 하나를 -를 주어 바꾸어서 설정

하고 그 값을 곱해주면 된다

 

Framework폴더의 Buffer폴더에서 VertexLayout 헤더로 이동하여

UVNormal 구조체 선언

 

다음 상수 버퍼 추가를 위해 GolbalBuffer 헤더로 이동하여

LightBuffer class 만들고

 

16을 넣어주어야 하기 떄문에 float padding 추가

 

다음 Envionment 헤더에 Light 정보 추가

 

 

cpp이동하여 생성 후

Set으로 이동하여 설정한 값 10번에 넘겨주고

 

GUIRender로 이동하여 

 lightDirection받아와 수정할수있게 만들고

 

 

Terrain 헤더로 이동하여 normal값 구해줄 MakeNormal()함수 만들기

 

간편한 작업을 위해 Framework 헤더에 추가

 

다음 Vector3 헤더에 외적 내적 함수 추가

 

float3 4의 계산을 위한 operator 함수 추가 

 

cpp이동하여 diffiuse 추가

 

다음 MakeNormal 만들기

 

안에 있는 값 수정을 위해 참조형으로 vertices, indices값 뽑기

수정을 안해도 값복사를 방지하여 속도차이를 줄이기위해 참조형으로 하는것이 좋

 

for문 이용하여 폴리곤 정보를 뽑고 정점에 대한 정보 입히기

완료 하고 실행을 하면

이제는 빛이 입혀져 음영이 추가되어 입체감이 어느정도 생김

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

728x90

'학원' 카테고리의 다른 글

DirectX 3D Sphere & NormalMapping  (1) 2023.10.27
DirectX 3D Specular  (0) 2023.10.25
DirectX 3D Terrain  (1) 2023.10.25
DirectX 3D ImGui  (1) 2023.10.24
DirectX 3D Grid  (1) 2023.10.19