02
23

 


버퍼

 

버퍼란 Shader 프로그래밍에서 GPU 자원(ID3D11Buffer : ID3D11Resource)를 뜻한다.

버텍스 버퍼, 인덱스 버퍼, 상수 버퍼 등 이에 해당된다.

셰이더와 프로그램이 연동되는 변수라고 생각하면 편하다.

 

상수 버퍼

 

상수버퍼는 말 그대로 상수를 데이터를 보내주는 버퍼로,

앞서 얘기한 월드 변환 행렬, 뷰 변환 행렬, 투영 변환 행렬을 셰이더로 넘겨주어

각 정점에 곱할 수 있게 해 준다. 

 

1. 상수버퍼에 넣어줄 구조체

struct CB_DATA
{
	KMatrix  matWorld;
	KMatrix  matView;
	KMatrix  matProj;
	KMatrix  matNormal;
	KVector4 vLightDir;
	KVector4 vValue; // 시간 값 xyzw
};

 

상수 버퍼 구조체를 이용해서 넘기면 편하게 받을 수 있다.

채워진 구조체 자체를 보낼 수 있기 때문이다. 

 

2. 상수 버퍼 생성

HRESULT KObject::CreateConstantBuffer()
{
    HRESULT hr = S_OK;
    D3D11_BUFFER_DESC bd;
    ZeroMemory(&bd, sizeof(D3D11_BUFFER_DESC));
    bd.ByteWidth = sizeof(CB_DATA);
    bd.Usage = D3D11_USAGE_DEFAULT;
    bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
    D3D11_SUBRESOURCE_DATA data;
    ZeroMemory(&data, sizeof(D3D11_SUBRESOURCE_DATA));
    data.pSysMem = &m_cbData;
    hr = g_pd3dDevice->CreateBuffer(&bd, &data, &m_pConstantBuffer);
    if (FAILED(hr)) return hr;
    return hr;
}

 

Direct 디바이스로 버퍼를 만드는 함수 CreateBuffer()로

m_pConstantBuffer주소에 버퍼를 만든다. 

필요한 D3D11_BUFFER_DESC, D3D11_SUBRESOURCE_DATA 구조 포인터를 기입한다.  

 

3. 상수버퍼의 갱신 및 셰이더 상수 버퍼 설정

 

자체적으로 구현된 렌더 파이프라인에 넣어주면 된다. 

리소스, 상수버퍼와 셰이더의 변수와 연동한다. 

 

   pContext->UpdateSubresource(
        m_pConstantBuffer.Get(), 0, NULL, &m_cbData, 0, 0);

    pContext->VSSetConstantBuffers(0, 1, m_pConstantBuffer.GetAddressOf());
    pContext->PSSetConstantBuffers(0, 1, m_pConstantBuffer.GetAddressOf());

 

0, 1 숫자는 0번째 슬롯에 1개를 보내겠다는 의미로 

Buffers <- s가 붙었다는 것은 여러 개를 보낼 수 있다는 뜻이다.

자세한 함수 설명은 msdn을 참조..

 

4. 셰이더

 

//HLSL->c언와 유사하다.
//정점쉐이더는 반드시 float4:SV_POSITION(레지스터)로 반환한다.
//정점버퍼의 정점1개마다 호출된다.
//POSITION(시멘틱:의미구조)

cbuffer CBuf
{
	matrix g_matWorld : packoffset(c0);
	matrix g_matView : packoffset(c4);
	matrix g_matProj : packoffset(c8);
	float4 vLightDir : packoffset(c12);
	float4	vValue : packoffset(c13); 
};

struct VS_OUTPUT
{
	float4 p : SV_POSITION;
	float3 n : NORMAL;
	float4 c : COLOR0;
	float2 t : TEXCOORD0;
};

VS_OUTPUT VS(float3 p: POSITION, float3 n : NORMAL, float4 c : COLOR, float2 t : TEXTURE) 
{
	VS_OUTPUT pOut = (VS_OUTPUT)0;
	float4 vLocal = float4(p,1.0f);
	float4 vWorld = mul(vLocal, g_matWorld);
	float4 vView = mul(vWorld, g_matView);
	float4 vProj = mul(vView, g_matProj);
	pOut.p = vProj;
	pOut.n = n;
	pOut.c = c;
	pOut.t = t;
	return pOut;
}

 

상단에 있는 것이 상수버퍼 구조체이다. 

셰이더에서 상수버퍼는 레지스터 단위로 할당이 되어야 한다. 

float4가 기준이다. 행렬인 경우 (Matrix)는 float4 4개가 있는 것과 같으므로

4개씩 늘어나고 float4는 1개씩 자리를 이동하는 모습이다.

 

결과 - 공간 변환 (박스 출력)

 

 

결과 - 상수버퍼로 시간을 전달, cos 값으로 정점 이동

 

COMMENT