DOTY
DirectX11. 3) Buffer, Shader I 본문
0. Buffer / Shader
- Buffer : 데이터를 저장하는 메모리 영역
- Shader : GPU에서 실행되는 경우가 많으며 그래픽스 파이프라인의 각 단계에서 실행된다.
0-1. Vertex Buffer
3D 모델은 여러 개의 삼각형으로 구성된다. 이 모델을 구성하는 삼각형 꼭짓점들에 대한 정보를 Vertex Buffer라고 하는 데이터 배열에 넣어야 한다. 이를 활용해서 렌더링을 한다.
0-2. Index Buffer
Vertex Buffer와 비슷하지만 다른 버퍼로 모든 꼭짓점들을 저장하는 것이 아닌 꼭짓점들의 위치를 저장하는 것이다. Vertex Buffer보다 메모리를 절약할 수 있다는 장점이 있다.
0-3. Vertex Shader
Vertex Buffer의 꼭짓점을 3D로 변환해주기 위해 사용된다. 꼭짓점에 대한 계산들을 처리하게 된다.
0-4. Pixel Shader
다각형의 색을 처리하기 위해 사용된다. 채색, 텍스쳐링, 조명 의 효과는 Pixel Shader에서 처리하게 된다.
0-5. HLSL
Shader을 코딩하는데 사용되는 언어.
※ Model Class, Camera Class, Color Shader Class가 Framework에 추가된다.

