Есть ли эффективный способ превысить GL_MAX_VIEWPORTS?

В настоящее время я реализую алгоритм оценки позы, предложенный в Ойкономидис и др., 2011 г., который включает в себя рендеринг сетки в N различных гипотетических позах (N, вероятно, будет около 64). В разделе 2.5 предлагается ускорить вычисления с помощью создания экземпляров для одновременной генерации нескольких визуализаций (после чего они сокращают каждую визуализацию до одного числа на графическом процессоре), и, судя по их описанию, похоже, что они нашли способ производить N визуализации одновременно.

На этапе настройки моей реализации я использую массив окон просмотра OpenGL для определения GL_MAX_VIEWPORTS окон просмотра. Затем на этапе рендеринга я передаю массив матриц GL_MAX_VIEWPORTS модели-позы в массив mat4uniform в памяти графического процессора (меня интересует только оценка положения и ориентации) и использую gl_InvocationID в моем шейдере геометрии, чтобы выбрать подходящую матрицу поз и viewport для каждого полигона меша.

GL_MAX_VIEWPORTS на моей машине 16 (у меня GeForce GTX Titan), поэтому этот метод позволит мне рендерить до 16 гипотез одновременно на GPU. Это может оказаться достаточно быстрым, но мне, тем не менее, любопытно следующее:

Есть ли обходной путь для ограничения GL_MAX_VIEWPORTS, который, вероятно, будет быстрее, чем вызов моей функции рендеринга ceil(double(N)/GL_MX_VIEWPORTS) раз?

Я только пару недель назад начал изучать шейдерный подход к OpenGL, так что еще не знаю всех хитростей. Первоначально я думал заменить использование встроенной поддержки видового экрана комбинацией:

  1. геометрический шейдер, добавляющий h*gl_InvocationID к y координатам вершин после проекции перспективы (где h — желаемая высота области просмотра) и передающий gl_InvocationID на фрагментный шейдер; а также
  2. фрагментный шейдер, который discard создает фрагменты с y координатами, которые удовлетворяют y<gl_InvocationID*h || y>=(gl_InvocationID+1)*h.

Но я отложил дальнейшее изучение этой идеи из-за страха, что ветвление и discard будут очень вредны для производительности.

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

Я понимаю, что единственный окончательный ответ на мой вопрос — реализовать обходной путь и измерить его производительность, но в настоящее время это малоприоритетное любопытство, и я не нашел ответов нигде, поэтому я надеялся, что более опытный пользователь GLSL может быть в состоянии предложить свою экономящую время мудрость.

Действительно ли ваш видовые экраны (то есть параметры glViewport) меняется с «просмотра» на «просмотр»? Судя по беглому описанию вашего алгоритма, я так не думаю.

Nicol Bolas 09.04.2019 20:30
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
4
1
193
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

При беглом взгляде на статью мне кажется, что фактический окно просмотра не меняется. То есть вы по-прежнему выполняете рендеринг с той же шириной/высотой и положениями X/Y с тем же диапазоном глубины.

Что вы хотите, так это изменить, на какой изображение вы выполняете рендеринг. Для чего предназначен gl_Layer; чтобы изменить, какой слой в многоуровневом массиве изображений, прикрепленных к буферу кадра, в который вы выполняете рендеринг.

Так что просто установите gl_ViewportIndex на 0 для всех вершин. Или, точнее, не устанавливайте его вообще.

Количество Вызовы инстансов GS не является ограничением имеют; это ваш выбор. Вызовы GS могут записывать несколько примитивов, каждый на свой уровень. Таким образом, вы можете сделать так, чтобы каждый экземпляр записывал, например, 4 примитива, каждый в 4 отдельных слоя.

Единственными ограничениями должны быть количество слоев, которые вы можете использовать (регулируется GL_MAX_ARRAY_TEXTURE_LAYERS и GL_MAX_FRAMEBUFFER_LAYERS, оба из которых должны быть не менее 2048), а также количество примитивов и данных вершин, которые может сгенерировать один вызов GS (которое равно довольно сложный).

Спасибо за это предложение! Потребовалось некоторое время, чтобы выяснить, как выполнить рендеринг в глубине прикрепления массива текстур, а затем прочитать результат, чтобы убедиться, что он работает (мне пришлось переключиться с использования glReadPixels на glGetTextureImage). К сожалению, предел далеко не так высок, как GL_MAX_ARRAY_TEXTURE_LAYERS, так как вы можете создавать только MAX_GEOMETRY_SHADER_INVOCATIONS экземпляров геометрического шейдера, а на моей машине их 32. Это все же лучше, чем ограничение GL_MAX_VIEWPORTS, поэтому я принял ваш ответ.

Ose 10.04.2019 19:13

Раздел 3.2.3 технического отчета, на который я ссылался в своем ответе, называется «отсечение нескольких окон просмотра», поэтому кажется довольно очевидным, что они отображались в разных окнах просмотра параллельно. Неясно, использовали ли они встроенную поддержку области просмотра или смоделировали ее с помощью discard, как и вопрос о том, действительно ли они смогли визуализировать все свои гипотезы одновременно.

Ose 10.04.2019 19:26

@Ose: вызовы GS не являются ограничением; см. мой ответ.

Nicol Bolas 10.04.2019 19:29

О, хорошо, я напишу несколько примитивов! Еще раз спасибо за помощь!

Ose 10.04.2019 19:32

Я столкнулся с другим ограничением: количество доступных униформ (khronos.org/opengl/wiki/Uniform_(GLSL)#Implementation_limit‌​s). Мне нужен массив Nmat4 (по одному на каждую гипотезу) и дополнительный mat4 для проекционной матрицы, но моя машина не позволит мне определить более 128 mat4 униформ. Этот вопрос предлагает обойти это с помощью объектов юниформ-буфера: stackoverflow.com/q/20647207/1292784 . Но мне все равно больше 127 гипотез не понадобится.

Ose 11.04.2019 15:32

Другие вопросы по теме