Заказ экземпляров в WebGL

Я рисую много прямоугольников, поэтому использую для этого WebGL2RenderingContext.drawArraysInstanced(). Я также использую множество буферов для управления шейдерами в каждом экземпляре (содержащими такие данные, как положение, цвета, состояние и т. д.). Теперь я хочу повлиять на порядок, в котором отрисовываются мои экземпляры (например, вывести на передний план экземпляр, на который нажал пользователь), и я ищу что-то вроде INSTANCE_ARRAY_BUFFER, что-то похожее на ELEMENT_ARRAY_BUFFER, но для экземпляров вместо вершины. Что-то, что позволило бы мне сказать «рисовать экземпляры в следующем порядке: 3,1,2,0,…». Есть ли какой-либо API, который позволил бы мне контролировать порядок отрисовываемых экземпляров, не изменяя порядок элементов всех буферов данных?

Основываясь на моих исследованиях, я подозреваю, что ответ будет «нет», но, возможно, я пропустил какой-то скрытый API WebGL. Кроме того, в качестве бонуса вопрос — было ли что-то подобное введено, возможно, в последних версиях OpenGL или WebGPU?

@httpdigest спасибо за ссылку. Я использую квадроциклы для отображения элементов пользовательского интерфейса и часто меняю атрибуты для каждого экземпляра. Судя по вашей ссылке, я вижу 3 арки: (1) То, что у меня есть сейчас (экземпляры рендеринга). (2) Нет экземпляров, проиндексировано гео, но требуется установка атрибута 4 раза для каждого «экземпляра». (3) Нет экземпляров, нет индексированного гео, но требуется установка атрибута 6 раз для каждого «экземпляра». Арка 3 могла бы решить мою проблему, так как тогда мы могли бы использовать ELEMENT_ARRAY_BUFFER для сортировки, но тогда установка атрибутов была бы очень медленной. Конечно, мне нужно их скамейке. Тем не менее, я не был бы рад замедлить настройку attr.

Wojciech Danilo 19.12.2020 22:07

С GL_DEPTH_TEST вам не нужно заботиться о порядке рендеринга. Для каждого прямоугольника у вас должен быть параметр глубины. Затем вы можете манипулировать этим параметром, чтобы вывести прямоугольник на передний план.

Hihikomori 19.12.2020 22:28

@МатвейВислоух, который будет работать с фигурами, созданными только с помощью геометрии, но мы визуализируем фигуры с помощью шейдеров на основе SDF, применяемых к четырехъядерным спрайтам. Такие шейдеры позволяют нам иметь сверхгладкие кривые и плавное масштабирование всего. В таком случае использование буфера глубины нарушит наше сглаживание.

Wojciech Danilo 19.12.2020 23:53
Стоит ли изучать 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 называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
407
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Ваш единственный актуальный вопрос

Есть ли какой-либо API, который позволил бы мне контролировать порядок отрисовываемых экземпляров, не изменяя порядок элементов всех буферов данных?

Да, поместите свои данные в текстуры, передайте массив идентификаторов в буфере

Несколько примеров, не только четверные здесь и здесь

Я понятия не имею, насколько быстрее или медленнее это будет. Моя интуиция подсказывает, что это будет медленнее, но я не проверял.

Мне было бы странно, что единственное, что вы оптимизируете, это порядок прорисовки, и что вам не нужно позиционировать все четырехугольники и изменять их UV. Если вам нужно расположить все четырехугольники и изменить их UV, то просто сначала запишите их в правильном порядке.

Другие комментарии на основе комментариев

  • Являются ли экземпляры лучшим способом рисовать много квадов?

    Я думаю, что вердикт здесь не так однозначен. 10 лет назад по моему опыту создание экземпляров было на 30% медленнее, чем просто создание данных для всех квадроциклов. Мои тесты показывают, что это уже не так, по крайней мере, ни на одном из моих графических процессоров, ни в WebGL.

  • Является ли запись 4 или 6 вершин в буферы на квадрат хорошим решением?

    Для пользовательского интерфейса обычно просто записывают все данные в буферы в каждом кадре. См. почти все библиотеки ImGUI

Спасибо за удивительный ответ, как всегда! Что касается позиционирования и UV-развертки — я вычисляю их в вершинном шейдере, но наша структура графического интерфейса изменчива, и поэтому мы изменяем только подмножество компонентов при взаимодействии с пользователем. Ваше решение с текстурами потрясающее. Однако, если я правильно понимаю, это потребует от меня перераспределения новой текстуры со всеми параметрами (и удаления старой) при каждом создании нового компонента, верно? (поскольку текстура будет содержать значения для всех «экземпляров»). (Конечно, я могу перераспределить немного больше для оптимизации)

Wojciech Danilo 20.12.2020 02:55

Я недостаточно знаю о том, что вы делаете, но вы можете выделить текстуру большего размера, чем вам нужно, и управлять пространством внутри (аналогично тому, как std::vector в C++ выделяет больше памяти, фактически используемой массивом)

gman 20.12.2020 03:09

О, я не знал об этом! Я был уверен, что распределение текстур просто слепо занимает место в памяти GPU. Удивительно знать это, спасибо!

Wojciech Danilo 20.12.2020 05:27

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