Direct3D 기본 초기화
사용하기 위해 가장 먼저 초기화를 시켜야 한다. 처음 했던 예제.
다 이해하고 외우기는 어렵다. 큰 틀, 과정을 이해하면 충분하다.
- 1단계 : 디바이스와 컨텍스트 생성
- 2단계 : H/W의 4X MSAA 품질 수준 지원 여부 확인
- 3단계 : DXGI_SWAP_CHAIN_DESC 구조체 내용 구성
- 4단계 : SwapChain의 생성
- 5단계 : SwapChain의 BackBuffer에 대한 Render Target View 생성
- 6단계 : Depth Buffer, Stencil Buffer 생성 및 View 생성 (스탠실 사용하지 않을 경우 생략 가능)
- 7단계 : Render Target View, Depth View, Stencil View 설정
- 8단계 : Viewport 대한 설정
D3DApp :: Init() 함수에서 초기화 진행
→ InitMainWindow() 에서 윈도우 관련 생성 및 초기화 진행
→ InitDirect3D()에서 Direct3D의 Device & Context 생성 및 초기화 진행
D3DApp :: OnResize() 함수에서 화면 크기 변화에 대한 처리
→ 초기화 5단계에서 8단계에 의한 초기화 부분 진행
→ Depth와 Stencil Buffer는 Texture2D 임
→ Depth와 Stencil의 사용을 위해서 View를 반드시 생성
DirectX 기본 렌더링
기본 렌더링 파이프라인
- Input assembler Stage
- *Vertex Shader Stage
- Rasterizer Stage
- *Pixel Shader Stage
- Output Merger Stage
*프로그래머가 직접 코딩으로 수정 할 수 있는 부분. 그 외의 부분은 불가능하다.
DirectX 기본 렌더링 구성
1) 화면 렌더링할 기하 설정을 위한 Vertex Buffer 및 Index Buffer 구성
2) Vertex Shader와 Pixel Shader의 구성을 위한 fx파일 제작
3) fx파일에 대한 컴파일
4) fx파일 내의 Tech와 Variable의 접근을 위한 변수 설정
5) CreateInputLayout을 통한 Input Assembler Stage에 대한
입력 버퍼 데이터를 설명하는 입력 레이아웃 정보 생성
Vertex 외로도 Index를 받아오는 이유는 최적화를 하기 위함이다.
삼각형을 두개 그린다고 했을 때, Vertex는 6개가 필요하지만 Index로 그리게 된다면 4개면 충분하다.
1) 화면 렌더링할 기하 설정을 위한 Vertex Buffer 및 Index Buffer 구성
UD3D11Device::CreateBuffer를 이용해서 Buffer 생성
HRESULT CreateBuffer(
[in] const D3D11_BUFFER_DESC *pDesc, // 버퍼 설정 설명 구조체
[in, optional] const D3D11_SUBRESOURCE_DATA *pInitialData, // 초기화 데이터 설명 구조체
[out, optional] ID3D11Buffer **ppBuffer
);
typedef struct D3D11_BUFFER_DESC {
UINT ByteWidth; //버퍼의 크기 (Byte기준)
D3D11_USAGE Usage; //읽고 쓰는 방법 (D3D11_USAGE_DEFAULT)
UINT BindFlags; // 렌더링파이프라인에 버퍼 설정 방법
UINT CPUAccessFlags; // CPU 엑세스 여부 (0:불필요)
UINT MiscFlags; // 기타 플래그 (0:불필요)
UINT StructureByteStride; //구조체로 정할 경우 각 크기(Byte)
} D3D11_BUFFER_DESC;
typedef struct D3D11_SUBRESOURCE_DATA {
const void *pSysMem; // 초기화 데이터에 대한 포인터
UINT SysMemPitch; // 2D및 3D 텍스처에만 사용
UINT SysMemSlicePitch; // 3D 텍스처에만 사용
} D3D11_SUBRESOURCE_DATA;
Vertex Buffer 및 Index Buffer 구성 예제
// Create the vertex buffer
Vertex::Basic32 vertices[] =
{
{ XMFLOAT3(-1.0f, -1.0f, -1.0f), XMFLOAT4(Colors::Red) },
{ XMFLOAT3(-1.0f, +1.0f, -1.0f), XMFLOAT4(Colors::Red) },
{ XMFLOAT3(+1.0f, +1.0f, -1.0f), XMFLOAT4(Colors::Red) },
};
mBoxVertexCount = 3;
D3D11_BUFFER_DESC vbd;
vbd.Usage = D3D11_USAGE_IMMUTABLE;
vbd.ByteWidth = sizeof(Vertex::Basic32) * mBoxVertexCount;
vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vbd.CPUAccessFlags = 0;
vbd.MiscFlags = 0;
vbd.StructureByteStride = 0;
D3D11_SUBRESOURCE_DATA vinitData;
vinitData.pSysMem = vertices;
HR(md3dDevice->CreateBuffer(&vbd, &vinitData, &mBoxVB));
// Create the index buffer
UINT indices[] = {
0, 1, 2,
};
mBoxIndexCount = 3;
D3D11_BUFFER_DESC ibd;
ibd.Usage = D3D11_USAGE_IMMUTABLE;
ibd.ByteWidth = sizeof(UINT) * mBoxIndexCount;
ibd.BindFlags = D3D11_BIND_INDEX_BUFFER;
ibd.CPUAccessFlags = 0;
ibd.MiscFlags = 0;
ibd.StructureByteStride = 0;
D3D11_SUBRESOURCE_DATA iinitData;
iinitData.pSysMem = indices;
HR(md3dDevice->CreateBuffer(&ibd, &iinitData, &mBoxIB));
2) Vertex Shader와 Pixel Shader의 구성을 위한 fx파일 제작
#include "LightHelper.fx"
cbuffer cbPerObject
{
float4x4 gWorld;
float4x4 gWorldViewProj;
};
struct VertexIn
{
float3 PosL : POSITION;
float4 Color : COLOR;
};
struct VertexOut
{
float4 PosH : SV_POSITION;
float3 PosW : POSITION;
float4 Color : COLOR;
};
VertexOut VS(VertexIn vin)
{
VertexOut vout;
// Transform to world space space.
vout.PosW = mul(float4(vin.PosL, 1.0f), gWorld).xyz;
// Transform to homogeneous clip space.
vout.PosH = mul(float4(vin.PosL, 1.0f), gWorldViewProj);
// Set vertex's color
vout.Color = vin.Color;
return vout;
}
float4 PS(VertexOut pin) : SV_Target
{
float4 litColor = pin.Color;
return litColor;
}
technique11 VertexColor
{
pass P0
{
SetVertexShader( CompileShader( vs_5_0, VS() ) );
SetGeometryShader( NULL );
SetPixelShader( CompileShader( ps_5_0, PS() ) );
}
}
3) fx파일에 대한 컴파일
→ d3dx11effect.h에 정의된 D3DX11CompileEffectFromFile 메서드 사용
4) fx파일 내의 Tech와 Variable의 접근을 위한 변수 설정
→ d3dx11effect.h에정의된GetVariableByName을 통한 셰이더내 변수 접근
→ ID3DX11EffectVariable의AsScalar, AsVector, AsMatrix, AsString등을 통한 변수타입 접근
→ d3dx11effect.h에정의된GetTechniqueByName을 통한 셰이더 내 기법 접근
매 프레임 갱신 때 진행해야 하는 내용
→ 화면에 보이는 객체들과 카메라 등의 행렬 값 계산
→ Render Target View와 Depth/Stencil View의 Clear
→ IASetInputLaytout을 통한 입력 레이아웃 정보 설정
→ IASetPrimitiveTopology를 통한 기본 도형 위상구조 정보 설정
→ IASetVertexBuffers와 IASetIndexBuffer 설정
→ Vertex Shader에 적용할 상수 값 설정
→ fx를 이용 시 fx의 pass에 대한 Apply 메서드 적용과 Context 설정
→ Draw (Vertex 이용) 혹은 DrawIndexed (Index를 이용)를 통한 렌더링
→ Present를 통한 화면 표시
5) CreateInputLayout을 통한 Input Assembler Stage에 대한 입력 버퍼 데이터를 설명하는 입력 레이아웃 정보 생성
→ IA단계에서 입력 레이아웃 정보 위해 D3D11_INPUT_ELEMENT_DESC 정의
→ GetDesc를 통해 현재 설정된 FX파일의 해당 Tech내 Pass의 설정 얻기
ID3D11Device::CreateInputLayout을 통한 IA설정 입력 레이아웃 설정
// Create the vertex input layout.
D3D11_INPUT_ELEMENT_DESC vertexDesc[] =
{
{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
{"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0}
};
// Create the input layout
D3DX11_PASS_DESC passDesc;
mTech->GetPassByIndex(0)->GetDesc(&passDesc);
// CreateInputLayout를 통해서 정점 버퍼를 어떻게 해석할지 GPU에게 알려준다.
HR(md3dDevice->CreateInputLayout(vertexDesc, 2, passDesc.pIAInputSignature, passDesc.IAInputSignatureSize, &mInputLayout));
Effect 파일
FX에 대한 개념
→ 셰이더 프로그램들과 렌더 상태들을 “Effect”라고 부르는 단위로 조직화하고 관리하는 틀을 제공하는 코드 집합
→ HLSL의 코드와 추가적인 상태 정보를 포함하는 파일 포맷
→ 셰이더 및 렌더링 파이프라인에 대한 상태에 대한 설정 지정 가능
→ 적어도 하나의 기법 (technique)을 정의
→ 기법(technique) 안에는 적어도 하나의 패스(pass) 포함
→ DX11에서는 Shader Model 5.0 버전 HLSL 사용
Effect 파일 구성요소
global variables : 셰이더 코드 전체에서 사용, 셰이더 간의 데이터 전송을 위해 사용
techniques : technique11로 시작, 특정 렌더링 기법을 하나 이상의 패스들로 구성
pass : technique안에서 pass로 시작, 정점⋅픽셀⋅기하 셰이더, 렌더 상태들 정의
shader functions : HLSL로 작성된 함수, 정점⋅픽셀⋅기하 셰이더 정의 및 기타 함수 정의
HLSL – Scalar Types
- bool : true and false
- int : 32bit signed integer
- uint : 32 bit unsigned integer
- dword : 32 bit unsigned integer
- half : 16 bit floating point value (-60,000 ~ 60,000 )
- float : 32bit floating point value
- double : 64bit floating point value
- fixed : 11bit floating point value (-2~2사이, 1/256)
HLSL – Vector Types
TypeComponents Name
vector <Type, Components> Name
→ Type : HLSL Scalar Type 설정
→ Components : 1~4까지의 차원 설정
bool bScalarVariable = true;
int iScaleValue = 10;
int1 iScaleValue1 = 20;
float3 fVecto3 = { 1.0f, 0.0f, 1.0f };
vector <float, 3> fRealVector3 = { 2.0f, 1.0f, 2.0f};
double dRotValue = 35.0;
HLSL – Matrix Types
TypeComponents Name
matrix <Type, Components> Name
→ Type : HLSL Scalar Type 설정
→ Components : row 개수, column 개수 (1~4)
int1x1 iMatrtix ={ 1.0f, 0.0f }
float4x4 fMatrix; // float matrix 4 row 4 column
float2x2 fMatrix2x2 = { 1.0f ,0.0f, 0.0f, 1.0f };
matrix<double, 2, 2> dMatrix = { 1.0 , 0.0 , 0.0, 1.0 };
HLSL – ETC
- array (배열) : 다차원 배열 가능
- structure (구조체) : C언어 구조체 방식 (C++방식이 아님)
- typedef : C/C++와 동일한 방식
- 지원하는 내장 함수
→ 삼각 함수 : sin,cos,tan,asin,acos,atan,atan2,degrees,radians
→ 수학 함수 : sqrt, exp, pow, log, log10, log2
→ 벡터 함수 : cross, dot, distance, len, normalize, transpose, mul
→ 기타 함수 : abs, max, min, lerp, clamp, saturate
HLSL에 대한 설명
의미 체계 - Win32 apps
의미 체계는 매개 변수의 의도된 사용에 대한 정보를 전달하는 셰이더 입력 또는 출력에 연결된 문자열입니다.
learn.microsoft.com
실습 진행
1) Vertex만을 이용해서 녹색 정사각형을 렌더링 하세요. 그리고 Vertex와 Index를 이용해서 녹색 정사각형을 렌더링 하세요.
→ Vertex는 POSITION과 COLOR값 만 존재
2) Vertex와 Index를 이용해서 App에서 지정된 색깔로 정사각형을 렌더링 하세요.
→ Vertex는 POSITION과 COLOR값 만 존재
→ App에서 COLOR값을 지정하고 그 값을 셰이더에 반영
Direct3D Texture
텍스처(Texture)
→ 표면에 표현된 질감이며 게임에서는 2D 이미지를 가장 많이 사용
렌더링 파이프라인에서 텍스처를 적용하는 일반적인 단계
→ Direct3D 텍스처에 렌더링 하는 경우 (D3D11_BIND_RENDER_TARGET)
→ Direct3D 텍스처를 셰이더의 리소스로 활용하는 경우 (D3D11_BIND_SHADER_RESOURCE)
텍스처 생성시 2개의 적용을 모두 할 수 있게 플래그 설정
→ D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE
Direct3D에서 텍스처 사용을 위한 단계
→ 텍스처 초기화 시점에서 텍스처의 Resource View를 생성 필수
→ 렌더 타겟 뷰 생성 (ID3D11RenderTargetView)
→ 셰이더 리소스 뷰 생성 (ID3D11ShaderResourceView)
텍스처 좌표를 통해서 특정 위치의 텍셀 값을 지정 가능
텍스처 좌표는 가로는 u, 세로는 v축으로 표현
텍스처 좌표 범위 : 0 ≤ 𝐮, 𝐯 ≤ 1
텍스처 생성 과정
1. 디스크에 저장된 이미지 (jpg, dds, png)
2. 이미지 파일 로딩 (DirectXTex의 LoadFromXXXFile)
3. ID3D11Texture2D 객체 생성 (DirectXTex의 CreateTexture)
4. Texture적용을 위한 셰이더 리소스뷰 생성 (ID3D11Device::CreateShaderResourceView)
5. 생성한 셰이더 리소스 뷰를 셰이더에 적용 (PSSetShaderResources)
HLSL의 Sampler State 객체는 텍스처에 적용하는 필터링 설정을 결정
텍스처를 재질/조명과 통합
→ LitColor = texColor * (ambient + diffuse )+ specular
실습 진행
1) Vertex와 Index를 이용해서 텍스처 맵핑 정사각형을 렌더링 하세요
→ Vertex는 POSITION과 TEXCOORD값 존재
→ 𝐠𝐫𝐚𝐬𝐬. 𝐝𝐝𝐬 파일을 이용해서 맵핑 하세요
2) Vertex와 Index를 이용해서 텍스처 맵핑 정사각형을 렌더링 하세요
→ Vertex는 POSITION과 TEXCOORD값 존재
→ 정사각형의 왼쪽 삼각형은 grass. dds 파일을 이용해서 맵핑 하세요
→ 정사각형의 오른쪽 삼각형은 ice. dds 파일을 이용해서 맵핑 하세요
Direct3D Lighting
재질 (Material)
→ 빛이 물체의 표면과 상호작용 하는 방식 결정하는 속성 값들
→ 재질 성질을 위해서 Ambient, Diffuse, Specular 설정
조명(Lighting)
→ 3D 객체들과 빛들 과의 상호작용을 시각적으로 표현
조명 모델 (Lighting Model or Illumination Model)
→ 3D 장면 렌더링 시 빛과 객체에 대한 상호작용을 과학적으로 설명
→ Local Illumination Model 과 Global Illumination Model 분류
조명 방정식 (Lighting Equation)
→ 조명 모델의 구성 요소들을 방정식으로 표현하여 최종 색상 값 계산
조명 모델의 대표적인 3가지 요소
1) Ambient Lighting (주변광) : 주변에서 존재하는 여러 객체 들과의 상호작용하는 빛
2) Diffuse Lighting (분산광) : 빛이 표면에 닿으면 모든 방향으로 균등하게 흩어지는 빛
3) Specular Lighting (반사광) : 객체의 표면에서 빛이 특정 방향으로 반사되는 빛
Ambient, Diffuse, Specular을 통한 기본 조명모델의 조명방정식
LitColor = ambient light + diffuse light + specular light
→ diffuse Lighting이 없는 상황이면 반사광도 없음
빛의 대표적인 3가지 종류
1) Directional Light (평행광) : 멀리 떨어져 있는 광원에서 오는 빛
2) Point Light (점광) : 광원을 기준으로 모든 방향으로 뿜어 나가는 빛
3) Spot Light (점적광) : 광원을 기준으로 특정 영역을 집중되게 비추는 빛
Directional Light의 기본 조명모델의 조명방정식
LitColor = ambient light + diffuse light + specular light
→ diffuse Lighting이 없는 상황이면 반사광도 없음
Directional Light의 기본 조명모델의 조명방정식
LitColor = ambient light + diffuse light + specular light
→ diffuse Lighting이 없는 상황이면 반사광도 없음
Spot Light의 기본 조명모델의 조명방정식
LitColor = 𝒎𝒂𝒙 −𝐿𝒅𝒊𝒓 · 𝒅, 𝟎
→ 𝑎0, 𝑎1, 𝑎2 : attenuation parameter
→ 𝑑 : 광원과 떨어진 거리
→ 𝑠를 이용해서 Spot Light의 원뿔 크기를 조정 가능
실습 진행
GeometryGenerator:: CreateSphere를 이용해서 구(반지름:0.5)를 렌더링하고 Direction Lighting을 하나 더 추가해보세요
→ Direciton (0,0,1), Ambient(0.7,0.7,0.7,1.0), Diffuse(0.4,0.4,0.4,1.0),Specular(0.5,0.5,0.5,16.0)
→ Vertex는 POSITION과 NORMAL, TEXCOORD값 존재
→ 𝐠𝐫𝐚𝐬𝐬. 𝐝𝐝𝐬 파일을 이용해서 맵핑 하세요
'대학생활 > 수업' 카테고리의 다른 글
게임인공지능 7주차 - Shortest Path, Dijkstra, A* Algorithm (0) | 2023.10.17 |
---|---|
게임밸런스및시뮬레이션 6주차 - VBA에 대하여, 중간과제 공지 (1) | 2023.10.16 |
리얼타임엔진 6주차 - 중간고사 준비 (0) | 2023.10.10 |
게임인공지능 6주차 - Graph, Path Finding, Shortest Path, Dijkstra (0) | 2023.10.10 |
게임기획과비주얼스크립팅 5주차 - 블루프린트 기능 추가 (0) | 2023.10.05 |