1. ColorShaderClass.h
#pragma once
#ifndef _COLORSHADERCLASS_H_
#define _COLORSHADERCLASS_H_
#include <d3d11.h>
#include <d3dcompiler.h>
#include <directxmath.h>
#include <fstream>
using namespace DirectX;
using namespace std;
class ColorShaderClass
{
private:
struct MatrixBufferType
{
XMMATRIX world;
XMMATRIX view;
XMMATRIX projection;
};
public:
ColorShaderClass();
ColorShaderClass(const ColorShaderClass&);
~ColorShaderClass();
bool Initialize(ID3D11Device*, HWND);
void Shutdown();
bool Render(ID3D11DeviceContext*, int, XMMATRIX, XMMATRIX, XMMATRIX);
private:
bool InitializeShader(ID3D11Device*, HWND, WCHAR*, WCHAR*);
void ShutdownShader();
void OutputShaderErrorMessage(ID3D10Blob*, HWND, WCHAR*);
bool SetShaderParameters(ID3D11DeviceContext*, XMMATRIX, XMMATRIX, XMMATRIX);
void RenderShader(ID3D11DeviceContext*, int);
private:
ID3D11VertexShader* m_vertexShader;
ID3D11PixelShader* m_pixelShader;
ID3D11InputLayout* m_layout;
ID3D11Buffer* m_matrixBuffer;
};
#endif
HSLS 셰이더를 호출하고 이를 활용해 GPU의 3D 모델을 그린다.
1-1. Initialize
셰이더에 대한 초기화 함수를 호출하는데 이를 위해서 color.vs, color.ps라는 HSLS 셰이더 파일의 이름을 전달한다.
1-1-1. Color.vs
// VertexShader
cbuffer MatrixBuffer
{
matrix worldMatrix;
matrix viewMatrix;
matrix projectionMatrix;
};
struct VertexInputType
{
float4 position : POSITION;
float4 color : COLOR;
};
struct PixelInputType
{
float4 position : SV_POSITION;
float4 color : COLOR;
};
PixelInputType ColorVertexShader(VertexInputType input)
{
PixelInputType output;
input.position.w = 1.0f;
output.position = mul(input.position, worldMatrix);
output.position = mul(output.position, viewMatrix);
output.position = mul(output.position, projectionMatrix);
output.color = input.color;
return output;
}
cBuffer MatrixBuffer : cBuffer은 버퍼의 개체 형식으로 Shader에게 전달되는 상수 데이터의 컨테이너 역할을 한다. 쉽게 말하자면 C++ 에는 struct라는 구조체가 있듯 HSLS에는 cBuffer라는 구조체가 있다고 보면 된다. 따라서 MatrixBuffer은 3개의 행렬을 전달하기 위한 구조체다.
struct Vertex(Pixel)InputType : float4 타입 두가지를 전달하기 위한 구조체. position = (x, y, z, 1)과 color = (r, g, b, a)를 전달하게 된다. color은 vertex와 pixel 두 가지에 작동된다. (다르게 사용해도 된다.)
PixelInputType ColorVertexShader(VertexInputType input) :
input으로 처음 점의 위치를 가져와서 3가지의 행렬을 곱해준다. 모델의 변환을 나타내는 WorldMatrix, 뷰(카메라)의 변환을 나타내는 ViewMatrix, 프로젝션의 변환(투영의 변환)을 나타내는 projectionMatrix 가 순서대로 곱해져서 output.position이 정해진다. ( ※ 세 행렬의 곱(MVP Matrix)을 통해서 최종적으로 점이 찍히는 위치를 계산하여 변환하는 것을 MVP Transformation이라고 부른다.)
1-1-2. Color.ps
// Pixel Shader
struct PixelInputType
{
float4 position : SV_POSITION;
float4 color : COLOR;
};
float4 ColorPixelShader(PixelInputType input) : SV_TARGET
{
return input.color;
}
화면에 렌더링 될 다각형에 각 픽셀을 그린다.
※ 정점 셰이더에서 MVP Transformation을 통해 픽셀의 변환이 일어난 후에 각 정점의 색이 정해진다(ColorVertexShader). 이 점들은 GPU를 통해서 나머지 픽셀의 색들에 대한 보간이 이루어지고 그 점들을 SV_POSITION과 COLOR를 통해 픽셀 셰이더에 전달된다. 마지막으로 픽셀 셰이더는 GPU에서 처리된 픽셀들의 보간 된 값들을 결정짓는 역할을 하게 된다.
2. ColorShaderClass.h
#pragma once
#ifndef _COLORSHADERCLASS_H_
#define _COLORSHADERCLASS_H_
#include <d3d11.h>
#include <d3dcompiler.h>
#include <directxmath.h>
#include <fstream>
using namespace DirectX;
using namespace std;
class ColorShaderClass
{
private:
struct MatrixBufferType
{
XMMATRIX world;
XMMATRIX view;
XMMATRIX projection;
};
public:
ColorShaderClass();
ColorShaderClass(const ColorShaderClass&);
~ColorShaderClass();
bool Initialize(ID3D11Device*, HWND);
void Shutdown();
bool Render(ID3D11DeviceContext*, int, XMMATRIX, XMMATRIX, XMMATRIX);
private:
bool InitializeShader(ID3D11Device*, HWND, WCHAR*, WCHAR*);
void ShutdownShader();
void OutputShaderErrorMessage(ID3D10Blob*, HWND, WCHAR*);
bool SetShaderParameters(ID3D11DeviceContext*, XMMATRIX, XMMATRIX, XMMATRIX);
void RenderShader(ID3D11DeviceContext*, int);
private:
ID3D11VertexShader* m_vertexShader;
ID3D11PixelShader* m_pixelShader;
ID3D11InputLayout* m_layout;
ID3D11Buffer* m_matrixBuffer;
};
#endif
2-1. Initialize
Color.vs과 Color.ps를 가져오고 InitalizeShader를 호출한다.
2-2. Shutdown
ShutdownShader를 호출하여 셰이더를 종료한다.
2-3. Render
SetShaderParameters를 먼저 호출하여 셰이더 내부의 파라미터를 호출한다.
2-4. InitializeShader
정점 셰이더와 픽셀 셰이더를 초기화하는 함수
- D3DCompileFromFile함수를 활용해서 정점 셰이더와 픽셀 셰이더를 컴파일 한다.
- 정점 셰이더를 생성하여 CreateVertexShader과 CreatePixelShader 함수를 이용하여 셰이더들을 생성한다.
- 셰이더에서 처리할 꼭짓점들의 데이터의 레이아웃을 만든다. 각 요소들에 대한 정보를 저장하게 된다.
- CreateInputLayout 함수를 이용하여 정점 입력 레이아웃을 생성한다.
- 정점 셰이더에서 활용할 상수 버퍼를 CreateBuffer 함수를 활용하여 상수 버퍼를 생한다.
- 상수 버퍼와 셰이더를 클래스 멤버 변수에 저장하고 성공하면 true를 반환한다.
※ 상수 버퍼 : 그래픽스 파이프라인에서 사용되는 상수 데이터를 GPU 전달하고 셰이더에서 불러올 때 쓰인다. 전달되는 정보는 행렬, 라이트, 재질 속성 등이다. 상수 버퍼는 CPU에서 GPU에 저장된 데이터를 가져와 수정 및 업데이트를 하고 다시 GPU에 저장한다.
2-5. ShutdownShader
InitializeShader에서 설정된 인터페이스들을 해제한다.
2-6. OutputShaderErrorMessage
정점 셰이더와 픽셀 셰이더를 컴파일 할 때 오류가 생길 경우 메세지를 출력한다.
2-7. SetShaderParameters
정점 셰이더에서 사용할 3개의 행렬인 WorldMatrix, ViewMatrix, ProjectionMatrix를 상수 버퍼에 설정한다.
worldMatrix = XMMatrixTranspose(worldMatrix);
viewMatrix = XMMatrixTranspose(viewMatrix);
projectionMatrix = XMMatrixTranspose(projectionMatrix);
전달하기 전에는 반드시 전치 행렬을 전달해줘야 한다.
MatrixBufferType의 구조체의 포인터 변수 dataPtr를 선언하고 이 변수를 활용해서 3개의 행렬 데이터를 복사하여 GPU 셰이더에서 사용될 수 있도록 한다.VSSetConstantBuffers 함수를 활용하여 정점 셰이더의 상수 버퍼를 설정하고 m_matrixBuffer를 사용하여 상수 버퍼를 전달하는 과정을 거친다.
2-8. RenderShader
이 함수가 호출되면 설정했던 그림을 렌더링 하게 된다. GPU에게 정점 버퍼의 데이터 형식을 알려주고 정점 버퍼에서 렌더링 하는데 필요한 정점 셰이더와 픽셀 셰이더를 설정한다. 이 과정이 끝나면 DrawIndexed함수가 호출되며 렌더링을 한다.
'DirectX' 카테고리의 다른 글
DirectX11. 5) Texture (0) | 2023.06.13 |
---|---|
DirectX11. 4) Buffer, Shader II (0) | 2023.06.12 |
DirectX11. 2) D3D11 Initialize (1) | 2023.06.09 |
DirectX11. 1) 창 띄우기 (0) | 2023.06.07 |
4. DirectXMath - Transform (1) | 2023.05.02 |