В этом уроке научимся сокращать число мешей в сцене путем слияния их по одинаковым материалам.
Известно, что, чем больше мешей внутри сцены, тем чаще нашему приложению требуется задействовать дорогостоящие операции по загрузке данных в видеокарту устройства пользователя (так называемые 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 объектов, в которых материалов намного меньше числа мешей, то такой способ может существенно ускорить отклик интерфейса на действия пользователя.
Пример применения алгоритма можно посмотреть в данном кейсе[ссылка удалена модератором].