There are many ways to change the way that
objects in your scene look. You can change their color, how much light
they reflect. You can paint them with two-dimensional images, or add rough
textures to their surfaces. The Appearance class contains the functions
for making these changes. This section shows you how to use these functions.

The simplest way of setting the appearance
is by specifying only the color and the shading method. This works for
setting an object to being a simple color, but to make an object look
realistic, you need to specify how an object appears under lights. You
do this by creating a Material.

Create an object

Sphere sphere = new Sphere();

Create an appearance

Appearance ap = new Appearance();

Create a color

Color3f col = new Color3f(0.0f, 0.0f, 1.0f);

Create the coloring attributes

ColoringAttributes ca = new ColoringAttributes

(col, ColoringAttributes.NICEST);

Add the attributes to the appearance

ap.setColoringAttributes(ca);

Set the appearance for the object

sphere.setAppearance(ap);

Materials

Materials have five properties that enable you to
specify how the object appears. There are four colors: Ambient, Emissive, Diffuse,
and Specular. The fifth property is shininess, that you specify with a number.

Each color specifies what light is given off in a
certain situation.

Ambient color reflects light that been scattered
so much by the environment that the direction is impossible to determine.
This is created by an AmbientLight in Java 3D.

Emissive color is given off even in darkness.
You could use this for a neon sign or a glow-in-the-dark object

Diffuse color reflects light that comes from one
direction, so it's brighter if it comes squarely down on a surface that if
it barely glances off the surface. This is used with a DirectionalLight.

Specular light comes from a particular direction,
and it tends to bounce off the surface in a preferred direction. Shiny metal
or plastic have a high specular component. The amount of specular light that
reaches the viewer depends on the location of the viewer and the angle of
the light bouncing off the object.

Changing the shininess factor affects not just how
shiny the object is, but whether it shines with a small glint in one area, or
a larger area with less of a gleaming look.

For most objects you can use one color for both Ambient
and Diffuse components, and black for Emissive (most things donít glow in the
dark). If itís a shiny object, you would use a lighter color for Specular reflections.
For example, the material for a red billiard ball might be:

// billiard ball

// ambient emissive diffuse specular
shininess

// Material mat = new Material(red,
black, red, white, 70f);

For a rubber ball, you could use a black or red
specular light instead of white which would make the ball appear less shiny.
Reducing the shininess factor from 70 to 0 would not work the way you might
expect, it would spread the white reflection across the whole object instead
of it being concentrated in one spot.

Texture

Materials make change the appearance of a whole shape,
but sometimes even the shiniest objects can seem dull. By adding texture you
can produce more interesting effects like marbling or wrapping a two-dimensional
image around your object.

The TextureLoader class enables you to load an image
to use as a texture. The dimensions of your image must be powers of two, for
example 128 pixels by 256. When you load the texture you can also specify how
you want to use the image. For example, RGB to use the color of the image or
LUMINANCE to see the image in black and white.

After the texture is loaded, you can change the TextureAttributes
to say whether you want the image to replace the object underneath or modulate
the underlying color. You can also apply it as a decal or blend the image with
the color of your choice.

If you are using a simple object like a sphere then
you will also have to enable texturing by setting the "primitive flags".
These can be set to Primitive.GENERATE_NORMALS
+ Primitive.GENERATE_TEXTURE_COORDS when you
create the object.

In case this is starting to sound a bit complicated,
here is an example. You can experiment with the texture settings in this example
and compare the results. You can download the picture I used from http://www.java3d.org/Arizona.jpg
or you can substitute a picture of your own.

import com.sun.j3d.utils.geometry.*;

import com.sun.j3d.utils.universe.*;

import com.sun.j3d.utils.image.*;

import javax.media.j3d.*;

import javax.vecmath.*;

import java.awt.Container;

public class PictureBall {

public PictureBall() {

// Create the universe

SimpleUniverse universe = new
SimpleUniverse();

// Create a structure to contain
objects

BranchGroup group = new BranchGroup();

// Set up colors

Color3f black = new Color3f(0.0f,
0.0f, 0.0f);

Color3f white = new Color3f(1.0f,
1.0f, 1.0f);

Color3f red = new Color3f(0.7f,
.15f, .15f);

// Set up the texture map

TextureLoader loader = new TextureLoader("K:\\3d\\Arizona.jpg",

"LUMINANCE", new Container());

Texture texture = loader.getTexture();

texture.setBoundaryModeS(Texture.WRAP);

texture.setBoundaryModeT(Texture.WRAP);

texture.setBoundaryColor( new
Color4f( 0.0f, 1.0f, 0.0f, 0.0f ) );

// Set up the texture attributes

//could be REPLACE, BLEND or DECAL
instead of MODULATE

TextureAttributes texAttr = new
TextureAttributes();

texAttr.setTextureMode(TextureAttributes.MODULATE);

Appearance ap = new Appearance();

ap.setTexture(texture);

ap.setTextureAttributes(texAttr);

//set up the material

ap.setMaterial(new Material(red,
black, red, black, 1.0f));

// Create a ball to demonstrate
textures

int primflags = Primitive.GENERATE_NORMALS
+

Primitive.GENERATE_TEXTURE_COORDS;

Sphere sphere = new Sphere(0.5f,
primflags, ap);

group.addChild(sphere);

// Create lights

Color3f light1Color = new Color3f(1f,
1f, 1f);

BoundingSphere bounds =

new BoundingSphere(new Point3d(0.0,0.0,0.0),
100.0);

Vector3f light1Direction = new
Vector3f(4.0f, -7.0f, -12.0f);

DirectionalLight light1

= new DirectionalLight(light1Color,
light1Direction);

light1.setInfluencingBounds(bounds);

group.addChild(light1);

AmbientLight ambientLight =

new AmbientLight(new Color3f(.5f,.5f,.5f));

ambientLight.setInfluencingBounds(bounds);

group.addChild(ambientLight);

// look towards the ball

universe.getViewingPlatform().setNominalViewingTransform();

// add the group of objects to
the Universe

universe.addBranchGraph(group);

}

public static void main(String[]
args) {

new PictureBall();

}

}

You can also set up three-dimensional textures, using
shapes instead of a flat image. Unfortunately, these do not currently work very
well across different platforms.

Special Effects

Look at the AppearanceTest example that comes with
Java 3D for more effects you can use. For example you can display objects as
wire-frames, display only the corners of an object and so on. You can even make
objects transparent, with the following settings: