Making a fake reflective disco ball in Altspace SDK

Hey all. I got asked to write up a little about how I pulled of a fairly convincing spinning discoball in AltspaceVR. The SDK doesnt really support dynamic lighting, or reflections, so we have to approach this as a bit of a visual trick.

When you look at a disco ball, all you are seeing is a normal chrome ball, but the faceted reflections means each face of the ball is reflecting just a fraction of the area it would be on a smooth surface. However overall the reflection is still spherical, just with a lot of gaps between the reflected areas.

So I thought, we can do this with some UV jiggerypokery!

So First, Here’s what we’ll be making:

discoball

ooooo shiny!

The most important part of this is prepping your sphere. A simple hard faced sphere wont work because we need the faces’ UVs to be very separated and isolated, but still in the right places relative to the other faces.

So here’s what I did:

Made a sphere, woo! sphere

Then I mapped my skybox image onto it. This could also be a proper reflection sphere image for the location you plan to place the ball.  Here’s the image I used (made from Altspace’s own skybox):

smallsky

Here it is assigned to my sphere.  Note the sphere is created with perfect UVs for this to map seamplessly: spheretextured

OK, so that’s a nice ball. Now we need to Separate the faces in the UVs so we get that faceted look. I also hardened the normals on the mesh at this point.

So Here are the UVs to begin with: startuvs

But we need to split the faces so they are no longer connected, and then shrink them into themselves. After separating the edges I used a Maya MEL  script I found here to shrink each UV “Shell” down towards its own center. Resulting in this:

separateduvs2

Here’s how things are looking in our 3D view:

sphere2

Now the trick here is that in Altspace we’ll use code to offset the image across these UVs horizontally.  The separation will make them seem to flash and sparkle.

The relevant code in Altspace, after loading the object is:

discoballMat = discoball.children[1].material;
discoballMat.map.wrapT = THREE.RepeatWrapping;
discoballMat.map.wrapS = THREE.RepeatWrapping;

This puts the current material to a variable. and then sets the map of that material to repeat the texture in all directions. So that once we start animating it to the side there’s another of the same image to go into.

The relevant part in the animation loop is this:

discoball.rotation.y += 0.01;
discoballMat.map.offset.x = (THREE.Math.radToDeg(discoball.rotation.y)/360);

And with that, you should have this!

discoball

Leave a Reply