Объединение геометрии / сетки без потери преимуществ

11

В three.js мы можем просто объединить геометрию, чтобы ограничить количество вызовов отрисовки и тем самым повысить производительность. В простом тесте с одним материалом я мог нарисовать 50 000 кубов + тени при 60 кадрах в секунду на моем графическом процессоре GTX660. Без объединения геометрии 5.000 кубов уже вызвали проблему.

Интересно, как сохранить преимущества рендеринга каждой кубической сетки отдельно? Например, как выбрать сетку куба, когда все объединено в одну геометрию? По умолчанию это невозможно, конечно.

Есть ли какой-нибудь общий метод для этой проблемы? В конце концов, у меня есть все объекты без сетки, даже после слияния. Таким образом, должен быть какой-то способ использовать их для выбора?

Что я хочу сделать в двух словах

  • SimCity как игра для учебных целей
  • Каждый дом - это кубовая сетка
  • Хотите сделать 50 000 домов и иметь возможность добавлять и удалять дома
  • Выбор дома с помощью курсора мыши (выбор) должен быть возможен
user990827
источник
Я не уверен, полезно ли это вам, но я упоминаю это для полноты. Simplygon имеет модель ценообразования на основе роялти для независимых разработчиков и может выполнять слияние и разбиение сетки во время разработки.
steeveeet

Ответы:

11

Ладно, я понял. После объединения всей геометрии у меня все еще есть отдельные сетки в массиве. Так что я могу просто использовать эти сетки для радиопередачи, даже если они даже не отображаются. Мне понадобилось время, чтобы понять это.

введите описание изображения здесь

Для выбора я использую эту реализацию octree: http://threejs.org/examples/#webgl_octree_raycasting

Это снижает количество тестов пересечений за обновление с 50.000 до ~ 500. Без октри fps сильно уменьшится.

Оранжевый корпус комплектации, который вы видите, на самом деле представляет собой теперь визуализированную сетку (+1 колл-колл) с измененным материалом и измененным размером.

введите описание изображения здесь

Поэтому я думаю, что следующий шаг - это реализовать какое-то разбиение карты. То есть разбить объединенную геометрию на несколько частей. Причина этого заключается в том, что объединенная геометрия имеет большое количество вершин. Это означает, что если я переместу карту на 99% за пределы экрана, графическая карта все равно должна обработать все вершины, потому что геометрия все еще видна, по крайней мере, 1% от нее. Так что, если он разбит, должны быть отображены только кусочки.

user990827
источник
Большое вам спасибо за это понимание. Я тоже пытался найти способ сделать это, и я думаю, что ваше решение здесь самое превосходное! Короткий вопрос: для вашего локального списка объектов (т.е. Three.Object3D), какие свойства требуются для работы rayCaster.intersectObjects ()?
AlvinfromDiaspar
Очень красиво сделано.
ClassicThunder,
У меня похожая проблема, но как-то не получается заставить работать радиовещание с r70. Делали ли вы что-то особенное при создании и объединении блоков? Я использую следующий код ( pastebin.com/PStaAF3P ) для создания и объединения узлов, но, может быть, чего-то не хватает, чтобы заставить работать raycaster?
мая
Быстрый вопрос: я делаю что-то очень похожее на вас (3D-карта, основанная на данных geoJSON). С вашим методом, когда вы поворачиваете камеру, вам нужно также вращать уже существующие строительные сетки? Или вы просто добавляете отдельные рамки на сцену, но не визуализируете их?
Спенсер
@ Спенсер Нет, не нужно вращаться. Я сохраняю отдельные блоки в глобальном массиве и добавляю только объединенную геометрию к сцене. Затем вы можете выполнить лучевую передачу с объектом в глобальном массиве, потому что raycaster зависит от матрицы камеры и положения каждого блока. Скорее всего, не лучшим образом, это было просто доказательство концепции для меня. Больше не делаю three.js на данный момент.
user990827
1

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

Если все объекты имеют одинаковую геометрию, вы можете использовать рендеринг экземпляров. Один поток определяет геометрию, а другой определяет свойства для каждого экземпляра (например, преобразование). Для отбрасывания усеченного контура вам необходимо построить поток экземпляров каждого кадра на основе теста видимости. Если у вас есть большое количество объектов, вы, возможно, захотите поместить эти объекты в свободное дерево или что-то еще, чтобы ускорить отбраковку.

JarkkoL
источник
0

Я не уверен в деталях three.js, но в целом OpenGL приходят на ум два возможных снижения производительности:

  1. Вы рассматривали инстансинг? Вам также понадобится только один вызов на ничью и меньше использовать VRAM.
  2. Вы серьезно взглянули на алгоритм выбора? Например, если ваши кубы имеют ограничивающие объемы в списке, а не в дереве, это объясняет разницу в этой величине.
bogglez
источник
0

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

HaoCS
источник