애니메이션은 그 전에 했던 뼈대에 대한 이해가 상당히 중요하다.모델을 로드할 때 좌표계를 변환해서 최상위 부모를 기준으로 한 좌표계로 변환행렬을 구한 후 이걸 Vs 단계에서 처리했다. 이 개념이 애니메이션과 정확히 동일하다.2D의 경우는 여러개의 이미지를 연속해서 보여주는 반면 3D의 경우 관절을 움직여서 움직임을 표현하는 식이다.스키닝먼저 모델을 로드할것인데 사용할 모델은 kachujin으로 가장 유명한 모델을 이용할 것이다.그런데 작성한 코드에 Skin을 추출하는 코드가 없기에 이걸 먼저 작성하고 가겠다.여기서 말하는 Skin은 Vertex들이 어떤 뼈대에 따라 움직일 것인지에 대한 정보를 의미한다.애니메이션은 뼈대를 움직여서 표현하는데 뼈대가 변함과 동시에 수많은 Vertex들이 같이 움직이여한다...
전체 글
성장 과정 일기, 누군가에게 정보를 제공하기 위해서가 아닌 스스로 배운 내용을 정리하기 위해 작성하는 블로그 입니다. 잘못된 정보가 있으면 댓글로 적어주세요.모델 띄우기이제 우리만의 format으로 만들었던 데이터를 다시 메모리로 올리는 과정을 해보자.Model 이라는 클래스를 만들고 여기에 한 모델이 가지고 있는 mesh며 material이며 추후엔 애니메이션 까지 등등을 가지고 있고 이걸 클라이언트에서 불러와 게임 내 화면에 보여주게하는 것이 목표이다.이전 포스팅에서 했던 Export를 반대로 하면 되는 것이다.#pragma oncestruct ModelBone{ wstring name; int32 index; int32 parentIndex; shared_ptr parent; // Cache Matrix transform; vector> children; // Cache};struct ModelMesh{ void CreateBuffers(); wstri..
Assimp로 Material 로딩유니티에서 에셋을 가져와 import 했을 때, 2D의 경우 매우 직관적이게 Texture를 틀기만 했음 됐지만 3D의 경우 수많은 파일들이 같이 들어온다. 특히 Model이 무엇인지 잘 몰라 헤맸던 경험이 있다. Material과 Shader 그리고 Animation 등등 여러 파일이 묶여 하나의 Model이 된다. 지금까지는 큐브, 구 등등 간단한 물체는 수학 식으로 생성할 수 있었지만, 그럴듯한 물체 즉 캐릭터 같은 물체들은 수많은 삼각형으로 이루어져있는데 이걸 수학 식으로 생성하는건 말이 안될 것이다.그렇기에 3D 제작 툴을 통해서 fbx 파일을 생성하고 엔진에서는 그걸 가져와 사용하는 방식으로 이루어진다. Assimp 라이브러리를 통해서 fbx 파일을 로드해보도..
MaterialMaterial 이란 물체들이 가지고 있는 잡동사니 특성이라고 생각하면 된다. 쉐이더를 통해서 물체를 그려줄 때 넘겨주는 인자중 하나인 셈이다. 어떻게 물체를 표현할 것이고 이 물체는 어떤 재질이고 빛은 어느 색을 흡수할 것인지 등등 을 넘겨주는 것이다. Texture와 같은 것도 Material에 포함되어 있는 것이다.#pragma once#include "ResourceBase.h"class Material : public ResourceBase{ using Super = ResourceBase;public: Material(); virtual ~Material(); shared_ptr GetShader() { return _shader; } MaterialDesc& GetMateria..
Global Shader이전에 작업하던 방식은 MeshRenderer 컴포넌트에서 .fx 파일의 쉐이더 에서 cubffer GLOBAL에 선언된 World, View, Projection 등의 행렬에 직접 접근해 Const Buffer에서 설정해 주었다. 이는 엄청난 편리함을 가져다 주는 장점이 있었다. 그런데 이 방식으로 고집해서 계속 하게되면 진지한 게임을 제작하는데 있어 문제가 발생한다.이렇게 하게되면 한가지 변수만 바뀌어도 나머지 변수들도 다 Update를 해주어야 하는 문제가 발생한다. 그렇기 때문에 이를 나눠 관리할 필요성이 있다.World, View, Projection에서 개개인의 물체마다 다르게 관리해야할 것은 바로 World 이고 나머지 행렬 두개는 묶어서 한번에 관리가 가능하다. 가령..
Height Map지면을 까는 Grid를 지난 포스팅에 해봤는데 이제 이것을 산 처럼 어디는 내려가고 어디는 올라가는 형식의 높이가 있는 맵을 한번 테스트 해보자. 유니티에서는 Terrain 툴이 존재해서 이것을 할 수 있다.이것을 이용할 것인데 이는 terrain의 높이를 8비트로 저장한 사진이다. 즉 0,0 부터 맵 끝까지 어느 지형의 높이를 0부터 255의 숫자로 나타낸 것이다. 이것을 우린 파싱해서 실제 맵에 적용해 줘야하는 것이다.이걸 CPU에서 연산해서 가지고 있다가 필요할 때 마다 GPU에 넘겨주는 방식도 있고 GPU 자체가 들고있어서 필요할 때마다 사용하는 방식 등 여러가지가 있지만 전자로 해보겠다.#include "pch.h"#include "07. HeightMapDemo.h"#incl..
카메라게임에서 가장 중요한 요소라고 할 수 있다.이전 포스팅에는 카메라가 없으니 view와 projection을 비워뒀는데 이제 카메라를 만들어서 카메라가 찍는 영역을 추출해서 화면에 보여주는 걸 만들어보자.#pragma once#include "Component.h"enum class ProjectionType{ Perspective, // 원근 투영 Orthographic, // 직교 투영};class Camera : public Component{ using Super = Component;public: Camera(); virtual ~Camera(); virtual void Update() override; void UpdateMatrix(); void SetNear(float value) ..
프로젝트 설정기존에 작업했던 작업물에서 3D 에 맞춰 작업하기 위해 새로운 프로젝트를 만들어보자. 기존에 사용했던 코드들 중 일부는 그대로 가져와주고 파이프라인 작업은 조금더 세련된 방법으로 수정한다. VS에서 Windows 데스크탑 마법사로 프로젝트를 만들어준다.그리고 나서 먼저 라이브러리를 만들어주자.파일 구조는 위와 같이 맞춰주고 Enginge 프로젝트에서 설정을 맞춰준다.위 과정은 많은 생략이 되어있다. 기존에 작성된 코드를 복사 하기도 한 반면 새로운 라이브러리들도 많이 추가되었기 때문에 너무 긴 글이 탄생할까 생략되었다.여기서 중요한건 Shader인데 우리가 2D 에서 사용하던 Render는 IA 과정과 VS, RS, PS 등등 여러 과정을 수동으로 전부 다 넣어줬어야 하는 반면 이건 자동으로..
Material렌더를 할 때 중복되는 부분인 Material과 Mesh를 Resource의 개념으로 따로 분리하도록 하자. MeshRenderer에서 사용하는 Mesh를 따로 설정하기 위해 Mesh라는 클래스를 만든다.#pragma once#include "ResourceBase.h"class Mesh : public ResourceBase{ using Super = ResourceBase;public: Mesh(ComPtr device); virtual ~Mesh(); void CreateDefaultRectangle(); shared_ptr GetVertexBuffer() { return _vertexBuffer; } shared_ptr GetIndexBuffer() { return ..
공용으로 관리될 부분은 Manager로 빼서 관리를 해보자.SceneManager지금까지 짠 코드를 보면 GameObject들을 그냥 Main 프로그램이 전부 다 가지고 있고 Update를 요청했다.우리가 생각해보면 유니티에서는 Scene이라고 하는 객체가 모든 GameObject를 가지고 있고 이를 관리하고 있다.그렇기에 SceneManager를 만들어서 관리해보자.여기서 Scene은 위에서 말한 대로 각종 오브젝트들을 보관하고 있는 클래스이다.SceneManager는 이러한 여러개의 Scene들을 하나로 묶어서 관리하기 위한 클래스이다.#pragma onceclass GameObject;class Scene{public: void Awake(); void Start(); void Update(); v..