Advertisement
  1. Code
  2. 3D
Code

Journey to the Next Dimension With Papervision3D: Part 2

Difficulty:IntermediateLanguages:

Continuing on from part 1 where we got to grips with Papervision3D, part 2 takes our scene a bit further. In this concluding part you'll learn how to make your revolving cubes jump out at the viewer with 3D glasses.

Introduction

I know it says up there that this tutorial is about Papervision3D in Flash, but actually it's about tricking your brain. We're going to make your brain think that it's looking at an actual 3D object, when in fact it's just seeing a 2D image.

If you're familiar with Papervision3D, you'll be able to follow this through using any project that has a scene, a camera, and a viewport. If not, check out Part 1 of this tutorial first, as I'm going to continue from where we left off. Here's the kind of thing we'll be working towards:

Final result

Step 1: Add a Second Camera

Point your finger in the air, and hold it up in front of your nose.

Look at it with just your right eye open, then with just your left. See how it appears to jump from left to right, while whatever's in the background barely seems to move at all?

Your brain notices these differences between what each of your eyes sees and uses them to generate a full 3D simulation of the world around you. In your head. Instantly. Pretty impressive!

If we're going to trick your brain, we'll need to make each of your eyes see a different image. So to start, let's add another "eye" (another camera) to the scene. This will be used to create the image for your right eye, while the existing camera's image will be fed to your left eye.

Create a new public variable called camera2...

...and initialise it in the Main() constructor function:

Step 2: Create a New Viewport

We'll need another viewport to take the camera's output, so add the following:

