[DX11,Live2D] 11_Live2D: Live2D CubismSDK

ChangJin·2025년 9월 17일
0

DirectX11

목록 보기
3/6
post-thumbnail

글에 사용된 모든 그림과 내용은 직접 작성한 것입니다.

[유튜브 영상]


[풀리퀘 보러가기]
https://github.com/Chang-Jin-Lee/D3D11-AliceTutorial/pull/10


글의 목적

D3D11에 Live2D Cubism를 연동해 model3.json 로드·마스크 처리·모션 재생·ImGui 제어까지 완성하고, setting/auto/extra 3가지 모션 그룹을 한 화면에서 선택/재생할 수 있도록 하는 방법에 대해서 알리기 위해서 작성


들어가기 전에 주의할 점 : 프로젝트에 SDK 경로를 잘 지정해야합니다. 추가 디렉토리와 lib 위치등을 잘 정의하세요

알게 된 점

  1. Live2D D3D11은 프레임마다 StartFrame(디바이스/컨텍스트/뷰포트)과 GenerateShader/SetDefaultRenderState 호출 순서를 지켜야 한다. -> 파이프라인을 지키지 않으면 CubismSDK만을 쓰는 게임을 만든다고 해도 실행되지 않습니다.
  2. SRV 수명: BindTexture가 AddRef를 안 하므로 텍스처 SRV는 별도 컨테이너에서 반드시 소유(해제되면 viewArray가 nullptr).
  3. dt 전달: 모션이 실행이 안되는 가장 흔한 이유는 deltaTime을 전달하지 않아서 이다. 매 프레임 모션을 업데이트 해주어야한다. UpdateMotion(model, dt) 경로가 돌아야 한다.
  4. 모션 그룹:
    • setting: model3.json 정의된 그룹/모션
    • auto: 모델 폴더의 *.motion3.json 자동 스캔(그룹이 비어도 즉시 사용)
    • extra: 외부 *.motion3.json을 UI로 수동 등록
  5. 셰이더 경로: FrameworkShaders/CubismEffect.fx가 실행 경로 기준으로 읽히도록 배치가 필요하다.


Live2D 파이프라인

  • 초기화
    • D3D11: 디바이스/컨텍스트/스왑체인/RTV/DSV/뷰포트
    • Cubism: InitializeConstantSettings(백버퍼세트, device), GenerateShader(device)
  • 데이터 로드
    • model3.json → Core/Framework 생성 → Renderer(D3D11) 준비 → 텍스처 SRV 바인딩(소유 컨테이너로 수명 유지)
  • 업데이트
    • 매 프레임 dt 전달 → UpdateMotion(model, dt) → 파라미터 저장/적용
  • 렌더
    • StartFrame(device, context, vpW, vpH) → SetDefaultRenderState()
    • 필요 시 마스크 오프스크린 생성/사용 → DrawModel() → EndFrame()

1) 초기화 (Engine/D3D11/Cubism)

  • D3D11 디바이스/스왑체인
    • 전체적으로 d3d11에서 많은걸 설정하지 않고 간단하게 구현하는걸 목표로 함
    • DXGI 스왑체인: 2 buffer, DXGI_FORMAT_R8G8B8A8_UNORM, Flip Model으로 세팅
    • Device/Context: D3D_DRIVER_TYPE_HARDWARE, feature level 11_0+
    • ID3D11RenderTargetView/ID3D11DepthStencilView 생성, D3D11_VIEWPORT 설정
    • 공통 상태 객체(권장 기본값)
      • Rasterizer: Cull None, Solid
      • DepthStencil: DepthEnable=false (Live2D 자체는 깊이 필요 없음)
      • Sampler: Linear+Wrap(메인 텍스처), Linear+Clamp(마스크)
  • Cubism Core/Framework
    • Core DLL 로드(런타임 폴더에 Live2DCubismCore.dll)
    • Framework StartUp/Initialize(파일로더/메모리 할당자 등록) — 프로젝트 구현에 맞게 구성
  • Cubism D3D11 렌더러(정적)
    • CubismRenderer_D3D11::InitializeConstantSettings(device)
    • CubismRenderer_D3D11::GenerateShader(device)

