XRManet / Engine

2 stars 0 forks source link

Scene Graph #3

Open sixzone11 opened 3 years ago

sixzone11 commented 3 years ago

적당한 씬 그래프 만들어주세요.

오브젝트 기준의 cpp 수준에서 다루는 내용일 것 같습니다.

sixzone11 commented 3 years ago

@kidsnow 제가 이해한게 맞으면 XRSceneNode 들을 등록하는 주체는 Renderer 객체가 아니라 SceneGraph 객체인데 맞나요? 아마 대략 아래같은 코드 구성이 될 것 같은데요.

scene->Update(dt);
scene->Render(&sceneGraph); // Render() 라고만 쓰면 Renderer::Render()랑 의미가 헷갈리니까, RenderSceneGraph()나 BuildSceneGraph() 등으로 고쳐써야할 것 같아요.

RenderDescription renderDescription; // 아직 없지만 이런 구조체 파라미터가 필요할 것 같네요
renderDescription._sceneGraph = sceneGraph; // 위에서 만든 씬 그래프
renderDescription._deviceFeatures = ...;
renderDescription._renderOptions = ...;
renderer->Update(&renderDescription);
renderer->Render();

이런 방향이 맞으면, SceneGraph에 등록된 ActorNode 등은 Renderer::Update() 에서 RHI 레이어에서 쓸 수 있는 최적 형태인 XRObjectGroup으로 변환할 생각이에요.

sixzone11 commented 3 years ago

아, 어차피 Renderer가 SceneRenderer 라는 관점이어서 SceneGraph를 내장하고 있다고 보는 개념이었나 싶네요.

그런 거라면 지금 분리시키는 방향으로 고치는 게 좋을 것 같아요. SceneGraph만 따로 순회하면서 로깅할 수 있으면 지금 개발할 때도 그렇고, 나중에 렌더러 제대로 도는지 확인할 때 검증할 때도 좋을 것 같아요.

sixzone11 commented 2 years ago

Scene::Update()는 SceneGraph의 노드들을 순회하여 RenderingDataDescription을 구축하는 역할을 한다. Renderer는 RenderingDataDescription를 입력으로 취하여, 각 렌더러가 저마다 수용 가능한 Description들에 대해 memory layout을 구축하도록 한다.

각 node의 데이터에 대한 업데이트는 layout을 통해서 이뤄져야 한다. 이를 위해선 특정 노드가 description 상에 어떻게 표현되는지, 그래서 렌더러가 이 description을 memory layout으로 전환한 결과 상의 memory range(offset, size)가 어떻게 결정되었는지 알 수 있어야 한다.

memory range를 매번 계산해내는 비용을 없애기 위해, 각 노드는 자신을 수용한 description을 따르는 memory layout이 파생되어 메모리 블록이 생성될 때마다 그 메모리 블록 상에서의 range를 memoize한다.

위 필요 사항들을 정리하여, 다음과 같은 관계 구축 단계를 거치도록 한다.

Scene::Update()

  1. SceneGraph - Rendering Data Decription 구축
  2. Renderer - Memory Layout 마련
  3. SceneGraph - 각 Node 별 Memory Range 등록

Renderer::Update() n개 node에 대한 data update가 발생하면, GPU memory bandwidth가 고려된 최적의 update range를 결정하여 copy command를 수행한다.