Процедурная генерация ландшафта в Three.js основана на создании геометрии, вершины которой определяются значениями шума. Наиболее часто используется Perlin Noise или Simplex Noise, обеспечивающие плавные, естественные переходы высот.
Для начала требуется плоскость, которая станет основой ландшафта:
const width = 200;
const height = 200;
const widthSegments = 199;
const heightSegments = 199;
const geometry = new THREE.PlaneGeometry(width, height, widthSegments, heightSegments);
geometry.rotateX(-Math.PI / 2); // поворот для горизонтального расположения
width и height определяют размеры
ландшафта.widthSegments и heightSegments —
количество сегментов, которые задают детализацию. Чем больше сегментов,
тем более плавный и детализированный рельеф.Для генерации высот применяется шум, который возвращает значения от 0
до 1. Для Perlin Noise можно использовать библиотеку simplex-noise:
import SimplexNoise from 'simplex-noise';
const simplex = new SimplexNoise();
const vertices = geometry.attributes.position.array;
for (let i = 0; i < vertices.length; i += 3) {
const x = vertices[i];
const z = vertices[i + 2];
const y = simplex.noise2D(x * 0.05, z * 0.05) * 10; // масштабирование координат и высоты
vertices[i + 1] = y;
}
geometry.computeVertexNormals();
x * 0.05) управляет
частотой шума: меньше значение — плавный рельеф, больше — более мелкие
детали.* 10) контролирует
максимальную амплитуду гор и впадин.computeVertexNormals() для корректного расчета
освещения.Выбор материала влияет на визуальное восприятие рельефа. Для базового
варианта используют MeshStandardMaterial с текстурами и
картой нормалей:
const material = new THREE.MeshStandardMaterial({
color: 0x556655,
roughness: 0.8,
metalness: 0.2,
});
Для имитации разнообразия можно использовать градиент высот:
const colors = [];
for (let i = 0; i < vertices.length; i += 3) {
const y = vertices[i + 1];
let color = new THREE.Color();
if (y < 2) color.set(0x223322); // низины — темно-зеленые
else if (y < 6) color.set(0x55aa55); // средние участки — зеленые
else color.set(0xaaaaaa); // вершины — серые
colors.push(color.r, color.g, color.b);
}
geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3));
material.vertexColors = true;
InstancedMesh.Для реалистичного отображения рельефа необходимы направленные источники света и корректные тени:
const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(50, 100, 50);
directionalLight.castShadow = true;
scene.add(directionalLight);
mesh.castShadow = true;
mesh.receiveShadow = true;
shadow.mapSize и
shadow.camera для снижения нагрузки.Процедурный ландшафт легко анимировать, изменяя параметры шума во времени:
const time = performance.now() * 0.0001;
for (let i = 0; i < vertices.length; i += 3) {
const x = vertices[i];
const z = vertices[i + 2];
vertices[i + 1] = simplex.noise3D(x * 0.05, z * 0.05, time) * 10;
}
geometry.attributes.position.needsUpdate = true;
geometry.computeVertexNormals();
noise3D) позволяет плавно
анимировать рельеф.needsUpdate = true обязательно для обновления позиции
вершин в WebGL.InstancedMesh и процедурной расстановки объектов на основе
высоты и наклона.Процедурная генерация ландшафта в Three.js сочетает математику шума, гибкую работу с геометрией и освещением, обеспечивая детализированные и динамичные 3D-сцены. Такой подход позволяет создавать разнообразные миры без использования готовых моделей и текстур.