Procedural content generation (PCG) allows developers to create dynamic 3D worlds using algorithms. With Three.js, you can generate entire cities, ecosystems, and landscapes programmatically. This article explores some key techniques for advanced procedural content generation.
1. Procedural City Generation
Using algorithms like L-systems, you can create city layouts with roads and buildings dynamically.
- Road Generation:
- L-systems use simple rules to define how roads branch and grow. For example:
const rules = { "F": "F+F-F-F+F" };
let result = "F";
for (let i = 0; i < 4; i++) result = result.replace(/F/g, rules["F"]);
// Use the result to define roads.
- Dynamic Buildings:
- Add buildings with random heights for a varied skyline.
for (let i = 0; i < 10; i++) {
const height = Math.random() * 50 + 10;
const building = new THREE.BoxGeometry(10, height, 10);
const material = new THREE.MeshStandardMaterial({ color: 0xcccccc });
scene.add(new THREE.Mesh(building, material));
}
2. Fractal-Based Landscapes
Fractals are perfect for creating mountains, trees, and other natural forms.
- Mountains with Perlin Noise:
- Generate a height map using noise functions.
const size = 256;
const heightMap = [];
for (let x = 0; x < size; x++) {
heightMap[x] = [];
for (let y = 0; y < size; y++) {
heightMap[x][y] = noise.perlin2(x / 50, y / 50) * 20; // Random heights
}
}
- Fractal Trees:
- Use recursion to grow tree branches.
function generateBranch(position, depth) {
if (depth === 0) return;
const branch = new THREE.CylinderGeometry(0.1, 0.2, 1);
branch.position.copy(position);
scene.add(new THREE.Mesh(branch, material));
generateBranch(position.add(new THREE.Vector3(0, 1, 0)), depth - 1);
}
generateBranch(new THREE.Vector3(0, 0, 0), 5);
3. Dynamic Textures
Procedural textures make surfaces unique and adaptable.
- Generate Textures on the Fly:
- Use a canvas to draw textures dynamically.
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
canvas.width = 256; canvas.height = 256;
for (let i = 0; i < 1000; i++) {
ctx.fillStyle = `rgba(${Math.random() * 255}, ${Math.random() * 255}, ${Math.random() * 255}, 1)`;
ctx.fillRect(Math.random() * 256, Math.random() * 256, 10, 10);
}
const texture = new THREE.CanvasTexture(canvas);
const material = new THREE.MeshStandardMaterial({ map: texture });
Conclusion
Procedural content generation with Three.js enables dynamic and scalable 3D worlds. Whether creating cities, landscapes, or textures, these techniques offer endless possibilities. With the integration of AI, PCG becomes even more powerful, offering new levels of interactivity and creativity.