(I'm rushing through this, since we covered it all last time.)

Step 3: Render the Second Camera to the Second Viewport

Remember, viewport2 will be blank until we render something to it. We don't need to create a new renderer for this; just use the existing one twice. So, in Main(), take this code:

...and add a new line to render the second camera to the second viewport, like so:

Do the same in your onEnterFrame() function, too:

If you test this out now, well, it'll look the same as it did before:

But that's no surprise: for one thing, the two cameras are in exactly the same place!

Step 4: Separate the Cameras

By default, cameras are placed at (x=0, y=0, z=-1000) - you can check by doing trace( camera.x, camera.y, camera.z ).

So seen from above, the scene looks like this:

From the top

Seen from the side, it's like this:

From the side

To properly mimic our own eyes, we should place our second camera a little bit to the right of our first:

From the top, side by side

Let's try moving it 50 pixels to the right, and see what happens. Put this in Main(), somewhere after creating the second camera:

Now test it out, and see what you get:

Behind you!

It looks weird, but it's clearly working! The area around the cubes is transparent in each viewport, so the first can be seen behind the second.

Step 5: Make it Wink!

It'll be useful to be able to look at what each camera is seeing individually, so let's take the eye analogy further by making them "wink" when we click. First, add an event listener to each viewport, to detect the mouse clicks:

Put that at the end of the Main() function. Don't forget to import MouseEvent:

Step 6: Set Up the Click Event Handlers

Add these new functions to your code, outside the Main() function but inside the Main class:

Step 7: Toggle Viewport Visibility

When we click the first viewport, we need it to become invisible while the second becomes visible (and vice-versa for when we click the second). So modify your event handlers like so:

Try it out:

Note that you have to click one of the cubes; the transparent areas don't fire off a CLICK MouseEvent.

Step 8: Find Some 3D Glasses

You're going to need a pair of 3D "anaglyph" glasses; the kind where each lens is a different color. The pair I'm using has a yellow lens in the left eye and a blue lens in the right eye (called the ColorCode3D system), but other color combinations are also popular, like red and cyan.

You can find these glasses on eBay for a few dollars: just search for 3d glasses

Alternatively, you could even make your own! André posted a comment on the first part of this tutorial explaining that he uses Tic-Tac boxes of different colors to make his. Genius!

Although my examples will be made for yellow and blue glasses, I'll try to explain the principles so that you can make yours work with whatever colors you have. It's a bit tricky, so please post a comment below if this gets confusing!

Step 9: Understand How the Glasses Work

Every pixel on your computer is like a group of three lightbulbs: one red, one green and one blue.

By adjusting the brightness of each "bulb" we can alter the color of that pixel:

  • A white pixel has all three bulbs turned on full
  • A black pixel has all three turned off
  • A green pixel has the green bulb turned on and the other two turned off

The lenses in 3D glasses stop the light from some of those bulbs from getting through. For example, the blue lens in my glasses blocks the red and green light from reaching my eye.

So if I look at this image through my blue lens, I won't be able to read it:

Font is from urbanpixel.ca

No light reaches my eye from the black area because all three bulbs are switched off. And no light reaches my eye from the green area, because only the green bulb is switched on, and the blue lens filters that out. So all I see is a black rectangle.

Now, OK, if you try this yourself you may find that this is not entirely true. Your lens probably isn't 100% pure blue, so it'll let a little green and red light through. Or maybe your monitor's colors are calibrated differently to mine, so the green text has a small amount of red and blue in it. To be honest, the same's true for me - but it doesn't matter, as long as the text is hard to read.

Our aim is to make it hard for your right eye to see the image from the left camera, and likewise for your left eye and the right camera.

Step 10: Make the Left Viewport Invisible to Your Right Eye

The blue lens is over my right eye, so in theory if I remove all the blue from the left camera's image, I won't be able to see it with my right eye.

In this step, then, let's make the left viewport's image only emit red and green light; no blue light at all. We can do this using a ColorTransform. These are easy to set up; first, import the class:

Then, create a new public variable to hold an instance of the class:

Now actually create this new instance inside Main():

Finally, tell Flash to apply this ColorTransform to the left camera's viewport:

(That last line must be after you've created the viewport and the color transform. It's probably easiest just to put it right at the end of Main().)

Step 11: Remove All the Blue from the Viewport

The SWF won't look any different yet, because the ColorTransform doesn't change the image at all by default.

We can choose what fraction of each bulb's light we want to let through by changing the blueMultiplier, greenMultiplier and redMultiplier properties of our ColorTransform.

Setting any of these to 1 tells Flash to leave it alone, while setting it to 0 tells Flash to turn it off completely. And, naturally, 0.5 will make it output half the normal amount, 2.0 will make it double it, and so on.

So to drain all of the blue out of the left viewport, we can do this:

You need to put that before the line that applies the transform to the viewport, like this:

If your glasses have a red or green lens over the right eye, then you should set the redMultiplier or greenMultiplier to 0, rather than the blue. For any other colors, you'll need to use a mixture of red, green and blue - more on that in Step 15.

Test the SWF:

Look how they shine for you

It's difficult to make out the "a" of the logo through the blue lens, but it's not difficult at all to make out the shape of the cubes against that white background!

Step 12: Fill the Transparent Areas

If you change the background of your SWF, you'll see the problem. Because the "white" area around the cubes is not actually white, but rather transparent and letting the white background of the SWF show through, it's not affected by the ColorTransform.

To fix this, we need to give the viewport a solid white background that the cubes will be rendered on top of. That's easy enough; just go back to where you created the viewport:

...and add a couple of lines to draw a white rectangle that's as big as the stage:

Test it out again:

And it was all yellow

The image should be really dim, dull and hard to see through the right lens, but as easy as the regular image to see through the left lens.

Step 13: Create a New ColorTransform

We need to do the same thing for the right viewport now. So, create your new ColorTransform:

Step 14: Apply the New ColorTransform

Now, apply this new transform to the right viewport:

Step 15: Remove All the Yellow from the Viewport

Since my left lens is yellow, I need to drain all the yellow out of this viewport.

(If your left lens is red, then this step is easy - just set the redMultiplier of your new ColorTransform to 0.)

But how do we get yellow out of red, green and blue?

If we were using paints, we couldn't; yellow is a primary color in that case. But when dealing with light, things are different. Take a look at this:

Image from Wikimedia Commons -- thanks, Mike Horvath and jacobolus!

Image from Wikimedia Commons. Thanks, Mike Horvath and jacobolus!

As you can see, red and green mix together to make yellow (which explains why the background of the left viewport became yellow when we removed all the blue). So to remove all the yellow from our image, we need to remove all the red and all the green!

We can do this like so:

Oh, right, we have to fill in the background of this viewport, too.

Step 16: Fill the Transparent Areas

Do this in the same way as before:

Test it out:

da ba de da ba di

The yellow lens on my glasses actually lets a fair amount of blue light through, but it's still a lot darker when viewed through that lens than when viewed through the blue lens, and that's what matters.

Step 17: Merge the Two Images

So we've got our two images set up and color-transformed. Trouble is, at the moment we can only see one of them at a time.

The most obvious way to let us see both at once is to reduce the alpha (the transparency) of the viewport at the front, like so:

Test this out:

Muddy

Ah. OK, not a rousing success. Alpha's clearly not the right tool for the job; what else have we got?

Step 18: Blend the Two Images

Flash gives us the choice of several different blend modes, methods of blending two display objects together. There's a full list of them here, but I'm just going to focus on the one called add.

The add blend mode goes through each pixel of the two images, and adds together the brightness of each of the three bulbs.

So if one particular pixel in the first image has the green bulb fully on and the other two fully off, and the same pixel in the second image has the blue bulb fully on and the other two fully off, then when blended together the green and blue bulbs will be fully on, and the red bulb will be fully off.

If the first and second images both have the red bulb half-way on and the other two fully off, then the blended image will have the red bulb fully on, while the other two stay off.

Get the picture? Great, let's use it. Delete the line we just wrote that adjusted the alpha, and replace it with this:

(We don't need to apply the blend mode to both viewports, just the one at the top of the display list.)

Test it out:

Great Scott!

That's more like it!

If you look at it through one eye at a time, you should notice that each eye sees a different viewport more promintently. You'll probably also be able to see a faint ghost of the other viewport, but that's not a problem; your brain can ignore that.

However, the image doesn't quite look 3D yet. Let's sort that out.

Step 19: Tweak the Separation

Even though your eyes are seeing different images, this isn't enough to fool your brain. Your brain's quite smart, you see; some would even say it's the smartest organ in your body. It knows that it should use other clues to work out whether or not an object is 3D. Perspective, for example: how small an object should look based on how far away it is.

The main problem here is that our two cameras are spaced much further apart from each other than our own eyes are. That's not surprising, since I picked the number 50 at random.

The actual separation distance we should use is going to depend on a number of things, like how far away you are from the monitor and how large your screen is, so I can't just give you a magic number to use. We'll have to figure it out manually.

We could do this by trying lots of different numbers one by one, but this is tedious and will take forever. I've got a better idea.

Add this line to your onEnterFrame() function:

Now change your onClickViewport and onClickViewport2 functions to the following:

Run the SWF, and move the mouse left and right. It'll look like this:

Put your glasses on, turn the lights off, and keep moving the mouse till you find the "sweet spot" where the image seems to become solid. Click the mouse at this point, and it'll trace out a number. Make a note of it!

Step 20: Set the Separation

Once you've found the optimum separation, delete the line we just added to the onEnterFrame() function:

Now find the line in Main() where you set the distance between the cameras:

...and replace the 50 with whatever number you noted down. I found that 18 was a good number to use for my setup.

Finally, test the SWF:

ThreeeeeDeeeee

Ta-da!

Conclusion

Well done - you've created a 3D scene in Flash and used some mind trickery to transfer it to a 3D scene inside your head ;)

If you've understood everything you went through, you should be able to use the same technique to make 3D anaglyph images using other 3D engines.

I mentioned in the first part that you might like to try making it possible for the user to move the camera with the mouse. Now you've added the anaglyph effect, moving the cameras forwards and backwards will look very impressive.

Thank you for reading this tutorial, I hope you've found it useful. As always, if you've any questions, please ask them in the comments below.

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.