Why I Built It

I was always fascinated by AI. How it can help us solve daily problems. Or even a hive solution to problems that were looked at as hard.


When people talk about AI. They see big data and algorithms. But I wanted to see the beautiful side of AI. Can it help me build art? Can it be created totally by AI?


That's how "3D Heightmap Surface - Pixel Art Visualizer" was created.


The idea wasn't to create a product. But to see what can be created if you create using AI.


I asked an AI assistant (ChatGPT) to help me write a web app that transforms any pixel art into a 3D model. And it gave me an expressive result: a webpage that lets you upload an image, view it as a heightmap, and even download it as a .glb model for use in 3D software like Blender or Unity.



What the Project Does


The concept is straightforward. Every pixel color determines how high or low the 3D surface should be.


So the uploaded pixel art will become a 3D landscape of your art.



All of it runs entirely in your browser, powered by Three.js no installation required.


The Core Code

If you are interested in seeing the code, here it is:


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>3D Heightmap Surface — Pixel Art Visualizer</title>
<style>
  body { margin: 0; overflow: hidden; background: #111; font-family: Arial, sans-serif; color: white; }
  #controls {
    position: absolute; top: 70px; left: 20px;
    display: flex; gap: 10px;
  }
  input[type="file"], button {
    padding: 10px 15px; font-size: 14px;
    border: none; border-radius: 8px; cursor: pointer;
  }
  input[type="file"] {
    background: #222; color: white;
  }
  button {
    background: #0a84ff; color: white;
  }
  h1 {
    position: absolute; top: 10px; left: 20px;
    font-size: 22px; margin: 0;
  }
  h2 {
    position: absolute; top: 35px; left: 20px;
    font-size: 14px; color: #aaa; margin: 0;
  }
</style>
</head>
<body>
<h1>3D Heightmap Surface</h1>
<h2>Pixel Art Visualizer</h2>

<div id="controls">
  <input type="file" id="imageInput" accept="image/*">
  <button id="saveBtn" disabled>Download Model</button>
</div>

<script src="https://cdn.jsdelivr.net/npm/[email protected]/build/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/examples/js/exporters/GLTFExporter.js"></script>

<script>
let scene, camera, renderer, mesh, controlsEnabled = false;

// Initialize scene
function initScene() {
  scene = new THREE.Scene();
  camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
  renderer = new THREE.WebGLRenderer({ antialias: true });
  renderer.setSize(window.innerWidth, window.innerHeight);
  document.body.appendChild(renderer.domElement);

  const light = new THREE.DirectionalLight(0xffffff, 2);
  light.position.set(1, 1, 1);
  scene.add(light);
  camera.position.set(0, 1.5, 5);

  animate();
}

function animate() {
  requestAnimationFrame(animate);
  if (mesh && controlsEnabled) mesh.rotation.z += 0.005;
  renderer.render(scene, camera);
}

// Handle image upload
document.getElementById('imageInput').addEventListener('change', event => {
  const file = event.target.files[0];
  if (!file) return;

  const url = URL.createObjectURL(file);
  loadImageAs3D(url);
});

function loadImageAs3D(imageURL) {
  const loader = new THREE.TextureLoader();
  loader.load(imageURL, texture => {
    if (mesh) scene.remove(mesh); // remove old mesh

    const geometry = new THREE.PlaneGeometry(5, 5, 128, 128);
    const material = new THREE.MeshStandardMaterial({
      map: texture,
      displacementMap: texture,
      displacementScale: 1,
      color: 0xcccccc,
    });

    mesh = new THREE.Mesh(geometry, material);
    mesh.rotation.x = -Math.PI / 2.5;
    scene.add(mesh);
    controlsEnabled = true;

    document.getElementById('saveBtn').disabled = false;
  });
}

// Download model as .glb
document.getElementById('saveBtn').addEventListener('click', () => {
  if (!mesh) return;
  const exporter = new THREE.GLTFExporter();
  exporter.parse(mesh, result => {
    const blob = new Blob([JSON.stringify(result)], { type: 'application/octet-stream' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = 'model.glb';
    a.click();
    URL.revokeObjectURL(url);
  });
});

initScene();
</script>
</body>

</html>


That’s it.


Just run it in a code editor and view it. And it you want to view it directly here it is.


No backend, no framework, just HTML and JavaScript—this simple.


How AI Helped


AI didn’t just write the code; it accelerated the entire development process.


Here's what I used it for.



The Bigger Idea

Projects like this are small, but their meaning is big. Not just for me.


They show how AI collaboration can expand human creativity, not replace it.


It shows another face of AI that we don't usually pay attention to.



Final Thoughts


AI doesn’t stop the creative process; it extends it.


It turns coding into a conversation between curiosity and the possibility of making new beautiful components.


This 3D heightmap surface is more than a fun experiment; it’s proof that AI can help anyone bring visual ideas to life, one pixel at a time.