rework/rendering #36

Merged
PeaAshMeter merged 5 commits from rework/rendering into main 2026-04-23 19:52:52 +03:00
Owner

Переделали мы рендеринг ПОЛНОСТЬЮ.

Теперь у нас:

  1. крутая архитектура с Render Queue
  2. за пост-обработку спрайтов отвечает один шейдер
  3. свет стал лучше (динамический и глобальный тоже)
  4. оптимизация

Дальше экспертное мнение

Проведя ревью архитектуры в ветке rework/rendering, я могу сказать, что проект перешел из стадии «прототипа на коленке» в стадию профессионального графического движка.

Вот мой детальный разбор и экспертное мнение по ключевым аспектам:

1. Система очередей (Render Queue) — Оценка: 5/5

Что это дает: Это фундамент. Теперь мы полностью контролируем порядок отрисовки.

  • Плюс: Мы избавились от "Z-fighting" (когда персонажи перекрывают друг друга некорректно) за счет сортировки по Y внутри очереди.
  • Производительность: Мы радикально сократили количество переключений состояний (State Changes). Раньше каждый объект вызывал setCanvas, что является одной из самых «дорогих» операций для GPU. Теперь это происходит один раз за слой.

2. Uber-Shader для спрайтов — Оценка: 4+/5

Что это дает: Весь визуал персонажа теперь в одной математической формуле.

  • Плюс: Интеграция освещения и обводки (outline) в один шейдер исключает необходимость второго прохода отрисовки (Multipass rendering). Это экономит видеопамять и циклы GPU.
  • Замечание: Сейчас мы передаем 8 источников света для каждого спрайта индивидуально (shader:send). При сотнях персонажей это может создать небольшую нагрузку на шину данных между CPU и GPU.
  • Совет на будущее: Если персонажей станет очень много, можно рассмотреть передачу данных о свете через Uniform Buffer или Texture Buffer, но для тактической игры текущего масштаба это избыточно.

3. Low-Res конвейер — Оценка: 5/5

Что это дает: Огромный прирост FPS на слабых устройствах.

  • Плюс: Тени и свет рендерятся в 50% разрешении. Поскольку свет — это мягкие градиенты, человеческий глаз практически не видит разницы в четкости, но GPU обрабатывает в 4 раза меньше пикселей (0.5 * 0.5 = 0.25 от площади).
  • Результат: Блюр теней теперь работает мгновенно.

4. Оптимизация TileGrid (SpriteBatch) — Оценка: 5/5

Что это дает: Отрисовка пола больше не является узким местом.

  • Плюс: Переход от тысяч вызовов draw к одному пакету SpriteBatch — это классический и самый эффективный способ оптимизации в 2D. Теперь размер карты (30x30 или 100x100) почти не влияет на производительность.

Что можно улучшить в будущем (Backlog):

  1. Кэширование данных света:
    Сейчас в SpriteBehavior:draw мы каждый кадр ищем и сортируем источники света. Это O(N \cdot \text{lights}). Если персонаж и источники света не двигались, этот расчет можно кэшировать и обновлять только по необходимости.

  2. Типы слоев (World vs Screen):
    Сейчас слой OVERLAY привязан к камере. Если вам понадобится UI-элемент, который «приклеен» к экрану, но должен быть частью очереди рендеринга, стоит добавить флаг isWorldSpace для слоев, чтобы Render знал, нужно ли делать camera:attach().

  3. Инстансинг персонажей:
    Если в игре появятся армии одинаковых монстров (например, 50 кабанов), можно будет объединить их в один SpriteBatch аналогично тайлам, но это потребует более сложной логики передачи параметров шейдера.

Итоговое мнение:
Текущая архитектура — очень здравая и масштабируемая. Она позволяет легко добавлять новые визуальные эффекты (туман войны, частицы, пост-эффекты типа Bloom), не ломая общую структуру. Система готова к наполнению контентом.

Предлагаю принять (merge) изменения из ветки rework/rendering в основную ветку.

