DirectX 26

법선 매핑(Normal Mapping)

빛도 구현했고 이제 텍스처를 씌워보자. 평평한 표면에 벽지를 바른듯 나무 무늬에서 입체감이 느껴지지 않는다. 그 이유는 각 면에서 노멀이 모두 균일하기 때문이다. 그럼 어떻게 해야 입체적으로 느낄 수 있을까? 단순하게 생각해보면 가운데와 같이 폴리곤을 아주 많이 쪼개는 방법이 있다. 하지만 이렇게 할 경우에는 처리할 연산이 너무나도 많아진다. 그래서 나온 것이 노말 매핑(normal mapping)이다. Normal map 울퉁불퉁한 표면을 위해 노말들만 가져와 텍스처에 저장한 것이 노말 맵이다. 각 텍셀에 RGB 자료를 담는 것이 아니라 압축된 x, y, z 성분들을 각각 R, G, B 채널에 담는다는 점에서 보통의 텍스처와 다르다. 법선 벡터는 z축에 가깝기 때문에 xyz 성분을 RGB에 담는 노말맵..

DirectX 2022.07.15

조명(Lighting)

Lighting 조명은 기본적으로 아래 세 가지 요소로 이루어진다. Ambient Diffuse Specular 그리고 이 조명을 적용하는 셰이더 방식은 두 가지가 있다. Forward Lighting: 메쉬마다 조명 적용. Deffered Lighting: MRT에 빛 연산 중간 내용들을 저장 후 마지막에 적용. 포워드 라이팅은 각 드로우 콜(draw call)마다 빛에 의한 색상 변화를 화면에 나타날 최종 이미지에 더하기 때문에 성능 측면에서 많이 무겁다. N개의 광원과 M개의 메시가 있다면 N*M 만큼 연산을 하기 때문에 요즘에는 잘 쓰지 않지만 그래도 알아두는 것이 좋다. 조명 종류(directional light, point light, spot light)에 대해서는 생략함. 아래 조명은 po..

DirectX 2022.06.09

Transform

DX12코드 갈아엎고 DX11로 다시 만들었다 구조도 전부 바뀜. 이 게시글->lighting ->normal mapping 순으로 수정 Transform 유니티처럼 Position, Rotation, Scale을 가지고 있는 transform component를 만들어 볼 생각이다. // Component.h enum class COMPONENT_TYPE : uint8 { TRANSFORM, END } 컴포넌트를 상속받고 타입을 정해준다. 컴포넌트는 타입과 루프에 돌릴 함수들을 가지고 있고 컴포넌트가 속한 게임 오브젝트를 friend 시켜놓는다. 컴포넌트는 타입을 가지고 있어 gameObject는 해당 타입의 컴포넌트에 접근 가능하게 해준다. class Component { public: Compone..

DirectX 2022.05.23

7.6 루트 서명 추가 설명

1. 루트 매개변수 루트 서명이 루트 매개변수의 배열로 정의된 점을 기억할 것이다. 지금까지는 서술자 테이블에 해당하는 루트 매개변수 하나로만 이루어졌다. 그러나 꼭 서술자 테이블이어야 하는 것은 아니다. 루트 매개변수는 세 종류이다. 서술자 테이블: 힙 안에 있는 일련의 서술자들의 구간을 지정한다. 루트 서술자: 묶을 자원을 직접 식별하는 하나의 서술자로 힙에 둘 필요가 없다. 상수 버퍼에 대한 CBV나 기타 자원에 대한 SRV/UAV만 묶을 수 있다. 특히, 텍스처에 대한 SRV는 루트 서술자로 묶을 수 없다. 루트 상수: 직접 묶을 32비트 상수 값들의 목록이다. 성능상 이유로 매개변수의 비용은 다음과 같다. 서술자 테이블: DWORD 하나 루트 서술자: DWORD 두 개 루트 상수: 32비트 상수..

DirectX 2022.01.08

7.4 도형 기하구조

