엔터티 / 구성 요소 시스템에서 재료를 처리하는 방법 “효과”에서 간단한 변수만큼 쉽지 않은 유연성을

내 E / C 구현은 엔터티가 단지 ID이고 구성 요소는 데이터이며 시스템은 데이터에 대해 행동하는 기본입니다. 현재 객체 재질과 렌더링에 문제가 있습니다. 나는이 간단한 objetcs를 들어 ModelComponentA와 묶여 RenderSystem, ModelComponent정점 버퍼 IDS 렌더링이 시스템의 사용이있다. 단순한 MaterialComponent것은 아마도 색이나 거울의 강도 등을 가지 겠지만, 둘 이상의 렌더 패스와 일반적인 “효과”에서 간단한 변수만큼 쉽지 않은 유연성을 원했습니다 MaterialComponent.

이 문제를 해결하기 위해 두 가지 해결책을 찾았습니다.

1-슈퍼 제네릭 소재 구성 요소

이 같은:

struct Material : public Component
{
    ShaderData* shader;
    std::vector<std::pair<std::string, boost::any>> uniforms;
    [...]
};

그리고 렌더링 시스템에서 유니폼을 반복하여 쉐이더에 전달합니다. 나는 이것이 느리지 만 내 목적을 위해 충분히 빠를 것이라고 생각합니다.

2-또 다른 추상화 계층, MaterialData

특정 머티리얼을 랩핑하는 클래스를 가짐에 따라, 특수 머티리얼로 상속 될 수있는 기본 클래스는 비슷 void set_shader_constants(ShaderData* d)하지만 구현은 각 클래스마다 다르며 MaterialComponentMaterialData 객체에 대한 포인터를 갖습니다.

어떤 접근 방식을 선호하는지 잘 모르겠지만 이러한 방법 중 어느 것도 여러 단계의 주제 나 다른 복잡한 렌더링 기술에 영향을 미치지 않습니다.

이것을 달성하는 방법에 대한 아이디어가 있습니까?



답변

머티리얼은 그래픽 개념이며 렌더러에 속합니다. 렌더러가 엔티티 시스템 위에 구축하기에는 너무 낮은 레벨의 아키텍처입니다. 엔터티 시스템은 더 높은 수준의 게임 개체를위한 것이어야합니다. 모든 것이 구성 요소 일 필요는 없으며 실제로는 모든 것을 하나의 패러다임으로 만들려고 시도하는 것은 일반적으로 나쁜 생각입니다. 최소 공통 분모 솔루션을 만듭니다.

결과적으로 다른 접근법을 사용하는 것이 좋습니다.

  • 머티리얼은 렌더러의 또 다른 유형입니다.
  • 렌더러에는 “화면에 그려 질 것”을 나타내는 유형이 있습니다. 이를 “렌더링 인스턴스”또는 “렌더러 블”또는 “모델”이라고하는 경우가 많습니다. 이 유형은 그릴 때 사용할 재질에 대한 참조를 가지고 있으며 렌더러 소비자가 원하는 재질로 해당 재질을 설정할 수 있도록 공용 API를 제공합니다.

이것은 본질적으로 객체 를 가져 와서 ModelComponent이름을 바꾸어 Model엔티티 / 구성 요소 레이어에 대한 종속성을 제거하고 나머지 렌더러와 함께 하위 추상화 계층으로 이동하도록 요구합니다.

그런 다음이 작업을 수행하십시오.

  • 다른 구성 요소와 동일한 추상화 계층에는 엔터티의 시각적 표현을 나타내는 일종의 “종료 구성 요소”가 있습니다. 이 컴포넌트는 머티리얼에 대한 참조를 포함하는 일부 렌더러 블에 대한 참조 만 포함합니다 (위에서 설명). 컴포넌트는 렌더러 블을 노출하기위한 API를 제공하여 (클라이언트가 조작 할 수 있도록) 노출을 제어하기 위해 렌더러 블의 API를 랩핑 할 수 있습니다. 그것은 당신에게 달려 있습니다.

이것은 모델과 재료가 모두 구성 요소가되도록하여 구성 요소 상호 의존성 문제를 해결합니다. 실체는 하나의 양상을 가져야하거나 그렇지 않아야하며, 그 양상은 물질을 포함하여 엔티티의 표현에 관한 모든 것을 인코딩 할 수 있어야한다.

또한 나머지 렌더 시스템 추상화와의 패리티가 없기 때문에 구성 요소로 해당 오브젝트와 관련하기 어려운 재질 오브젝트로 다른 접근 방식을 취할 수있는 유연성도 제공합니다.

더 복잡한 효과와 다중 패스를 허용하는 문제는 머티리얼의 셰이더 파일에 의해 노출 된 명명 된 쉐이더 상수를 쿼리하고 설정하는 함수를 노출함으로써 주로 머티리얼에서 해결할 수있는 것입니다. 다중 패스 등을 지원하는 효과 파일 (D3D)을 사용하는 경우 특히 그렇습니다. 효과 파일을 사용하지 않더라도 각각 고유 한 셰이더가있는 머티리얼의 여러 패스 아이디어를 노출하고 머티리얼 API가 머니퓰레이터를 제공 할 수 있습니다. 머티리얼의 추상화 수준이 같기 때문에 렌더링 API에 통합하는 것이 더 쉽고 깔끔합니다.