# Переделали мы рендеринг ПОЛНОСТЬЮ. Теперь у нас: 1) крутая архитектура с Render Queue 2) за пост-обработку спрайтов отвечает один шейдер 3) свет стал лучше (динамический и глобальный тоже) 4) оптимизация # Дальше экспертное мнение Проведя ревью архитектуры в ветке `rework/rendering`, я могу сказать, что проект перешел из стадии «прототипа на коленке» в стадию профессионального графического движка. Вот мой детальный разбор и экспертное мнение по ключевым аспектам: ### 1. Система очередей (Render Queue) — Оценка: 5/5 **Что это дает:** Это фундамент. Теперь мы полностью контролируем порядок отрисовки. * **Плюс:** Мы избавились от "Z-fighting" (когда персонажи перекрывают друг друга некорректно) за счет сортировки по Y внутри очереди. * **Производительность:** Мы радикально сократили количество переключений состояний (State Changes). Раньше каждый объект вызывал `setCanvas`, что является одной из самых «дорогих» операций для GPU. Теперь это происходит один раз за слой. ### 2. Uber-Shader для спрайтов — Оценка: 4+/5 **Что это дает:** Весь визуал персонажа теперь в одной математической формуле. * **Плюс:** Интеграция освещения и обводки (outline) в один шейдер исключает необходимость второго прохода отрисовки (Multipass rendering). Это экономит видеопамять и циклы GPU. * **Замечание:** Сейчас мы передаем 8 источников света для *каждого* спрайта индивидуально (`shader:send`). При сотнях персонажей это может создать небольшую нагрузку на шину данных между CPU и GPU. * **Совет на будущее:** Если персонажей станет очень много, можно рассмотреть передачу данных о свете через `Uniform Buffer` или `Texture Buffer`, но для тактической игры текущего масштаба это избыточно. ### 3. Low-Res конвейер — Оценка: 5/5 **Что это дает:** Огромный прирост FPS на слабых устройствах. * **Плюс:** Тени и свет рендерятся в 50% разрешении. Поскольку свет — это мягкие градиенты, человеческий глаз практически не видит разницы в четкости, но GPU обрабатывает в 4 раза меньше пикселей (0.5 * 0.5 = 0.25 от площади). * **Результат:** Блюр теней теперь работает мгновенно. ### 4. Оптимизация TileGrid (SpriteBatch) — Оценка: 5/5 **Что это дает:** Отрисовка пола больше не является узким местом. * **Плюс:** Переход от тысяч вызовов `draw` к одному пакету `SpriteBatch` — это классический и самый эффективный способ оптимизации в 2D. Теперь размер карты (30x30 или 100x100) почти не влияет на производительность. ### Что можно улучшить в будущем (Backlog): 1. **Кэширование данных света:** Сейчас в `SpriteBehavior:draw` мы каждый кадр ищем и сортируем источники света. Это $O(N \cdot \text{lights})$. Если персонаж и источники света не двигались, этот расчет можно кэшировать и обновлять только по необходимости. 2. **Типы слоев (World vs Screen):** Сейчас слой `OVERLAY` привязан к камере. Если вам понадобится UI-элемент, который «приклеен» к экрану, но должен быть частью очереди рендеринга, стоит добавить флаг `isWorldSpace` для слоев, чтобы `Render` знал, нужно ли делать `camera:attach()`. 3. **Инстансинг персонажей:** Если в игре появятся армии одинаковых монстров (например, 50 кабанов), можно будет объединить их в один `SpriteBatch` аналогично тайлам, но это потребует более сложной логики передачи параметров шейдера. **Итоговое мнение:** Текущая архитектура — очень здравая и масштабируемая. Она позволяет легко добавлять новые визуальные эффекты (туман войны, частицы, пост-эффекты типа Bloom), не ломая общую структуру. Система готова к наполнению контентом. **Предлагаю принять (merge) изменения из ветки `rework/rendering` в основную ветку.**
PeaAshMeter added the
Refactoring
label 2026-04-23 19:52:31 +03:00
PeaAshMeter added 5 commits 2026-04-23 19:52:32 +03:00
PeaAshMeter added this to the Глобальный проект улучшения графики project 2026-04-23 19:52:32 +03:00
PeaAshMeter merged commit 41a906fe6a into main 2026-04-23 19:52:52 +03:00
PeaAshMeter moved this to Сделано in Глобальный проект улучшения графики on 2026-04-23 19:58:29 +03:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: ArcMutex/heroes-of-nerevelon#36
No description provided.