В этом уроке научимся сокращать число мешей в сцене путем слияния их по одинаковым материалам.

Известно, что, чем больше мешей внутри сцены, тем чаще нашему приложению требуется задействовать дорогостоящие операции по загрузке данных в видеокарту устройства пользователя (так называемые draw calls).
Чтобы уменьшить число вызовов, замедляющих рендер нашей сцены, можно из мешей с одинаковыми материалами сделать один меш.
Реализация алгоритма
Напишем фрагмент кода с помощью библиотеки three.js, который будет обрабатывать меши в нашей сцене (массив meshes) путем объединения мешей с одним и тем же материалом в один.
Что мы делаем:
Составляем массив мешей нашего объекта, сгруппированных по материалам.
Для каждой группы создаем новый меш, полученный путем объединения геометрий всех мешей данной группы.
В сцене заменяем первый меш из группы только что созданным мешем, а остальные меши группы удаляем.
Повторяем действия для остальных групп.
const meshesByMaterial = []; for (let i = 0; i < meshes.length; i++) { const mesh = meshes[i]; const findIndex = meshesByMaterial .findIndex(item => item .find(itemMesh => itemMesh.material === mesh.material) !== undefined); if (findIndex === -1) { meshesByMaterial.push([mesh]); } else { meshesByMaterial[findIndex].push(mesh); } } for (let i = 0; i < meshesByMaterial.length; i++) { const meshesCur = meshesByMaterial[i]; if (meshesCur.length < 2) { continue; } meshesMerge(meshesCur); }
Рассмотрим функцию соединения мешей между собой (результат объединения будет в первом меше):
meshesMerge(meshes) { const meshFirst = meshes[0]; const geometries = meshes.map((mesh, index) => { const geometry = mesh.geometry.clone(); mesh.updateMatrixWorld(); geometry.applyMatrix4(mesh.matrixWorld); return geometry; }); const mergeGeometry = geometriesMerge(geometries); if (mergeGeometry === null) { return null; } mergeGeometry.applyMatrix4(meshFirst.matrixWorld.clone().invert()); meshFirst.geometry = mergeGeometry; for (let i = 1; i < meshes.length; i++) { meshes[i].removeFromParent(); } return meshFirst; }
На что стоит обратить внимание:
При подготовке списка геометрий для их последующего слияния важно произвести операцию клонирования.
Функция geometriesMerge – стандартная утилита внутри пакета three.js.
У результирующей геометрии необходимо скорректировать мировую матрицу исходя из положения итогового меша.
Заключение
Если в сцене много 3D объектов, в которых материалов намного меньше числа мешей, то такой способ может существенно ускорить отклик интерфейса на действия пользователя.
Пример применения алгоритма можно посмотреть в данном кейсе[ссылка удалена модератором].