원기둥 메시 생성하는 원기둥 중심은 원첨이고 y축 방향으로 서 있는 형태다. 모든 정점은 '고리'들에 있다. 더미의 개수가 stackCount라고 할 때 고리들은 총 stackCount + 1개이다. 그리고 각 고리는 sliceCount개의 고유한 정점들로 구성된다. 인접한 고리들의 반지름 차이는 이다. 최하단 고리가 0번째 라고 할 때, i번째 고리의 반지름은 이고, 높이는 가 된다. 여기서 △h는 더미 하나당 높이고 h는 원기둥의 높이이다. 그럼 여기서 조각의 정점 좌표와 인덱스는 아래와 같이 될 것이다. GeometryGenerator::MeshData GeometryGenerator::CreateCylinder(float bottomRadius, float topRadius, float heigh..

DirectX 2022.01.06

7.3 패스별 상수 버퍼

std::unique_ptr PassCB = nullptr; 이 버퍼는 하나의 렌더링 패스 전체에서 변하지 않는 상수 자료를 저장한다. // FrameResource.h struct PassConstants { // 변하지 않는 상수 버퍼(시야 행렬, 투영 행렬, 시점 위치 등) 자료들. XMFLOAT4X4 View = MathHelper::Identity4x4(); XMFLOAT4X4 Proj = MathHelper::Identity4x4(); XMFLOAT4X4 InvView = MathHelper::Identity4x4(); XMFLOAT4X4 InvProj = MathHelper::Identity4x4(); XMFLOAT4X4 ViewProj = MathHelper::Identity4x4(); X..

DirectX 2022.01.06

7.2 렌더 항목

하나의 물체를 그리려면 버퍼 상수 등 묶고 설정하고 할 게 많다. 물체가 여러개이면 훨씬 복잡해진다. 물체를 그리는데 필요한 자료를 캡슐화하여 경량의 구조체로 만들면 편하다. 하나의 완전한 그리기 호출 명령을 렌더링 파이프라인에 제출하는 데 필요한 자료 집합을 이 책에서는 렌더 항목(render item)이라고 부른다. struct RenderItem { RenderItem() = default; // 이 행렬은 세계 공간에서의 물체의 위치, 방향, 크기를 결정. XMFLOAT4X4 World = MathHelper::Identity4x4(); // 개체 데이터가 바뀌어 상수 버퍼를 갱신해야 함을 나타내는 플래그. int NumFramesDirty = gNumFrameResource; // ObectCB..

DirectX 2022.01.06

7.1 프레임 자원

지금까지의 예제에서 사용해온 방식은 매 프레임마다 D3DApp::FlushCommandQueue()를 호출해 해당 프레임의 명령들이 모두 실행되기를 기다렸다. 이러한 방식은 비효율적이다. 한 프레임의 시작에서 CPU가 명령을 쓰는동안 GPU는 놀게된다. 한 프레임의 끝에서 GPU가 명령을 처리하는 동안 CPU는 놀게된다. 이 문제의 해결 방법은 매 프레임 CPU가 수정해야 하는 자원들을 순환 배열(circular array)로 관리하는 것이다. 이렇게 관리되는 자원들을 이 책에서는 프레임 자원(frame resource)라고 부르고, 일반적으로 사용한다. 순환 배열을 이용한 기법이란 프레임 n에서 CPU는 자원 배열을 훑으며 다음번 가용 프레임 자원(즉, GPU가 사용하지 않는 자원)을 찾는다. GPU가..

DirectX 2022.01.05

6.10 기하구조 보조 구조체

하나의 기하구조 그룹을 정의하는 정점 버퍼와 색인 버퍼를 한데 엮는 편리한 보조 구조체를 설명한다. 이 구조체는 실제 정점 자료와 색인 자료를 시스템 메모리에 유지해서 CPU가 그 자료를 언제라도 읽을 수 있게 하는 역할도 한다. 선택(picking)이나 충돌 검출을 위해서는 CPU가 기하구조 자료에 접근해야 한다. 이 구조체는 버퍼 형식이나 보폭(stride) 같은 버택스 버퍼와 인덱스 버퍼의 주요 속성들도 담아 두며, 버퍼에 대한 뷰를 돌려주는 메서드도 제공한다. struct SubMeshGeometry { UINT IndexCount = 0; UINT StartIndexLocation = 0; INT BaseVertexLocation = 0; // 기하구조의 경계 상자(bounding box) 뒷 ..

DirectX 2022.01.03