UE5

[week2] Texture Rendering

검정색필통 2025. 3. 20. 23:31

# DirectX 11 렌더링 파이프라인 (함수 호출 기반 정리)

## CPU 준비 단계 (함수 단위)
1. **디바이스 및 스왑 체인 생성**
   - `D3D11CreateDeviceAndSwapChain()`

2. **렌더 타겟 및 뎁스 스텐실 준비**
   - `SwapChain->GetBuffer()`
   - `Device->CreateRenderTargetView()`
   - `Device->CreateDepthStencilView()`

3. **자원(Resource) 준비**
   - 정점 버퍼: `Device->CreateBuffer()`
   - 인덱스 버퍼: `Device->CreateBuffer()`
   - 셰이더 컴파일: `D3DCompileFromFile()`
   - 셰이더 생성: `Device->CreateVertexShader()`, `Device->CreatePixelShader()`
   - 인풋 레이아웃 생성: `Device->CreateInputLayout()`
   - 상수 버퍼 생성: `Device->CreateBuffer()` (D3D11_BIND_CONSTANT_BUFFER)
   - 텍스처 및 샘플러: `Device->CreateTexture2D()`, `Device->CreateSamplerState()`


## 한 프레임 렌더링 함수 호출 순서
1. Context->ClearRenderTargetView()
2. Context->ClearDepthStencilView()
3. Context->OMSetRenderTargets()
4. Context->IASetVertexBuffers()
5. Context->IASetIndexBuffer()
6. Context->IASetInputLayout()
7. Context->VSSetShader(), PSSetShader(), (필요 시 GS/HS/DS)
8. Context->VSSetConstantBuffers(), PSSetConstantBuffers()
9. Context->RSSetViewports()
10. Context->PSSetSamplers(), PSSetShaderResources()
11. Context->Draw() 또는 DrawIndexed()
12. SwapChain->Present()

 

 

자원(메모리/성능) 소모가 큰 순서

1️⃣ 텍스처 생성 / 로드 고해상도 텍스처는 VRAM 메모리를 대량 사용하며 압축 및 비압축 처리 비용도 큼
2️⃣ 셰이더 컴파일 (D3DCompileFromFile) 실시간 컴파일은 CPU 부하가 매우 큼 (실제 게임은 보통 미리 컴파일한 *.cso 파일 사용)
3️⃣ 버퍼 생성 (CreateBuffer) 대규모 Vertex / Index / ConstantBuffer 생성 시 메모리 할당 비용 발생
4️⃣ InputLayout 생성 내부 구조 분석과 파싱으로 약간의 자원 소비 (한 번만 생성 후 캐싱 가능)
5️⃣ PSSetShaderResources (텍스처 바인딩) 너무 자주 바인딩하면 드라이버 state change 비용 발생
6️⃣ Draw() / DrawIndexed() 호출 GPU 실행 명령이긴 하지만, 이미 준비된 자원 위에서 실행되므로 상대적으로 비용은 낮음
7️⃣ OMSetRenderTargets / Clear 호출 렌더타겟 & 뎁스 초기화는 GPU 메모리 클리어 작업, 비용 있지만 짧은 편
8️⃣ VSSetShader / PSSetShader 호출 상태 설정 변경 정도이므로 자원 소모는 낮음

 

 

자원 소모 최적화 팁

✅ 1️⃣ 텍스처 최적화

DDS(DXT 압축) 텍스처 사용 압축된 텍스처 포맷으로 VRAM 사용량 최소화, 로딩 속도 증가, GPU-Friendly
Mipmap 포함 저장 멀리 있는 물체는 낮은 해상도로 자동 렌더링 → 성능 최적화
필요한 해상도만 사용 8K 텍스처 불필요하면 4K / 2K 로 줄여서 메모리 절약
다중 텍스처 통합(Atlas) 여러 작은 텍스처를 한 장으로 묶어 Draw Call & state change 최소화

✅ 2️⃣ 셰이더 최적화

런타임 컴파일 금지 D3DCompileFromFile() 대신 미리 컴파일된 cso 파일 로드 사용
셰이더 캐싱 시스템 구축 동일한 셰이더 재사용 시 재컴파일/재로드 하지 않음, 메모리 절약
불필요한 if / 분기 최소화 GPU 분기 처리는 비싼 연산 → 브랜치 대신 조건 mask 처리 추천

✅ 3️⃣ 버퍼 관리 최적화

