High Level Shader Language (HLSL)

Date:     Updated:

카테고리:

태그:

홍정모님의 그래픽스 새싹코스 강의를 듣고 정리한 내용입니다.


🐥 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;
};

1

  • 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;
};

2

  • 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

ezgif com-crop



맨 위로 이동하기

Graphics 카테고리 내 다른 글 보러가기

댓글 남기기