Ускоряем рендер сцены в three.js путем объединения мешей в один

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

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

Пример блока на сайте с 3D моделью
Пример блока на сайте с 3D моделью

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

Пример применения алгоритма можно посмотреть в данном кейсе[ссылка удалена модератором].

Источник: https://habr.com/ru/articles/747200/


Интересные статьи

Интересные статьи

Об оптимизации компиляции TypeScript написано немало статей, но про один способ я не слышал и обнаружил его довольно случайно.Некоторые библиотеки предоставляют много возможностей, из которых в вашем ...
Наверняка хотя бы раз в жизни вы или ваши знакомые в поисках приятного досуга на вечер обращались к Яндексу или Гуглу с запросами вроде “кино онлайн бесплатно” или “смотреть сериалы 2021”. Если так, н...
Первая и вторая части повествовали об интернете нулевых. Теперь мы переходим к десятым: времени всё более всеобщей интернетизации и всё большей массовости мемов. Если ещё в конце нулевых мемы из инт...
Важный дисклеймер Перед началом хочу позволить себе небольшой, но важный дисклеймер. Я не стараюсь вам продать этот cпособ как панацею. Я лишь хочу рассказать вам ещё один способ представлять дан...
Оглавление 1. Терминология 2. Стиль, вёрстка и форма зависят друг от друга? 3. Текст — это не отдельные символы 3.1. Наложения текста 3.2. Стиль может изменить лигатуру 4. Эмодзи ...