Articles Archive
Articles Search
Director Wiki

Creating a 3D Maze From a Picture

April 17, 2002
by Will Turnage

Dear Handyman,

I have a picture of a maze, and I want to turn it into a 3D model. I don't have any 3D programs, otherwise I would just use those. Can you help me out?


Dear Misa,

Taking a picture of a maze and turning it into its own 3D model can be a pretty daunting task, however, there are a few tricks you can use to make it easier.

You should start by getting a picture of a maze. Ideally, the picture of the maze should be a 1 bit graphic where a black pixel represents the sides of the maze and a white pixel represents the path that you can walk through. Take for example, this maze:

The image on the left is the actual image of the maze, and the image on the right has been blown up for clarity. If you don't have a picture of a maze, then there are plenty of online resources that will generate pictures of mazes for you. This particular maze came from There is a simple form there that you fill out specifying the width and height, and it will generate a picture of a random maze for you.

Once you have your picture imported into your Director cast, then you need to create a handler which will take that image and convert it into a 3D model. The other piece of information you will need is the scale of your maze. That is, how wide do you want the walls and passages to be. Once you know these two things, then you're ready to write some code:

on createMaze whichImage, wallSize
  mazeImage = whichImage.image.duplicate ()

  imageWidth = mazeImage.width - 1
  imageHeight = mazeImage.height - 1

  mazeWorld = member ("mazeWorld")
  mazeWorld.resetWorld ()

This handler is passed two parameters. The first parameter is the cast member that contains the image of the maze. The second parameter is the size that you want the maze walls to be. The handler starts by getting the image of the maze from the member and storing it in a variable. Next, it stores the height and the width of the image in a variable. Finally, you assign your Shockwave3D cast member to a variable and reset the world so that it's empty. Once the world is reset, you're ready to start building some walls.

  wallResource = mazeWorld.newModelResource ("mazeWall", #box)
  wallResource.width = wallSize
  wallResource.height = wallSize
  wallResource.length = wallSize

  mazeWall = mazeWorld.newModel ("mazeWall", wallResource)

  mazeWorld.newtexture ("mazewall texture", #fromCastMember, member ("greenblock"))
  mazeWorld.newshader ("mazewall shader", #standard)
  mazeWorld.shader ("mazewall shader").texture = mazeWorld.texture ("mazewall texture")

  repeat with i = 1 to 6
    mazeWall.shaderList[i] = mazeWorld.shader ("mazeWall shader")
  end repeat

You start by creating a new model resource for the maze walls. This resource is a simple cube that has the same width, height, and length that you passed to the handler. Next, you create a model named "mazeWall" based on the model resource you just created. After that, you create a new texture and shader for the maze wall. In this case, the texture is used from a cast member called "greenblock", which is just a small green bitmap image. Finally, you repeat through all six sides of the box and assign the green shader to each face of the cube. Now that everything is set up, you're ready to start building the maze.

  counter = 1

  repeat with i = 0 to imageHeight
    repeat with j = 0 to imageWidth
      if mazeImage.getPixel(j,i, #integer) = 255 then
        newMazeWall = mazeworld.model("mazewall").clone("mazewall" & counter)
        newMazeWall.translate (wallSize * j, -(wallSize * i), 0)
        counter = counter + 1
        -- this counter statement is just used for debugging
        -- so you know that the handler is still working
        -- and that you don't think your computer has locked up
        put counter
      end if
    end repeat
  end repeat


You start by setting a counter to 1. This will be used for naming the maze walls. Next, you repeat through each row of the image. You check the image to see if the pixel has a color of 255 which in this case means it's a black pixel in an 8 bit image. If the pixel is black, then you create a clone of your original maze wall model. Move this new cube into its proper position by using the information about the current pixel and multiplying that number by the size of the wall. Finally, you increase counter by 1.

That's all there is to it. When you're done, you will have a 3D cast member that contains an exact replica of your maze, like this:

A sample Director 8.5 movie is available for download in SIT or ZIP archives. It may take about 10 or 20 seconds to generate the sample maze in the demo, watch the value of counter in the Message window to see when it finishes.

All colorized Lingo code samples have been processed by Dave Mennenoh's brilliant HTMLingo Xtra, available from his site at

Will Turnage is a multimedia programmer based in New York City. In addition to his weekly role as Director Online's Multimedia Handyman, he is also the Technology Director for Sony Music's Client Side Technologies Group. You can read more about his work at

Copyright 1997-2019, Director Online. Article content copyright by respective authors.