DEV Community

Cover image for Building the "Round City" of Baghdad in Three.js: A Journey Through History and Performance
bingkahu
bingkahu

Posted on

Building the "Round City" of Baghdad in Three.js: A Journey Through History and Performance

Recreating the Round City of Baghdad in the Browser

I’ve been working on a web-based recreation of 8th-century Baghdad—the famous "Round City."

My goal was to create a procedural, interactive environment that captures the scale of the Golden Age of Islam while keeping it performant enough to run in a browser.


⚙️ The Technical Challenge: Instanced Rendering

To populate the city with 4,000 unique-looking buildings without tanking the frame rate, I used InstancedMesh.

Instead of the GPU drawing 4,000 separate objects (which would mean 4,000 draw calls), it treats them as a single group. By using a "dummy" object to calculate positions, scales, and rotations, I can generate a massive city in milliseconds.

JavaScript Example

// Quick look at the logic
const cityBody = new THREE.InstancedMesh(geometry, material, 4000);
for (let i = 0; i < 4000; i++) {
    const r = 250 + Math.random() * 800; // Radius logic
    const a = Math.random() * Math.PI * 2; // Angle logic
    dummy.position.set(Math.cos(a) * r, 0, Math.sin(a) * r);
    dummy.updateMatrix();
    cityBody.setMatrixAt(i, dummy.matrix);
}
Enter fullscreen mode Exit fullscreen mode

🛡️ Fighting the "Z-Fighting"

One of the biggest headaches in 3D web dev is Z-fighting—that annoying flickering when two surfaces overlap.

I solved this by:

  • Using a logarithmicDepthBuffer in the renderer
  • Giving the "lake" a physical thickness of 0.2 instead of using a flat plane
  • Applying a tiny 0.05 Y-offset to ensure the water sits just above the ground

📖 Narrative Interaction

A city is more than just boxes.

I added a narrative layer where clicking on a building pulls from a procedural array of residents—from Master Astrolabe Makers to Greek Translators.

It turns a technical demo into a living chronicle.


🌱 What’s Next?

I’m looking to add:

  • More procedural greenery (palm trees)
  • Basic AI for boats in the river

🔗 Links


💡 Final Thoughts

Instanced rendering made this project possible, but I’m always looking for ways to push it further.

I’d love to hear your thoughts on how to optimize instanced meshes even further!

Top comments (0)