텍스처 이미지도 결국은 수많은 픽셀 데이터로 구성된 "데이터 덩어리"입니다.
ComputeShader가 이 데이터를 조작하려면, GPU에서 읽고 쓸 수 있는 구조로 버퍼를 준비해야 합니다.
| 구성 요소 | 설명 |
|---|---|
_input | 원본 텍스처를 GPU에서 읽을 수 있게 만든 자원 |
_srv | Shader Resource View. ComputeShader가 읽기 위해 참조하는 뷰 |
_output | 조작된 데이터를 담을 텍스처 |
_uav | Unordered Access View. ComputeShader가 쓸 수 있도록 설정 |
_outputSRV | 결과 텍스처를 SRV로도 참조할 수 있게 추가 뷰 생성 |
_input 자원을 새로 생성DC->CopyResource()를 사용해 원본 텍스처 복사_input 텍스처를 읽기 전용 자원으로 SRV 생성_output 텍스처에 대해 UAV 생성 → ComputeShader가 이 자원에 쓸 수 있음_output 자원을 SRV로도 읽을 수 있도록 추가로 SRV 생성[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();
}
auto newSrv = MakeComputeShaderTexture();
auto texture = make_shared<Texture>();
texture->SetSRV(newSrv);
이렇게 하면 가공된 텍스처를 Material에 세팅해 여러 객체에 반영할 수 있음.