2) 데이터 로드 (모델/텍스처/모션)

  • model3.json 로드
    • CubismModelSettingJson으로 파싱해서 moc3, 모델 텍스처 목록, 물리/포즈/모션 그룹 조회
    • CubismModel 생성 및 CubismRenderer_D3D11 인스턴스 생성/바인딩
  • 텍스처 로드/바인딩
    • 모델 텍스처 파일들을 ID3D11ShaderResourceView로 로드
    • 렌더러에 BindTexture(textureIndex, srv)로 전달
    • 반드시 std::vector<ComPtr> 등 “소유 컨테이너”에 SRV를 저장해 수명 보존 (해제 시 viewArray == nullptr 발생)
  • 마스크/오프스크린 준비
    • 렌더러 내부에서 클리핑 매니저가 필요시 마스크용 오프스크린 텍스처를 생성·관리함 (호출자는 별도 생성 불필요)
  • 모션 준비
    • setting 그룹: model3.json 정의된 그룹/파일
    • auto 그룹: 모델 폴더의 *.motion3.json 자동 스캔(그룹이 비어도 사용)
    • extra 그룹: UI에서 외부 *.motion3.json 추가
    • 필요 시 PreloadAllMotions()로 캐시(재생 지연 최소화) -> 최소한의 최적화

3) 업데이트 (dt 기반)

  • dt 계산
    • 프레임 간 시간차(초 단위) 계산해 전달 -> 현재는 ImGui에서 Tick을 가져와서 갱신함
  • 모션 구동
    • 필요 시 StartMotion(group, index) 호출 (우선순위/루프 정책은 프로젝트 규칙대로)
    • 매 프레임 UpdateMotion(model, dt)를 호출 → 경로가 다를경우 파라미터에 누적 적용
  • 물리/포즈/리깅
    • Physics/Hit/Expression/Opacity 등 필요한 시스템 업데이트
    • 최종적으로 model->Update()로 드로어블 변환/메시가 확정됨
  • 파라미터 직접 제어(UI 등)
    • ImGui에서 파라미터 슬라이더 조정 시 현재 파라미터에 가산·덮어쓰기
    • 이름/인덱스 접근: "ParamAngleX" 등 ID 문자열과 [index] 동시 표기

4) 렌더 (프레임 순서)

  • 프레임 시작
    • 앱 측: 백버퍼 RTV/DSV 바인딩, 필요 시 Clear
    • Live2D: CubismRenderer_D3D11::StartFrame(device, context, viewportWidth, viewportHeight)
  • 모델별 드로우
    • renderer->SetMvpMatrix(mvp) 또는 모델 매트릭스 갱신
    • 필요한 색/옵션 설정(불투명도 등)
    • renderer->DrawModel() 호출
    • 내부: 마스크가 필요한 드로어블만 오프스크린에 먼저 렌더 → 본패스에서 샘플링
    • 블렌딩 상태(노말/가산/곱)는 렌더러가 적절히 세팅
  • 프레임 종료
    • CubismRenderer_D3D11::EndFrame(device, context)
    • 스왑체인 Present


모션/그룹 관리(한 화면에서 선택·재생)

  • Group
    • setting: model3.json 정의 사용
    • auto: 모델 폴더의 *.motion3.json 자동 스캔
    • 간혹 자동 스캔이 안되는 json 파일들이 있으니 유저가 직접 등록할 수 있게 만들어 둠
      extra: “Add Motion JSON...”으로 외부 파일 등록(모델 폴더 밖도 가능)
  • Motion Player
    • ImGui의 Group 콤보에서 해당 그룹의 모든 모션 리스트를 표시(파일명/ID)
    • 슬라이더/리스트 선택, 항목별 Play 버튼으로 재생
    • PreloadAllMotions로 캐시(디스크 I/O 히치 감소) -> 조금이나마 최적화 하기 위함


ImGui 구성

  • Live2D: model3.json 로드/상태, “Add Motion JSON...” 버튼
  • Live2D Model Info: Motion Player(그룹/모션 리스트·재생), Parameters/Parts(이름+인덱스 표기/슬라이더 조정)
  • Live2D Textures: 텍스처 미리보기
  • System Info: FPS/GPU/CPU/RAM/VRAM


의존성/경로

  • 이걸 정의하는게 가장 중요합니다. 경로를 잘못 지정하면 많은 시간을 소모할 수 있습니다. GPT나 Cursor나 재미나이나 전부 잘 못잡아줍니다. 유저가 잘 정의해서 집어 넣어야함.

  • Include: $(SolutionDir)third_party/CubismSdkForNative-5-r.4.1/Framework/src, Core/include

  • Lib: $(SolutionDir)third_party/CubismSdkForNative-5-r.4.1/Core/lib/windows/x86_64/143

  • Link: Live2DCubismCore_MTd.lib(Debug) / Live2DCubismCore_MT.lib(Release)

  • DLL: 실행 폴더에 Live2DCubismCore.dll

  • Shader: FrameworkShaders/CubismEffect.fx (런타임 경로 유효성 확보)


profile
게임 프로그래머

0개의 댓글