1. 📦 TextureBuffer 클래스 구조

📌 왜 필요한가?

텍스처 이미지도 결국은 수많은 픽셀 데이터로 구성된 "데이터 덩어리"입니다.
ComputeShader가 이 데이터를 조작하려면, GPU에서 읽고 쓸 수 있는 구조로 버퍼를 준비해야 합니다.


📁 TextureBuffer 구성 요약

구성 요소설명
_input원본 텍스처를 GPU에서 읽을 수 있게 만든 자원
_srvShader Resource View. ComputeShader가 읽기 위해 참조하는 뷰
_output조작된 데이터를 담을 텍스처
_uavUnordered Access View. ComputeShader가 쓸 수 있도록 설정
_outputSRV결과 텍스처를 SRV로도 참조할 수 있게 추가 뷰 생성

🛠 처리 과정

[1] CreateInput

  • 전달받은 텍스처의 정보(크기, 포맷 등)를 바탕으로 _input 자원을 새로 생성
  • DC->CopyResource()를 사용해 원본 텍스처 복사

[2] CreateSRV

  • _input 텍스처를 읽기 전용 자원으로 SRV 생성

[3] CreateOutput

  • 동일한 포맷/크기로 출력용 텍스처 생성
  • UAV + SRV 바인딩 가능하도록 설정

[4] CreateUAV

  • _output 텍스처에 대해 UAV 생성 → ComputeShader가 이 자원에 쓸 수 있음

[5] CreateResult

  • _output 자원을 SRV로도 읽을 수 있도록 추가로 SRV 생성

2. 🧠 핵심 Shader 코드 (26. TextureBufferDemo.fx)

```hlsl

[numthreads(32, 32, 1)]
void CS(uint3 id : SV_DispatchThreadID)
{
float4 color = Input.Load(int4(id, 0));

// 방법 1: 원래 색상 그대로
// Output[id] = color;

// 방법 2: 색상 반전
Output[id] = 1.0f - color;

// 방법 3: 회색 톤
// Output[id] = float4((color.r + color.g + color.b) / 3.0f, ... );

}


### ✔️ 포인트 정리
- `SV_DispatchThreadID`는 전역 유니크한 ID이므로 픽셀 단위 조작 가능
- `numthreads(32, 32, 1)` → 스레드 그룹 하나에 1024개 스레드
- 이미지 전체 크기 기준으로 그룹 개수(x, y)를 계산해 `Dispatch()` 호출

---

## 3. 🧩 TextureBufferDemo 클래스 실습

### 주요 흐름
1. `TextureBuffer` 생성 → 원본 텍스처 로드 (`veigar.jpg`)
2. `_srv`, `_uav` 바인딩
3. `Dispatch()`로 ComputeShader 실행
4. 가공된 결과를 `GetOutputSRV()`로 받아 사용

```cpp
ComPtr<ID3D11ShaderResourceView> TextureBufferDemo::MakeComputeShaderTexture()
{
	auto shader = make_shared<Shader>(L"26. TextureBufferDemo.fx");

	auto texture = RESOURCES->Load<Texture>(L"Veigar", L"..\\Resources\\Textures\\veigar.jpg");
	auto buffer = make_shared<TextureBuffer>(texture->GetTexture2D());

	shader->GetSRV("Input")->SetResource(buffer->GetSRV().Get());
	shader->GetUAV("Output")->SetUnorderedAccessView(buffer->GetUAV().Get());

	uint32 width = buffer->GetWidth();
	uint32 height = buffer->GetHeight();
	uint32 arraySize = buffer->GetArraySize();

	uint32 x = max(1, (width + 31) / 32);
	uint32 y = max(1, (height + 31) / 32);
	shader->Dispatch(0, 0, x, y, arraySize);

	return buffer->GetOutputSRV();
}

4. 🖼 결과 사용

수정된 텍스처를 화면에 출력

auto newSrv = MakeComputeShaderTexture();
auto texture = make_shared<Texture>();
texture->SetSRV(newSrv);

이렇게 하면 가공된 텍스처를 Material에 세팅해 여러 객체에 반영할 수 있음.


profile
李家네_공부방

0개의 댓글