2016-11-21 4 views
-1

Мне интересно, как, например, графические (/ игровые) двигатели выполняют свою работу с гетерогенными данными лота, в то время как настроенный простой цикл рендеринга превращается в кошмар, когда у вас небольшие изменения.Проблемы с рендерингом/обновлением OpenGL

Пример:

Во-первых, скажем, у нас есть некоторые блоки в нашей сцене.

  1. Graphic-Engine: создавать кубы и перемещать их
  2. Customized: создать шаблон куба для вершин, нормалей и т.д. скопировать и перевести их в положение и скопировать, например, в vbo. Один вызов glDraw * выполняет эту работу.

Во-вторых, какая-то странная логика. Мы хотим, чтобы блок 1, 4, 7, ... вращался по оси x, 2, 5, 8, ... по оси y и 3, 6, 9 по оси z с линейной скоростью вращения камеры расстояние.

  1. Graphic-Engine: манипулируя матрицу объекта, и он работает
  2. Customized: (я думаю) на объект glDraw * коллировать с изменением модели-матрицы униформы не является хорошей идеей, так что матрица перевода должна быть чем-то вроде атрибут? Я должен обновить их каждый кадр.

В-третьих, блок должен исчезнуть, если расстояние до камеры ниже, чем любое константное значение Q.

  1. Графический Двигатель: если (object.distance (камера) < Q) scene.drop (объект);
  2. Подгоняно: (я думаю) наш vbo недействителен, и мы должны его воссоздать?

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

Другой пример: Что касается мира вокселов (например, Minecraft), где мы рисуем только видимую поверхность, и мы можем бросить бомбу и уничтожить многие вокселы. Если данные о мировом представлении находятся в одном огромном буфере, у нас есть только один glDraw * -call, но каждый раз он должен воссоздавать буфер. Если есть меньшие куски, у нас есть много glDraw * -calls, а также приходится манипулировать буферами, которые меньше.

Так что это приятно отправить, скажем, 10 МБ данных обновления буфера вместо 2 gl * -колла с 1 МБ? Сколько обновлений в порядке? Должен ли цикл рендеринга обрабатывать ленивые обновления?

Я ищу руководство, какое приложение с 60fps должно иметь возможность обновлять/рисовать на кадр, чтобы получить представление о том, что возможно. Для моих тестов каждая попытка оптимизации является еще одним узким местом.

И я не хочу, чтобы те учебники, которые гласят: эй, есть новый классный вызов gl * Instance, который является супер-быстрым, buuuuut вы должны проверить, поддерживает ли ваш gpu его. Ну, я также скорее рассмотрю эту оптимизацию, а не значимую реализацию.

Есть ли у вас какие-либо идеи, источники, лучшие практики или эмпирическое правило, как лучшая игра для рендеринга/обновления?

Мои вопросы все почти то же самое:

  • Сколько обновлений для каждого кадра в порядке на современном оборудовании?
  • Могу ли я lazy-load данные иметь его после нескольких кадров, но без замораживания моего приложения
  • Должен ли я делать небольшие обновления и профиль моей петли, если есть несколько микросекунд, оставшихся до следующего рендеринга?
  • Возможно, мне нужно реализовать профилировщик в режиме реального времени, который со временем ощущает ощущение, насколько дорогими обновлениями и может определить количество обновлений для каждого кадра?

спасибо.

+0

Ну, ваш настраиваемый цикл рендеринга может делать точно так же, как и общий движок графического движка. Но поскольку он настроен, он может быть фактически оптимизирован для вашего конкретного случая, например, не хранить граф сцены в явной структуре данных и оценивать матрицы и т. Д.вместо того, чтобы бросать их в память. – ybungalobill

+1

Хотя я нахожу вопрос очень интересным, я не знаю, с чего начать с ответа, поскольку для этого потребуется довольно обширная длина. Не могли бы вы разбить его на вопрос, на который можно ответить с помощью реальных усилий? – BDL

+0

@BDL основное внимание уделяется тому, как обрабатывать обновления без замораживания вашего приложения. Вместо того, чтобы проверять это, было бы неплохо, если бы кто-то мог сказать: «на сегодняшнем оборудовании не должно быть проблем с худшим случаем обновления вершин 50k». Или, может быть, он говорит: «20 gl * Buffer update calls с не более 100 МБ в порядке». Как бы настроить сцену с вершинами лота, которые могут меняться каждые несколько секунд? Есть ли ленивая стратегия загрузки в opengl, что я могу сказать: пожалуйста, обновите 50k вершин, но мне не нужно быть для следующего кадра (не замораживать). – Aitch

ответ

1

Непонятно, как любой из ваших вопросов относится к вашим «графическим двигателям» и «настроенным» примерам. Все обновления, которые вы делаете с помощью «графических движков», в конце концов переводятся на эти вызовы OpenGL.

Вкратце:

Сколько обновлений для каждого кадра в порядке на современном оборудовании?

Сегодняшняя пропускная способность PCIe огромна (может достигать 30 ГБ/с). Однако, чтобы использовать его полностью, вам необходимо сократить количество транзакций посредством консолидации вызовов OpenGL. Точное количество обновлений полностью зависит от оборудования, драйверов и способа их использования, а графическое оборудование разнообразно.

Это тот ответ, который вы не хотели слышать, но, к сожалению, вы должны смотреть правде в глаза: чтобы сократить количество вызовов OpenGL, вам нужно использовать API новой версии. Например. вместо того, чтобы устанавливать каждую единицу индивидуально, вам лучше представить кучу из них через однородные объекты буфера шейдеров. Вместо того, чтобы представлять каждый MVP каждой модели отдельно, лучше использовать инстансный рендеринг. И так далее.

Еще более радикальным подходом было бы перейти к более низкоуровневому (и более новому) API, то есть к Vulkan, который направлен на решение именно этой проблемы: стоимость отправки работы на GPU.

Могу ли я данные отложенной загрузки, чтобы он после того, как несколько кадров, но без замораживания моего приложения

Да, вы можете загрузить буфер объекты асинхронен. См. Buffer Object Streaming.

Должен ли я выполнять небольшие обновления и профиль моей петли, если осталось несколько микросекунд до следующего рендеринга?

Возможно, мне нужно внедрить профилировщик в режиме реального времени, который со временем ощущает ощущение, насколько дорогими обновлениями и может определить количество обновлений для каждого кадра?

Вам не нужны никакие из них, если вы делаете это асинхронно.

Смежные вопросы