Russian Qt Forum
Ноябрь 22, 2024, 01:15
Добро пожаловать,
Гость
. Пожалуйста,
войдите
или
зарегистрируйтесь
.
Вам не пришло
письмо с кодом активации?
1 час
1 день
1 неделя
1 месяц
Навсегда
Войти
Начало
Форум
WIKI (Вики)
FAQ
Помощь
Поиск
Войти
Регистрация
Russian Qt Forum
>
Forum
>
Qt
>
OpenGL
>
Picking [решено]
Страниц: [
1
]
Вниз
« предыдущая тема
следующая тема »
Печать
Автор
Тема: Picking [решено] (Прочитано 10778 раз)
Igors
Джедай : наставник для всех
Offline
Сообщений: 11445
Picking [решено]
«
:
Июль 21, 2020, 15:29 »
Добрый день
Интересуют все 3 вида выборки: объектов, вертексов и фейсов. Старый код (что я когда-то писал "по Липчаку") конечно полностью развалился и отсыпает ошибки с core profile 3.3. Быстро убедился что пытаться как-то его залатать не удастся. Неск лет назад что-то доделывал и спрашивал на пресловутом gamedev, ничего нового, советовали ту же технику "кодирования цветами".
Идея там проста и привлекательна - давайте нарисуем каждый объект (или вертекс, фейс) "своим" цветом и отрендерим а текстуру. Потом читаем пыксели - и получим что выбрали. Однако все почему-то оговариваются что, мол, "этот подход/метод не лучший". Оно и понятно, соскочили 3D -> 2D, возможности не те.
Ну то ладно, "дефицит концептуальности" я как-нибудь переживу. Но у меня рендерится с AA (samples), а значит цвета пыкселей смешиваются и "декодирование" загнется. Как мне переключаться между контекстами с AA и без - ума не приложу. И данных рисования прорва, реально ли вообще использовать их в др контексте?
А если не "цветом" то как? Сейчас гуглю чтобы представить осмыслить общую картину - но пока грустно. Что посоветуете ?
Спасибо
«
Последнее редактирование: Сентябрь 17, 2020, 07:21 от Igors
»
Записан
ssoft
Программист
Offline
Сообщений: 584
Re: Picking
«
Ответ #1 :
Июль 21, 2020, 16:35 »
Цитата: Igors от Июль 21, 2020, 15:29
Интересуют все 3 вида выборки: объектов, вертексов и фейсов.
Разницы нет никакой, что выбирать. Каждый выбираемый элемент нужно пометить своим идентификатором.
Цитата: Igors от Июль 21, 2020, 15:29
Идея там проста и привлекательна - давайте нарисуем каждый объект (или вертекс, фейс) "своим" цветом и отрендерим а текстуру. Потом читаем пыксели - и получим что выбрали. Однако все почему-то оговариваются что, мол, "этот подход/метод не лучший". Оно и понятно, соскочили 3D -> 2D, возможности не те.
Очень эффективный метод - только отключаем текстурирование и любое смешивание во фрагментном шейдере. Формируем кадр при наличии изменений по запросу. Достаточно дешево, так как можно все прорисовать практически за один проход. Можно еще ограничить область отображения квадратиком 3х3 под координатами мыши (тогда рисуем всегда). Но метод имеет существенные ограничения - осуществляется выбор только верхнего элемента.
Другой способ - формировать буфер выбора, подобно старому способу ранних версий OpenGL glSelectBuffer, но самостоятельно! glSelectBuffer ооооччееень медленная штука. Формируйте изображение в квадратик 3х3 под координатами мыши о заполняйте его во фрагментном шейдере. Получите перечень всех объектов с глубиной отображения.
Еще способ - формируйте пространственное дерево. Находите ячейку пространства - получаете список потенциальных элементов, ищите пересечение луча с объектами.
Записан
ssoft
Программист
Offline
Сообщений: 584
Re: Picking
«
Ответ #2 :
Июль 21, 2020, 17:29 »
Цитата: Igors от Июль 21, 2020, 15:29
Но у меня рендерится с AA (samples), а значит цвета пыкселей смешиваются и "декодирование" загнется. Как мне переключаться между контекстами с AA и без - ума не приложу. И данных рисования прорва, реально ли вообще использовать их в др контексте?
А зачем в другом контексте? Можно рисовать в этом же, только с другими установками и другим наборов шейдерных программ. Ну а если все-таки хотите в другом контексте, то используйте shared context.
Записан
Igors
Джедай : наставник для всех
Offline
Сообщений: 11445
Re: Picking
«
Ответ #3 :
Июль 22, 2020, 11:25 »
Цитата: ssoft от Июль 21, 2020, 17:29
А зачем в другом контексте? Можно рисовать в этом же, только с другими установками и другим наборов шейдерных программ. Ну а если все-таки хотите в другом контексте, то используйте shared context.
Упрощенно: sampling (в установках формата/контекста) - это (возможно максимальное) число суб-пикселей которые будут считаться для каждого пикселя. Цвет итогового пикселя будет получен осреднением этих суб-пикселей (самплов), отсюда и проблема - "чистый" (заданный) цвет не получить.
Цитата: ssoft от Июль 21, 2020, 16:35
Разницы нет никакой, что выбирать. Каждый выбираемый элемент нужно пометить своим идентификатором.
Думаю реализуемо, но мне это не кажется "таким уж простым". Для объекта годится униформ, а вот для фейса или вертекса - не вижу др возможности кроме как прицепить геометрический шейдер и там использовать gl_PrimitiveIDIn
Цитата: ssoft от Июль 21, 2020, 16:35
Но метод имеет существенные ограничения - осуществляется выбор только верхнего элемента.
Это как раз устраивает, но аналогичные проблемы есть. Напр рисуются не только сами объекты но и ихние "манипуляторы" (ручки за которые юзер может дергать), при выборке они имеют высший приоритет. Придется городить неск проходов. В общем, как обычно, реализация "простой" идеи оказывается, мягко говоря, "достаточно хлопотливой".
Цитата: ssoft от Июль 21, 2020, 16:35
Другой способ - формировать буфер выбора, подобно старому способу ранних версий OpenGL glSelectBuffer, но самостоятельно! glSelectBuffer ооооччееень медленная штука. Формируйте изображение в квадратик 3х3 под координатами мыши о заполняйте его во фрагментном шейдере. Получите перечень всех объектов с глубиной отображения.
Здесь не понял. Фрагментный шейдер считает цвет, ну я могу считать только в заданном квадрате, и что с того? Не знаю др способов сохранения посчитанного кроме текстуры (в рамках 3.3)
Цитата: ssoft от Июль 21, 2020, 16:35
Еще способ - формируйте пространственное дерево. Находите ячейку пространства - получаете список потенциальных элементов, ищите пересечение луча с объектами.
Это удовольствие дорогое (особенно учитывая перестройку BVH при любой активности юзера). И выбор вертексов это не решает.
Вообще как-то кисло. Задача стопудово типовая, такие должны решаться "открыл "книгу", прочитал, реализовал". Собсно так и было до этой вакханалии с шейдерами. А тут кроме этого детского лепета с цветами ничего не видно. Ладно, не буду спешить с выводами, погуглю еще. Спасибо за участие
Записан
ssoft
Программист
Offline
Сообщений: 584
Re: Picking
«
Ответ #4 :
Июль 22, 2020, 19:15 »
Цитата: Igors от Июль 22, 2020, 11:25
Цитата: ssoft от Июль 21, 2020, 16:35
Другой способ - формировать буфер выбора, подобно старому способу ранних версий OpenGL glSelectBuffer, но самостоятельно! glSelectBuffer ооооччееень медленная штука. Формируйте изображение в квадратик 3х3 под координатами мыши о заполняйте его во фрагментном шейдере. Получите перечень всех объектов с глубиной отображения.
Здесь не понял. Фрагментный шейдер считает цвет, ну я могу считать только в заданном квадрате, и что с того? Не знаю др способов сохранения посчитанного кроме текстуры (в рамках 3.3)
Мы использовали GL_ARB_shader_storage_buffer_object (OpenGL 4.3) и хранили структуру
Код
C++ (Qt)
struct
PixelData
{
uint32_t id
;
float
depth
;
}
;
и использовали атомарный счетчик (
https://www.khronos.org/opengl/wiki/Atomic_Counter
) для определения позиции записи.
Но идея такая. Складывать такую структуру в 1D Texture. Рисовать всего 1 пиксель, чтобы обеспечить неконкурентный доступ к текстуре. Использовать 4 байта под id и следующие 4 под depth.
Искать в 1D текстуре ближайший ноль на четной позиции и записывать туда пару {id,depth}. В результате на выходе 1D текстура с последовательностью пар. Расскажите, если получится).
Записан
Igors
Джедай : наставник для всех
Offline
Сообщений: 11445
Re: Picking
«
Ответ #5 :
Июль 28, 2020, 07:39 »
Цитата: ssoft от Июль 22, 2020, 19:15
Мы использовали GL_ARB_shader_storage_buffer_object (OpenGL 4.3) и хранили структуру
Видел (боковым зрением) ф-ции синхронизации для четверки, стало быть и запись там уже есть. Но требования "core 3.3", делать "и так и сяк" - себе дороже. А в 3.3 похоже никаких возможностей что-то "вернуть" из шейдера нема
Ну ладно, буду делать на CPU, пусть медленновато, но не катастрофа. Правда и здесь один из случаев = выбрать только "видимые" (не перекрытые отрисованным) примитивы. Думал отрендерить Z-buffer, но это опять проблемы (точности) пикселей и растеризации, решения не имеют. А рейтрасер в приложении есть (bullet) но тащить/заряжать его - типа "корову на баню".
Пока наметил такой план: при смене view в отдельной нитке строить структуры поиска ну и при клике выбирать (возможно с OpenMP). Что за структуры: думаю перевести все вертексы в экран и по паре сортированных x/y массивов (одна для вертексов, др для фейсов). Хотелось бы конечно использовать мощности GPU (да и вообще более стандартного, канонического решения) - но где ж взять если нету
Записан
ssoft
Программист
Offline
Сообщений: 584
Re: Picking
«
Ответ #6 :
Июль 28, 2020, 17:09 »
И все же мне не понятны следующие моменты:
- что мешает использовать вариант 1 с отображением вертексов, ребер, граней, объектов своим идентификационным цветом в framebuffer без AA и читать пиксели?
- что мешает использовать вариант 2 с отображением вертексов, ребер, граней, объектов своим идентификационным цветом в framebuffer для формирования последовательности PixelData?
И тот и другой способ требуют максимум OpenGL core 3.0.
Записан
Igors
Джедай : наставник для всех
Offline
Сообщений: 11445
Re: Picking
«
Ответ #7 :
Июль 28, 2020, 19:35 »
Цитата: ssoft от Июль 28, 2020, 17:09
- что мешает использовать вариант 1 с отображением вертексов, ребер, граней, объектов своим идентификационным цветом в framebuffer без AA и читать пиксели?
Ну вот меш "плотненький", т.е. один пиксель покрывает 2 и более примитивов. И все - приплыли, решений нет. Можно отрендерить в текстуру побольше, ну это так, заплатка до след раза.
Цитата: ssoft от Июль 28, 2020, 17:09
- что мешает использовать вариант 2 с отображением вертексов, ребер, граней, объектов своим идентификационным цветом в framebuffer для формирования последовательности PixelData?
И тот и другой способ требуют максимум OpenGL core 3.0.
Хорошо бы, но как я ее сформирую если могу только рендерить в текстуру (причем пиксель не тот что "я хочу" а только тот "что дали") ?
Edit: и еще (забыл сказать) - да, выбирать "только видимые" нужно, НО выбирать "всех" (под мышей или в рамке) независимо от их перекрытия - тоже нужно. И выходит что "чтение текстуры" недостаточно, все равно нужно городить что-то еще.
«
Последнее редактирование: Июль 29, 2020, 07:10 от Igors
»
Записан
ssoft
Программист
Offline
Сообщений: 584
Re: Picking
«
Ответ #8 :
Июль 29, 2020, 13:38 »
Цитата: Igors от Июль 28, 2020, 19:35
Цитата: ssoft от Июль 28, 2020, 17:09
- что мешает использовать вариант 1 с отображением вертексов, ребер, граней, объектов своим идентификационным цветом в framebuffer без AA и читать пиксели?
Ну вот меш "плотненький", т.е. один пиксель покрывает 2 и более примитивов. И все - приплыли, решений нет. Можно отрендерить в текстуру побольше, ну это так, заплатка до след раза.
Рендерят обычно в текстуру равную по размеру отображаемой области, тогда не важно насколько плотный меш. Кто сверху, того и выбираем.
Цитата: Igors от Июль 28, 2020, 19:35
Хорошо бы, но как я ее сформирую если могу только рендерить в текстуру (причем пиксель не тот что "я хочу" а только тот "что дали") ?
Я попробую реализовать пример в свободное время). Но это будет не скоро.
Записан
Igors
Джедай : наставник для всех
Offline
Сообщений: 11445
Re: Picking
«
Ответ #9 :
Июль 30, 2020, 07:12 »
Цитата: ssoft от Июль 29, 2020, 13:38
Кто сверху, того и выбираем.
Ну так придется ерзать, пояснять юзеру типа "ты в кучу мышей не тыкай, там мож выберется мож нет". См аттач: ожидается что
все
вертексы в кружке браша будут выбраны (и закрашены),
Цитата: Igors от Июль 28, 2020, 19:35
Хорошо бы, но как я ее сформирую если могу только рендерить в текстуру (причем пиксель не тот что "я хочу" а только тот "что дали") ?
А если "попробывать" реализовать Вашу идею с PixelData чуть по-другому:
- цепляем геометрический шейдер и в нем проверяем должен ли примитив быть выбран. Если да, то эмиттим вертекс точно в позиции (пикселе) что соответствует индексу примитива. Это решает все случаи выборки кроме того же злополучного браша (аттач)
Thoughts?
Записан
Igors
Джедай : наставник для всех
Offline
Сообщений: 11445
Re: Picking
«
Ответ #10 :
Июль 31, 2020, 12:02 »
Тут прильнул к матчасти..
Цитата: Igors от Июль 30, 2020, 07:12
- цепляем геометрический шейдер и в нем проверяем должен ли примитив быть выбран. Если да, то эмиттим вертекс точно в позиции (пикселе) что соответствует индексу примитива.
Идея слить все расчеты selection в геометричекий шейдер правильная, но в велосипедных способах вывода нет нужды, для этого давно есть
штатное средство
Записан
Igors
Джедай : наставник для всех
Offline
Сообщений: 11445
Re: Picking
«
Ответ #11 :
Сентябрь 17, 2020, 07:21 »
Как говорят, "может кому пригодится"
- конечно маловероятно. Но отписаться "чем дело кончилось" - хорошая привычка.
В конце-концов все сделал. используются только штатные средства и вся выборка полностью на GPU. Хотя не исключено что есть какие-то подводные камни о которых я не знаю. Как реализовано:
- для picking (выборки) я использую transforn feedback API совместно с геометрическим шейдером. В нем проверяю выбран ли примитив и если да, то записываю его индекс в выходной буфер. Важный момент: я (ошибочно) полагал что OpenGL "не умеет писать" (вывод только в текстуру). Это не так, писать он умел задолго до 3.3. Правда API там весьма задроченое, разобраться трудновато, но тем не менее.
- если нужно выбирать "только видимые" (не перекрытые другими) то дополнительно использую occlusion API, что также было в наличии задолго до 3.3. Правда приходится тюкать по 1 примитиву, ничего другого не нашел, но реализовать просто.
Наблюдаю интересный эффект. OpenGL - популярнейшая технология, "используют миллионы"
(что впрочем совсем не показатель квачества). Ну казалось бы для такой типовой задачи как "тыкать мышей" - уж должны быть накатаные решения! Здесь мы вправе рассчитывать и на open-sources или хотя бы какой-то sample code. Но я ничего такого не нашел, не видно было даже "куда копать". Да, популярное решение есть (кодировать цветом), но оно не устроило.
Т.е. выходит что "популярный уровень" (тонны тьюториалов перепечатывающих друг друга) - вовсе не "так уж хорошо". Мда..
Записан
Страниц: [
1
]
Вверх
Печать
« предыдущая тема
следующая тема »
Перейти в:
Пожалуйста, выберите назначение:
-----------------------------
Qt
-----------------------------
=> Вопросы новичков
=> Уроки и статьи
=> Установка, сборка, отладка, тестирование
=> Общие вопросы
=> Пользовательский интерфейс (GUI)
=> Qt Quick
=> Model-View (MV)
=> Базы данных
=> Работа с сетью
=> Многопоточное программирование, процессы
=> Мультимедиа
=> 2D и 3D графика
=> OpenGL
=> Печать
=> Интернационализация, локализация
=> QSS
=> XML
=> Qt Script, QtWebKit
=> ActiveX
=> Qt Embedded
=> Дополнительные компоненты
=> Кладовая готовых решений
=> Вклад сообщества в Qt
=> Qt-инструментарий
-----------------------------
Программирование
-----------------------------
=> Общий
=> С/C++
=> Python
=> Алгоритмы
=> Базы данных
=> Разработка игр
-----------------------------
Компиляторы и платформы
-----------------------------
=> Linux
=> Windows
=> Mac OS X
=> Компиляторы
===> Visual C++
-----------------------------
Разное
-----------------------------
=> Новости
===> Новости Qt сообщества
===> Новости IT сферы
=> Говорилка
=> Юмор
=> Объявления
Загружается...