큰 정적 버퍼는 한 번 생성 후 재사용 매 프레임 CreateBuffer() 호출하지 말고 초기화 시 생성해서 계속 유지
동적 버퍼는 D3D11_USAGE_DYNAMIC + Map() 사용 CPU 가 자주 업데이트하는 경우 Map/Unmap 으로 효율적 쓰기 가능
Stream Output 또는 Instancing 사용 반복되는 데이터 전송을 줄이고 GPU 내부 인스턴싱으로 성능 향상

✅ 4️⃣ 상태 변화(State Change) 최적화

PSSetShaderResources / VSSetShader / Sampler 최소 변경 매 Draw Call 마다 텍스처, 쉐이더 바꾸면 드라이버 오버헤드 증가 — 유사 상태 묶어 그리기 (Batch) 추천
DrawCall 정리 (Batching) 유사한 메터리얼, 동일 텍스처를 사용하는 객체들을 한 번에 처리해서 상태 전환 비용 최소화
렌더링 순서 정리 (Material sorting) 텍스처나 셰이더 교체가 적은 순서대로 렌더링을 정리하면 GPU 스테이트 변경 비용 절약

✅ 5️⃣ Present & VSync 주의

VSync 끄기(개발 중) 성능 측정 시 GPU 제한 없이 성능 체크 가능
VSync 켜기(출시) 화면 찢어짐 방지, 그러나 GPU 대기 시간이 추가되므로 FPS 제한 확인 필요

✅ 전체 최적화 흐름 추천

  1. 초기화 시 정적 리소스 전부 로드 & 캐싱
  2. 렌더링 시 텍스처 & 셰이더 상태 변경 최소화 → 비슷한 메터리얼끼리 묶어서 그리기
  3. 자주 변경되는 정점 데이터는 동적 버퍼 사용 (Map/Unmap)
  4. draw 호출 개수 최소화 (인스턴싱 또는 배치)
  5. 텍스처는 압축 포맷과 mipmap 필수 적용
  6. Shader 컴파일은 무조건 사전 컴파일 후 cso 파일 로딩

 

✅ 3️⃣ 정적 버퍼 vs 동적 버퍼 비교 정리

항목 정적 버퍼 (D3D11_USAGE_DEFAULT) 동적 버퍼 (D3D11_USAGE_DYNAMIC)
용도 변경 거의 없는 데이터 (지형, 모델 메쉬 등) 프레임마다 업데이트되는 데이터 (UI, 파티클, 애니메이션 변형 등)
CPU 접근 ❌ 없음 (GPU 전용) ✅ CPU 쓰기 가능 (Map/Unmap 사용)
업데이트 방법 변경 시 리소스를 다시 생성해야 함 Map(DISCARD) & memcpy & Unmap
장점 GPU 최적화 / 빠른 렌더링 CPU가 자주 바꾸는 데이터 처리에 최적화
단점 변경 어려움 (매번 리소스 새로 생성 필요) 잘못 설계하면 빈번한 복사 및 GPU Sync 문제가 발생할 수 있음

 

✅ 배치 렌더링(Batching) vs 인스턴싱(Instancing) 비교

항목 배치 렌더링 (Batching) 인스턴싱 (Instancing)
방식 CPU 에서 여러 오브젝트 정점 데이터를 월드 변환 후 큰 버퍼로 묶어서 전송 정점 버퍼는 1개, 인스턴스 데이터(월드행렬 등)를 추가로 보내 GPU에서 변환 처리
움직임/변화 불가능 또는 버퍼 재생성 필요 실시간 가능 (인스턴스 버퍼만 매 프레임 업데이트)
DrawCall 개수 1회 Draw() 호출 (묶어서 처리) 1회 DrawIndexedInstanced() 호출로 여러 인스턴스 렌더링
CPU 부하 큼 (큰 정점 버퍼 합치고 계산 필요) 적음 (인스턴스 버퍼 갱신만 하면 됨)
GPU 효율 중간 (큰 정점량이면 오히려 부담) 높음 (병렬 처리 최적화 가능)
주로 사용하는 상황 고정 지형, 타일맵, 변경 안 되는 배경 나무, 풀, 파티클, 반복되는 작은 오브젝트 대량 렌더링

 

2주차 배운 것

 

1. Actor와 ActorComponent

2. 대략적인 생명주기

3. 텍스쳐 렌더링

4. 인덱스 버퍼 사용방법

5. SubUV