[Graphics] Constant Buffer

2025. 4. 7. 21:51·게임개발/Graphics

 

Constant Buffer를 이용해 행렬정보(지금은 offset)를 매 프레임마다 한번에 업데이트함

 

Constant Buffer는 Vertex Shader 단계에서 정점 변환에 필요한 데이터를 셰이더에 전달하는 데 사용됩니다.

Constant Buffer: GPU 셰이더에 자주 바뀌는 데이터를 빠르고 효율적으로 전달하기 위한 구조체 기반 메모리 블록.

 

[Constant Buffer 사용 X]

deviceContext->VSSetShaderConstantF(0, world.m, 4);      // world matrix
deviceContext->VSSetShaderConstantF(4, view.m, 4);       // view matrix
deviceContext->VSSetShaderConstantF(8, projection.m, 4); // projection matrix

: 매 프레임마다 셰이더에 개별 데이터(행렬, float 등) 전달, API 호출이 많아지고, CPU와 GPU 사이의 통신 비용이 높아짐

 

[Constant Buffer 사용]

struct Transform
{
    Matrix world;
    Matrix view;
    Matrix projection;
};

Transform transform;
transform.world = ...;
transform.view = ...;
transform.projection = ...;

context->UpdateSubresource(_constantBuffer.Get(), 0, nullptr, &transform, 0, 0);
context->VSSetConstantBuffers(0, 1, _constantBuffer.GetAddressOf());

: Transform 구조체 하나에 세 개의 행렬을 묶어서 한 번에 전송.  CPU → GPU 전송을 최소화하면서도 셰이더는 자주 접근 가능

 

[Struct.h]

/* Constant Buffer, 16Byte 정렬 필요 */
struct TransformData
{
	Vec3 offset;		// offset 0, size = 3 * sizeof(float) = 12Byte;
	float dummy;		// offset 12, size = 1 * sizeof(float) = 4Byte;
};

 

[DefaultVertexShader.hlsl]

cbuffer TransformData : register(b0)
{
	float4 offset;
}

// IA - VS - RS(VS_main에서 자동 처리) - PS - OM
// VS_main은 정점 단위로 실행, 위치 관련 처리
VS_OUTPUT VS_main(VS_INPUT input)
{
	VS_OUTPUT output;
	output.position = input.position + offset;
	output.uv = input.uv;

	return output;
}

 

[Game.h]

// Game.h
private:
	/* Constant Buffer 생성 */
	void CreateConstantBuffer();
private:
	/* Constant Buffer */
	TransformData _transformData;
	ComPtr<ID3D11Buffer> _constantBuffer;

[Game.cpp]

// Game.cpp
void Game::Update()
{
	_transformData.offset.x += 0.003f;
	_transformData.offset.y += 0.003f;

	D3D11_MAPPED_SUBRESOURCE subResource;
	ZeroMemory(&subResource, sizeof(subResource));

	// GPU의 Constant Buffer를 CPU에서 쓰기 위한 접근 요청
	_deviceContext->Map(
		_constantBuffer.Get(),			// 업데이트할 Constant Buffer
		0,								// 서브리소스 인덱스 (일반적으로 0)
		D3D11_MAP_WRITE_DISCARD,		// 이전 내용은 버리고 새로 쓰기 (가장 일반적인 방식)
		0,								// Reserved (항상 0)
		&subResource					// 매핑 결과를 받을 구조체 (CPU가 접근 가능한 포인터 제공됨)
	);
	// CPU에서 GPU 버퍼에 데이터 복사 (_transformData → Constant Buffer에 업로드)
	::memcpy(subResource.pData, &_transformData, sizeof(_transformData));
	// 맵핑 해제 → GPU에서 읽을 수 있도록 다시 연결
	_deviceContext->Unmap(_constantBuffer.Get(), 0);
}

void Game::Render()
{
	/* 랜더링 시작 */
	RenderBegin();

	/* IA - VS - RS - PS - OM */
	{
		// IA (Input Assembler) : 정점의 정보 전달
		// VS (Vertex Shader) : 정점의 위치/색상 등 가공
		_deviceContext->VSSetConstantBuffers(0, 1, _constantBuffer.GetAddressOf());

		// RS (Rasterizer) : 정점 → 픽셀로 삼각형 그리기

		// PS (Pixel Shader) : 픽셀 단위 색상 처리

		// OM (Output Merger) : 최종 픽셀을 렌더 타겟에 출력
	}

	/* 랜더링 끝, 화면에 출력 */
	RenderEnd();
}

void Game::CreateConstantBuffer()
{
	D3D11_BUFFER_DESC desc;
	ZeroMemory(&desc, sizeof(desc));

	// CPU 쓰기 가능, GPU 읽기 가능 (매 프레임마다 CPU에서 업데이트 할 경우)
	desc.Usage = D3D11_USAGE_DYNAMIC;
	desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
	desc.ByteWidth = sizeof(TransformData);
	desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;

	// 설정된 desc를 기반으로 GPU에 Constant Buffer 생성 후 _constantBuffer에 저장
	HRESULT hResult = _device->CreateBuffer(&desc, nullptr, _constantBuffer.GetAddressOf());
	CHECK(hResult);
}

 

'게임개발 > Graphics' 카테고리의 다른 글

[Graphics] 행렬  (0) 2025.04.21
[Graphics] RasterizerState, SampleState, BlendState  (0) 2025.04.10
[Graphics] 텍스처와 UV  (0) 2025.04.07
[Graphics] 삼각형 띄우기  (0) 2025.04.07
[Graphics] 초기화  (0) 2025.04.06
'게임개발/Graphics' 카테고리의 다른 글
  • [Graphics] 행렬
  • [Graphics] RasterizerState, SampleState, BlendState
  • [Graphics] 텍스처와 UV
  • [Graphics] 삼각형 띄우기
Mingurii
Mingurii
minkyeong's devlog
  • Mingurii
    Mingurii
    Mingurii
  • 전체
    오늘
    어제
    • 분류 전체보기 (53)
      • 알고리즘 - 기초 (8)
        • 재귀 (0)
        • 누적합 (8)
        • 최소신장트리 (0)
      • 알고리즘 (32)
        • 구현 (0)
        • DP (30)
        • DFS, BFS (0)
        • 백트래킹 (0)
        • 투포인터 (2)
        • 이진탐색 (0)
        • 그리디 (0)
        • 다익스트라 (0)
        • 크루스칼, 프림 (0)
        • 위상정렬 (0)
        • 플로이드-워셜 (0)
        • 유니온 파인드 (0)
        • 세그먼트 트리 (0)
      • 게임개발 (11)
        • Gameplay Ability System (0)
        • Graphics (11)
        • Lyra 분석 (0)
        • 다크 앤 다커 클론 코딩 (0)
        • After the Farmer Sleeps (0)
      • 서버 (2)
        • 공부 (2)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    c++
    2167
    1749
    9655
    알고리즘
    코테
    게임수학
    서버
    코딩테스트
    그래픽스
    누적합
    행렬
    DP
    백준
    2293
    DirectX11
    2294
    20438
    투포인터
    DX11
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
Mingurii
[Graphics] Constant Buffer
상단으로

티스토리툴바