GPU 셰이더에 일정한 데이터를 효율적으로 전달하기 위한 고정 크기의 메모리 블록이다.
즉, 한 번에 GPU에게 다양한 데이터를 전달할 수 있다.
주로 변하지 않는 변수들을 셰이더에 넘겨줄 때 사용한다.
정렬 : 16Byte 단위로 정렬되어야 GPU가 제대로 읽을 수 있다.
예시 :
cbuffer ExampleBuffer
{
float4 position; // 16Byte
float3 direction; // 12Byte
float padding; // 4Byte
}
C++와 HLSL 양쪽에서 동일한 메모리 정렬을 보장하기 위해 자료형 정렬 기준을 맞춰야 한다.
struct CB_Context
{
FMatrix View;
FMatrix ViewInverse;
FMatrix Projection;
FMatrix ViewProjection;
float RunningTime;
float Padding[3]; // 16Byte를 맞추기 위한 패딩
} FrameData;
ID3D11Buffer* constantBuffer = nullptr;
D3D11_BUFFER_DESC cbDesc = {};
cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
cbDesc.ByteWidth = sizeof(CB_Context);
cbDesc.Usage = D3D11_USAGE_DYNAMIC;
cbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
device->CreateBuffer(&cbDesc, nullptr, &constantBuffer);
CB_Context cbData = {};
cbData.View = XMMatrixTranspose(viewMatrix);
cbData.ViewInverse = XMMatrixTranspose(XMMatrixInverse(nullptr, viewMatrix));
cbData.Projection = XMMatrixTranspose(projMatrix);
cbData.ViewProjection = XMMatrixTranspose(viewMatrix * projMatrix);
cbData.RunningTime = totalTime;
D3D11_MAPPED_SUBRESOURCE mappedResource;
context->Map(constantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
memcpy(mappedResource.pData, &cbData, sizeof(CB_Context));
context->Unmap(constantBuffer, 0);
context->VSSetConstantBuffers(0, 1, &constantBuffer);
context->PSSetConstantBuffers(0, 1, &constantBuffer);
cbuffer CB_Context
{
matrix View;
matrix ViewInverse;
matrix Projection;
matrix ViewProjection;
float RunningTime;
};
VS_OUTPUT VS(VS_INPUT input)
{
VS_OUTPUT output;
float4 worldPos = float4(input.Position, 1.0f);
output.Position = mul(worldPos, ViewProjection);
return output;
}