В three.js мы можем просто объединить геометрию, чтобы ограничить количество вызовов отрисовки и тем самым повысить производительность. В простом тесте с одним материалом я мог нарисовать 50 000 кубов + тени при 60 кадрах в секунду на моем графическом процессоре GTX660. Без объединения геометрии 5.000 кубов уже вызвали проблему.
Интересно, как сохранить преимущества рендеринга каждой кубической сетки отдельно? Например, как выбрать сетку куба, когда все объединено в одну геометрию? По умолчанию это невозможно, конечно.
Есть ли какой-нибудь общий метод для этой проблемы? В конце концов, у меня есть все объекты без сетки, даже после слияния. Таким образом, должен быть какой-то способ использовать их для выбора?
Что я хочу сделать в двух словах
- SimCity как игра для учебных целей
- Каждый дом - это кубовая сетка
- Хотите сделать 50 000 домов и иметь возможность добавлять и удалять дома
- Выбор дома с помощью курсора мыши (выбор) должен быть возможен
Ответы:
Ладно, я понял. После объединения всей геометрии у меня все еще есть отдельные сетки в массиве. Так что я могу просто использовать эти сетки для радиопередачи, даже если они даже не отображаются. Мне понадобилось время, чтобы понять это.
Для выбора я использую эту реализацию octree: http://threejs.org/examples/#webgl_octree_raycasting
Это снижает количество тестов пересечений за обновление с 50.000 до ~ 500. Без октри fps сильно уменьшится.
Оранжевый корпус комплектации, который вы видите, на самом деле представляет собой теперь визуализированную сетку (+1 колл-колл) с измененным материалом и измененным размером.
Поэтому я думаю, что следующий шаг - это реализовать какое-то разбиение карты. То есть разбить объединенную геометрию на несколько частей. Причина этого заключается в том, что объединенная геометрия имеет большое количество вершин. Это означает, что если я переместу карту на 99% за пределы экрана, графическая карта все равно должна обработать все вершины, потому что геометрия все еще видна, по крайней мере, 1% от нее. Так что, если он разбит, должны быть отображены только кусочки.
источник
Для выбора вы также можете визуализировать идентификаторы для каждого куба для другой цели визуализации и просто проверить, какое значение идентификатора находится у курсора. Преимущество заключается в том, что комплектация идеальна для пикселей и эффективно работает даже для более сложной геометрии.
Если все объекты имеют одинаковую геометрию, вы можете использовать рендеринг экземпляров. Один поток определяет геометрию, а другой определяет свойства для каждого экземпляра (например, преобразование). Для отбрасывания усеченного контура вам необходимо построить поток экземпляров каждого кадра на основе теста видимости. Если у вас есть большое количество объектов, вы, возможно, захотите поместить эти объекты в свободное дерево или что-то еще, чтобы ускорить отбраковку.
источник
Я не уверен в деталях three.js, но в целом OpenGL приходят на ум два возможных снижения производительности:
источник
Другой подход, который вы можете использовать, это встроить некоторый атрибут вершины в вашу геометрию и поместить логику выделения в ваш фрагментный шейдер. Это чрезвычайно полезно, когда вы не хотите иметь две копии данных в памяти, и у вас будет больше контроля над тем, как реализовано выделение.
источник