Turning Pixel Art into 3D: Building a Heightmap Visualizer with AI Guidance

Written by Joeboukhalil | Published 2025/11/06
Tech Story Tags: ai | tool | 3d | chatgpt | real-life-use-of-ai | pixel-art-visualizer | pixel-art-3d | 3d-pixel-art

TLDRBuilding a tool with the help of AI that transforms pixel 2D images into heightmap surfaces.via the TL;DR App

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.


  • Upload any pixel art.
  • It then turns pixel brightness into depth.
  • Download the result as a .glb 3D model.


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.


  • Understanding how to use Three.js displacement maps
  • Troubleshooting missing exports and blank screens. Because it would show a black screen without anything on it.
  • Generating a readable interface
  • Writing explanations so I can understand the mistakes if I want to build it later.


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.



Written by Joeboukhalil | I'm an independent creator passionate about building useful tools, simulations, and theories that make complex ideas more accessible. I explore the intersection of technology, education, and human experience—often with the help of AI like ChatGPT.
Published by HackerNoon on 2025/11/06