✅ 목표

  • 지금까지 따로따로 관리하던 MeshInstancing, ModelInstancing, AnimationInstancing을 하나로 통합.
  • 하나의 Shader(23. RenderDemo.fx)로 모든 종류의 렌더링을 처리할 수 있게 구성.
  • GameObject마다 어떤 타입의 렌더링인지 pass 번호만 지정해주면 끝!
  • 최종적으로는 Draw Call을 획기적으로 줄이고, 성능은 극대화된 구조 구축이 목표.

1️⃣ RenderDemo 클래스 생성 및 세팅

🎯 기존 AnimInstancingDemo를 복사해서 RenderDemo로 생성

  • Client/Game 필터에 RenderDemo 클래스를 추가
  • Shader만 다음과 같이 변경:
_shader = make_shared<Shader>(L"23. RenderDemo.fx");

⚙️ Main에서 등록

#include "RenderDemo.h"
desc.app = make_shared<RenderDemo>();
  • 이제부터는 이 클래스에서 애니메이션 캐릭터, 모델, 메쉬를 한꺼번에 배치할 예정.

2️⃣ 통합 Shader: 23. RenderDemo.fx

  • Shader는 기존 20, 21, 22번 Shader를 하나로 묶은 형태.
  • 핵심은 pass 번호만 다르게 설정해서 렌더링 타입을 구분한다.
technique11 T0
{
    PASS_VP(P0, VS_Mesh, PS)
    PASS_VP(P1, VS_Model, PS)
    PASS_VP(P2, VS_Animation, PS)
}

각 VS는 따로 정리되어 있으며, 공통 부분은 00. Render.fx로 분리해 관리한다.


3️⃣ 공통 Shader 파일: 00. Render.fx

#ifndef _RENDER_FX_
#define _RENDER_FX_

#include "00. Global.fx"

#define MAX_MODEL_TRANSFORMS 250
#define MAX_MODEL_KEYFRAMES 500
#define MAX_MODEL_INSTANCE 500

// [1] Mesh 렌더링용 구조체 + VS
...

// [2] Model 렌더링용 구조체 + VS (BoneTransform)
...

// [3] Animation 렌더링용 구조체 + VS (TweenBuffer, TransformMap)
...

#endif

이 파일에는 MeshOutput, VertexMesh, VertexModel, GetAnimationMatrix() 함수, 그리고 각각의 VS가 통합되어 있다.

이제 Shader마다 반복해서 작성할 필요 없이, #include "00. Render.fx" 한 줄이면 끝!


4️⃣ RenderDemo.cpp에서 세 가지 타입의 오브젝트 배치

[A] 애니메이션 캐릭터 500개

auto obj = make_shared<GameObject>();
obj->AddComponent(make_shared<ModelAnimator>(_shader));
obj->GetModelAnimator()->SetPass(2); // Pass 2: Animation

[B] 일반 Model 오브젝트 100개

obj->AddComponent(make_shared<ModelRenderer>(_shader));
obj->GetModelRenderer()->SetPass(1); // Pass 1: Model

[C] 메쉬 구체 100개

obj->AddComponent(make_shared<MeshRenderer>());
obj->GetMeshRenderer()->SetPass(0); // Pass 0: Mesh
  • 모든 오브젝트는 _objs 벡터에 담기고, 이후 INSTANCING->Render(_objs)를 통해 일괄 렌더링된다.

5️⃣ 각 Pass별 VS 처리 구조

Pass 번호타입VS 함수명설명
0MeshVS_Mesh단순 월드 변환만
1ModelVS_ModelBoneIndex로 BoneTransform 사용
2AnimVS_Animation애니메이션 행렬 계산 + 트윈

즉, 렌더러에서 SetPass(x)만 적절히 해주면 Shader 내부에서 자동 분기되어 렌더링된다.


🧠 핵심 구조

🎯 통합 처리 구조

// RenderDemo.cpp
obj->Get[RendererType]()->SetPass(0 or 1 or 2);
_objs.push_back(obj);

// InstancingManager.cpp
Render(_objs); // 내부에서 타입별로 자동 분리 처리

🎯 Shader 분기

technique11 T0
{
    PASS_VP(P0, VS_Mesh, PS)
    PASS_VP(P1, VS_Model, PS)
    PASS_VP(P2, VS_Animation, PS)
}

🎯 장점

  • 통합적인 구조: Shader / InstancingBuffer / GameObject 분리 없이 일괄 관리
  • 확장 용이: Pass만 추가하면 새로운 렌더러 쉽게 추가 가능
  • 유지보수 편리: 공통 Shader 파일에서 관리

profile
李家네_공부방

0개의 댓글