I also have no idea how to make different textures for different faces, I made several unsuccessful attempts, and if anyone has any ideas, please suggest them.
let existingChunks = {};
const CHUNK_SIZE = 100; // Размер чанка
const MAX_HEIGHT = 2; // Максимальная высота для генерации чанков
// Измените этот массив на свои биомы
const biomes = [
{
vertices: [[-11.140454, -1.0, 6.045034], [-5.874499, -1.000002, -25.147928], ...],
verticalTexture: "https://i.postimg.cc/Pq7xgZY0/wallpaper.jpg",
topHorizontalTexture: "https://i.postimg.cc/y83ChCs2/image.png",
bottomHorizontalTexture: "https://i.postimg.cc/wvStLGvz/image.jpg"
},
{
vertices: [[-7.000378, 0.999999, -4.244266], [-6.353668, 0.999999, -5.322138], ...],
faces: [[0, 2, 25], [25, 2, 1], ...],
verticalTexture: "https://i.postimg.cc/Pq7xgZY0/wallpaper.jpg",
topHorizontalTexture: "https://i.postimg.cc/y83ChCs2/image.png",
bottomHorizontalTexture: "https://i.postimg.cc/wvStLGvz/image.jpg"
}
];
// Функция для создания коридора
function createCorridor(chunkId, x, y, z, scene) {
const biome = biomes[Math.floor(Math.random() * biomes.length)]; // Случайный выбор биома
return createMeshFromArrays(biome.vertices, biome.faces, scene, chunkId, x, y, z, biome);
}
// Функция для создания сцены в Babylon.js
async function createScene() {
const engine = new BABYLON.Engine(canvas, true);
const scene = new BABYLON.Scene(engine);
const camera = new BABYLON.FreeCamera("FreeCam", new BABYLON.Vector3(0, 10, -10), scene);
camera.setTarget(BABYLON.Vector3.Zero());
camera.attachControl(canvas, true);
new BABYLON.HemisphericLight("Hemispheric Light", new BABYLON.Vector3(1, 1, 0), scene).intensity = 0.7;
scene.registerBeforeRender(() => {
GenerateChunks(camera.position, scene);
});
engine.runRenderLoop(() => {
scene.render();
});
return scene;
}
// Функция для генерации чанков коридоров
function GenerateChunks(position, scene) {
const chunkX = Math.floor(position.x / CHUNK_SIZE);
const chunkZ = Math.floor(position.z / CHUNK_SIZE);
const chunkY = Math.floor(position.y / CHUNK_SIZE); // Новая ось Y
for (let x = chunkX - 2; x <= chunkX + 2; x++) {
for (let z = chunkZ - 2; z <= chunkZ + 2; z++) {
for (let y = chunkY - MAX_HEIGHT; y <= chunkY + MAX_HEIGHT; y++) { // Генерация по Y
const chunkId = `${x},${y},${z}`; // Обновленный идентификатор чанка
if (!existingChunks[chunkId]) {
createCorridor(chunkId, x, y * CHUNK_SIZE, z, scene); // Обновленный вызов
existingChunks[chunkId] = true; // Сохраняем существующий чанк
}
}
}
}
}
// Обновленная функция createMeshFromArrays для работы с коридорами
function createMeshFromArrays(vertices, faces, scene, chunkId, x, y, z, biome) {
const positions = [];
const indices = [];
const uvs = [];
vertices.forEach(vertex => {
positions.push(vertex[0] + x * CHUNK_SIZE, vertex[1] + y, vertex[2] + z * CHUNK_SIZE); // Учитываем ось Y
});
let faceCount = 0;
faces.forEach(face => {
const startIndex = faceCount * 3; // Каждая грань содержит 3 индекса
indices.push(face[0], face[1], face[2]); // Индексы вершин
// Обратный порядок
indices.push(face[2], face[1], face[0]);
faceCount++;
});
const mesh = new BABYLON.Mesh(chunkId, scene);
const vertexData = new BABYLON.VertexData();
vertexData.positions = positions;
vertexData.indices = indices;
// Установка UV-кординат
const uv = [0, 0, 1, 0, 1, 1, 0, 1];
vertexData.uvs = new Array(indices.length).fill(0).map((_, i) => uv[i % 4]); // Повторяем UV для каждой грани
vertexData.applyToMesh(mesh);
// Создание материалов
const verticalMaterial = new BABYLON.StandardMaterial(`verticalMaterial_${chunkId}`, scene);
verticalMaterial.diffuseTexture = new BABYLON.Texture(biome.verticalTexture, scene);
const topMaterial = new BABYLON.StandardMaterial(`topMaterial_${chunkId}`, scene);
topMaterial.diffuseTexture = new BABYLON.Texture(biome.topHorizontalTexture, scene);
const bottomMaterial = new BABYLON.StandardMaterial(`bottomMaterial_${chunkId}`, scene);
bottomMaterial.diffuseTexture = new BABYLON.Texture(biome.bottomHorizontalTexture, scene);
// Создаем подмеши для каждой грани
let subMeshCount = faces.length; // Количество граней
for (let i = 0; i < subMeshCount; i++) {
const startIndex = i * 6; // Каждый подмеш содержит 2 треугольника (6 индексов)
const endIndex = startIndex + 6;
const subMesh = new BABYLON.SubMesh(i, 0, positions.length / 3, startIndex, endIndex, mesh);
// Применяем правильный материал к каждой грани
if (i === 0) { // Условие для верхней грани
subMesh.materialIndex = topMaterial.id;
} else if (i === 1) { // Условие для нижней грани
subMesh.materialIndex = bottomMaterial.id;
} else {
subMesh.materialIndex = verticalMaterial.id; // Для остальных вертикальных граней
}
}
return mesh;
}
// Запуск инициализации сцены
createScene();
Example 2
const CHUNK_SIZE = 100; // Размер чанка
const MAX_HEIGHT = 2; // Максимальная высота для генерации чанков
// Измените этот массив на свои биомы
const biomes = [
{
vertices: [[-11.140454, -1.0, 6.045034], [-5.874499, -1.000002, -25.147928], ...],
faces: [[10, 0, 35], [1, 3, 2], ...],
verticalTexture: "https://i.postimg.cc/Pq7xgZY0/wallpaper.jpg",
topHorizontalTexture: "https://i.postimg.cc/y83ChCs2/image.png",
bottomHorizontalTexture: "https://i.postimg.cc/wvStLGvz/image.jpg"
},
{
vertices: [[-7.000378, 0.999999, -4.244266], [-6.353668, 0.999999, -5.322138], ...],
faces: [[0, 2, 25], [25, 2, 1], ...],
verticalTexture: "https://i.postimg.cc/Pq7xgZY0/wallpaper.jpg",
topHorizontalTexture: "https://i.postimg.cc/y83ChCs2/image.png",
bottomHorizontalTexture: "https://i.postimg.cc/wvStLGvz/image.jpg"
}
];
// Функция для создания коридора
function createCorridor(chunkId, x, y, z, scene) {
const biome = biomes[Math.floor(Math.random() * biomes.length)]; // Случайный выбор биома
return createMeshFromArrays(biome.vertices, biome.faces, scene, chunkId, x, y, z, biome);
}
// Функция для создания сцены в Babylon.js
async function createScene() {
const engine = new BABYLON.Engine(canvas, true);
const scene = new BABYLON.Scene(engine);
const camera = new BABYLON.FreeCamera("FreeCam", new BABYLON.Vector3(0, 10, -10), scene);
camera.setTarget(BABYLON.Vector3.Zero());
camera.attachControl(canvas, true);
new BABYLON.HemisphericLight("Hemispheric Light", new BABYLON.Vector3(1, 1, 0), scene).intensity = 0.7;
scene.registerBeforeRender(() => {
GenerateChunks(camera.position, scene);
});
engine.runRenderLoop(() => {
scene.render();
});
return scene;
}
// Функция для генерации чанков коридоров
function GenerateChunks(position, scene) {
const chunkX = Math.floor(position.x / CHUNK_SIZE);
const chunkZ = Math.floor(position.z / CHUNK_SIZE);
const chunkY = Math.floor(position.y / CHUNK_SIZE); // Новая ось Y
for (let x = chunkX - 2; x <= chunkX + 2; x++) {
for (let z = chunkZ - 2; z <= chunkZ + 2; z++) {
for (let y = chunkY - MAX_HEIGHT; y <= chunkY + MAX_HEIGHT; y++) { // Генерация по Y
const chunkId = `${x},${y},${z}`; // Обновленный идентификатор чанка
if (!existingChunks[chunkId]) {
createCorridor(chunkId, x, y * CHUNK_SIZE, z, scene); // Обновленный вызов
existingChunks[chunkId] = true; // Сохраняем существующий чанк
}
}
}
}
}
// Обновленная функция createMeshFromArrays для работы с коридорами
function createMeshFromArrays(vertices, faces, scene, chunkId, x, y, z, biome) {
const positions = [];
const indices = [];
const uvs = [];
vertices.forEach(vertex => {
positions.push(vertex[0] + x * CHUNK_SIZE, vertex[1] + y, vertex[2] + z * CHUNK_SIZE); // Учитываем ось Y
});
faces.forEach(face => {
indices.push(face[0], face[1], face[2]); // Индексы вершин
indices.push(face[2], face[1], face[0]); // Обратный порядок
});
// Установка UV-кординат
const uv = [0, 0, 1, 0, 1, 1, 0, 1];
uvs.push(...uv);
const mesh = new BABYLON.Mesh(chunkId, scene);
const vertexData = new BABYLON.VertexData();
vertexData.positions = positions;
vertexData.indices = indices;
vertexData.uvs = uvs;
vertexData.applyToMesh(mesh);
const material = new BABYLON.StandardMaterial(`material_${chunkId}`, scene);
// Установка текстур в зависимости от расположения
if (y > 0) { // Для верхних горизонтальных границ
material.diffuseTexture = new BABYLON.Texture(biome.topHorizontalTexture, scene);
} else if (y < 0) { // Для нижних горизонтальных границ
material.diffuseTexture = new BABYLON.Texture(biome.bottomHorizontalTexture, scene);
} else { // Для вертикальных границ
material.diffuseTexture = new BABYLON.Texture(biome.verticalTexture, scene);
}
material.backFaceCulling = false;
mesh.material = material;
return mesh;
}
// Запуск инициализации сцены
createScene();
But I’ll come back later and figure something out.