Дисплейсмент и геометрические деформации

Babylon.js предоставляет широкий набор инструментов для работы с геометрией, включая дисплейсмент (displacement) и различные виды геометрических деформаций. Эти методы позволяют создавать сложные поверхности и динамически изменять формы объектов в 3D-пространстве без необходимости вручную моделировать каждую деталь.


Основы дисплейсмента

Дисплейсмент — это способ изменения формы поверхности на основе карты высот (height map). В Babylon.js дисплейсмент реализован через материалы и специальные карты, которые смещают вершины меша вдоль нормалей.

Создание дисплейсмента:

const ground = BABYLON.MeshBuilder.CreateGround("ground", {width:10, height:10, subdivisions: 100}, scene);

const material = new BABYLON.StandardMaterial("groundMat", scene);
material.diffuseTexture = new BABYLON.Texture("textures/ground_diffuse.jpg", scene);
material.bumpTexture = new BABYLON.Texture("textures/ground_bump.jpg", scene);
material.displacementTexture = new BABYLON.Texture("textures/ground_height.png", scene);
material.displacementStrength = 2;

ground.material = material;

Ключевые моменты:

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

Геометрические деформации с помощью MorphTarget

MorphTarget позволяет анимировать и деформировать меши без изменения исходной геометрии. Каждая MorphTarget хранит смещение вершин относительно базового меша, и с помощью веса (influence) можно плавно смешивать исходную и целевую форму.

Пример использования MorphTarget:

const sphere = BABYLON.MeshBuilder.CreateSphere("sphere", {diameter: 2, segments: 32}, scene);

const morphTarget = new BABYLON.MorphTarget("morph", {positions: sphere.getVerticesData(BABYLON.VertexBuffer.PositionKind).map(v => v * 1.2)});
sphere.morphTargetManager = new BABYLON.MorphTargetManager();
sphere.morphTargetManager.addTarget(morphTarget);

scene.registerBeforeRender(() => {
    morphTarget.influence = (Math.sin(performance.now() * 0.001) + 1) / 2;
});

Особенности MorphTarget:

  • Позволяет анимировать лица меша, изменять формы персонажей или объектов.
  • Можно использовать несколько MorphTarget одновременно для сложных комбинаций деформаций.
  • MorphTarget не влияет на физику объекта, если не пересчитывать коллайдеры.

Использование VertexData для кастомных деформаций

Для более сложных форм и процедурной геометрии Babylon.js позволяет работать напрямую с VertexData. Этот подход даёт полный контроль над вершинами, нормалями, UV и индексами меша.

Пример: волнообразная деформация поверхности

const ground = BABYLON.MeshBuilder.CreateGround("waveGround", {width:10, height:10, subdivisions:50}, scene);
const vertexData = BABYLON.VertexData.ExtractFromMesh(ground);

const positions = vertexData.positions;
for (let i = 0; i < positions.length; i += 3) {
    positions[i + 1] += Math.sin(positions[i] * 2 + performance.now() * 0.002) * 0.5;
}

vertexData.applyToMesh(ground, true);

Преимущества работы с VertexData:

  • Абсолютная свобода деформации: можно изменять любые координаты вершин и нормалей.
  • Возможность создания процедурных форм без текстурных карт.
  • Поддержка анимации в реальном времени через обновление VertexData перед рендером.

Динамическое обновление геометрии

Babylon.js позволяет динамически изменять форму мешей в ходе выполнения сцены. Важные аспекты:

  1. Subdivisions и плотность вершин — низкая детализация меша ограничивает качество деформаций.
  2. Обновление нормалей — после изменения позиций вершин необходимо пересчитывать нормали для корректного освещения:
ground.updateVerticesData(BABYLON.VertexBuffer.NormalKind, BABYLON.VertexData.ComputeNormals(positions, vertexData.indices));
  1. Использование GPU — для сложных и больших мешей предпочтительно применять шейдерные методы (DisplacementMapShader) вместо CPU-декомпозиций вершин.

Комбинирование методов

На практике часто используют дисплейсмент + MorphTarget + VertexData. Пример: базовая карта высот задаёт рельеф, MorphTarget добавляет анимацию, VertexData обеспечивает произвольные динамические эффекты.

Пример комбинирования:

  • Создать сетку с высокой детализацией.
  • Применить displacementTexture для рельефа.
  • Добавить MorphTarget для анимации формы.
  • Использовать VertexData для процедурной волны или колебаний.

Такой подход позволяет создавать реалистичные и динамичные сцены с минимальными затратами на ручное моделирование.