Як поводитися з матеріалами в системі Entity / Component


13

Моя реалізація E / C є базовою, де Суб'єкти - це лише ідентифікатори, Компоненти - це дані, а Системи діють на Дані. Зараз у мене проблеми з матеріалами об'єктів та рендерінгом взагалі. Для простих objetcs у мене ModelComponent, прив’язаний до a RenderSystem, ModelComponentє ідентифікатор вершинного буфера, який використовує система візуалізації. Простий 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)але реалізація залежить від кожного класу, і MaterialComponentвін матиме вказівник на об'єкт MaterialData.

Я не впевнений, якому підходу я б віддав перевагу, але жоден з них не торкається теми декількох пропусків або інших складних методів візуалізації.

Будь-яка ідея, як це досягти?

Відповіді:


26

Матеріали є графічною концепцією та належать до вашого рендерінгу. Відображувач є занадто низьким рівнем архітектури, щоб бути побудованим на основі системи сутності. Системи сутності повинні бути для ігрових об'єктів вищого рівня. Не все повинно бути складовим, а насправді це взагалі погана ідея намагатися змусити все в єдиній парадигмі. Це створює рішення, що має найменший загальний знаменник.

Отже, я б радив скористатися іншим підходом:

  • Матеріал - це просто інший тип у вашому рендері.
  • Ваш рендер має тип, який представляє "річ, яку потрібно намалювати на екран". Часто їх називають "екземплярами візуалізації" або "рендереблями" або навіть "моделями". Цей тип має посилання на матеріал, який він буде використовувати під час малювання, і надає загальнодоступний API, щоб дозволити споживачеві рендерінга встановити цей матеріал на все, що бажається.

Це, по суті, просить вас взяти його ModelComponentта перейменувати його Model, усунувши залежність від шару сутності / компонентів і таким чином перемістивши його на нижній шар абстракції, поряд з рештою рендерінга.

Потім ви робите це:

  • У тому ж шарі абстракції, що і у інших ваших компонентів, у вас є якийсь "аспектний компонент", який представляє візуальну презентацію сутності. Цей компонент просто містить посилання на деякий переказ (як описано вище), який, в свою чергу, містить посилання на матеріал. Компонент може надавати API для викриття рендерингу (таким чином, дозволяючи клієнтам маніпулювати ним), або він може обернути API відтворюваного для контролю експозиції. Це залежить від вас.

Це вирішує проблему взаємозалежності компонентів, з якою ви стикаєтесь, маючи моделі та матеріали, які є обома компонентами; суб'єкт господарювання повинен мати або аспект, або ні, і цей аспект повинен мати можливість кодувати все, що стосується представлення суб'єкта, включаючи матеріал.

Це також надає вам можливість використовувати інші підходи до матеріального об'єкта, який важче зробити з цим об'єктом як компонентом через відсутність паритету з рештою абстракції системи візуалізації.

Ваша проблема щодо отримання більш складних ефектів та декількох пропусків - це проблема, яку можна вирішити насамперед у матеріалі, виставивши функції запиту та встановивши названі константи шейдерів, що піддаються файлу шейдерів матеріалу. Це особливо актуально, якщо ви використовуєте файли ефектів (у D3D), які підтримують кілька проходів тощо. Навіть якщо ви не використовуєте файли ефектів, ви можете розкрити ідею про кілька проходів з матеріалу, кожен з яких має різні шейдери, і дозволити API матеріалу надати маніпулятори для цього. Інтеграцію в API візуалізації найімовірніше було б простіше і зрозуміліше, оскільки матеріал зараз знаходиться на одному рівні абстракції.


1
Дякую за вашу відповідь, ця проблема мучила мене досить довгий час, але створити візуалізацію без обмежень E / C набагато простіше.
Люк Б.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.