High Level Shader Language (HLSL)
카테고리: Graphics
태그: DirectX
홍정모님의 그래픽스 새싹코스 강의를 듣고 정리한 내용입니다.
🐥 Vertex Shader
Constant Buffer
// Constant Buffer in CPU
struct ModelViewProjectionConstantBuffer {
Matrix model;
Matrix view;
Matrix projection;
};
static_assert((sizeof(ModelViewProjectionConstantBuffer) % 16) == 0,
"Constant Buffer size must be 16-byte aligned");
// ...
// Constant Buffer in GPU (Vertex Shader)
cbuffer ModelViewProjectionConstantBuffer : register(b0) {
matrix model;
matrix view;
matrix projection;
};
- CPU에서 버퍼에 담는 데이터의 구조와 GPU에서 받는 버퍼의 데이터 구조가 같아야 함
- GPU가속을 위해 데이터는 16-byte의 배수로 설정
- Shader 코드 안에서 버퍼가 어떤 타입의 레지스터에 들어가는지 명시해줌
Input/Output Buffer
// Input Elements in CPU
vector<D3D11_INPUT_ELEMENT_DESC> inputElements = {
{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0,
D3D11_INPUT_PER_VERTEX_DATA, 0},
{"COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 4 * 3,
D3D11_INPUT_PER_VERTEX_DATA, 0},
{"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 4 * 3 + 4 * 3,
D3D11_INPUT_PER_VERTEX_DATA, 0},
};
// Data struct in GPU
struct VertexShaderInput {
float3 pos : POSITION;
float3 color : COLOR0;
float2 texcoord : TEXCOORD0;
};
struct PixelShaderInput {
float4 pos : SV_POSITION;
float3 color : COLOR;
float2 texcoord : TEXCOORD0;
};
- HLSL에서는 float3, float4x4, matrix 등 아주 유용한 데이터 타입을 사용할 수 있음(x,y,z,w로 접근 가능)
- 일반적으로 vertex shader의 input/output 데이터 구조를 정의하고 사용
- 변수 옆에 Semantics 명시해야 함 (cpu에서 지정한 input elements와 일치해야 함)
Main Function (Kernel)
// Compile Shader in CPU
HRESULT hr = D3DCompileFromFile(filename.c_str(), 0, 0, "main", "vs_5_0",
compileFlags, 0, &shaderBlob, &errorBlob);
// Shader code in hlsl file
PixelShaderInput main(VertexShaderInput input) {
PixelShaderInput output;
float4 pos = float4(input.pos, 1.0f);
pos = mul(pos, model);
pos = mul(pos, view);
pos = mul(pos, projection);
output.pos = pos;
output.color = input.color;
output.texcoord = input.texcoord;
return output;
}
- main 메서드의 이름은 cpu에서 shader compile할 때 표기한 이름과 맞아야 함
- 앞서 정의한 input/output 구조로 작성
🐥 Pixel Shader
// Constant Buffer in CPU
struct PixelShaderConstantBuffer {
float xSplit;
float padding[3];
};
// Pixel Shader (hlsl file)
cbuffer PixelShaderConstantBuffer : register(b0) { float xSplit; }
struct PixelShaderInput {
float4 pos : SV_POSITION;
float3 color : COLOR;
float2 texcoord : TEXCOORD0;
};
float4 main(PixelShaderInput input) : SV_TARGET {
return input.texcoord.x > xSplit ? float4(0.0, 0.0, 1.0, 1.0)
: float4(1.0, 0.0, 0.0, 1.0);
}
- Pixel Shader에 필요한 constant buffer 역시 16-byte 단위로 받아야 하기 때문에 padding 변수 추가해서 넘겨줌
- Pixel Shader의 input은 vertex shader의 output 타입
- DirectX가 알잘딱센으로 rasterization & Correction Interpolation 해줌
🐥 Results
댓글 남기기