4. Lights, colors and materials

4.1 Lighting your world

Lights in virtual worlds are not like lights in the real world. Real lights are physical objects that emit light; you can see the object that emits the light as well as the light it emits, and that light reflects off of various other objects to allow you to see them. In computer simulated worlds ligths are immaterial: they don't necessarily have any geometry to represent the light source. For instance a lighting node describes how a part of the world should be lit, but does not automatically create any geometry to represent the light source. If you want a light source in your scene to be a visible object, you need to create a piece of geometry (a lightbulb for example), and place it at the same location as the light node (perhaps you should assign an emissiveColor - as part of the associated Appearance node se later - to the geometry; otherwise there's no indication that the object is associated with the light source).

Another difference between VRML(as currently implemented) the real world is that objects in VRML don't cast shadows. This fact is due to the way current VRML browsers handle lighting: the renderers they're based on are using "shading algorithms" instead of "raytracing". Renderers don't attempt to simulate photons rushing around and bouncing off of things, but instead apply a lighting equation to each piece of geometry drawn, in order to shade surfaces realistically. The lighting equation combines the colors of the object in question (as indicated in the shape's Appearance node) with the colors of light available (as indicated by light nodes). This computation ignores the effects of opaque objects between the light and the geometry being lit: if you need cast shadows, you have to simulate them (by placing flat dark semitransparent polygons where the shadow should be or using per-vertex coloring - see later).
There are three kinds of light nodes in VRML: DirectionalLight, PointLight, and SpotLight. A VRML lighting node lights only certain objects:

The standard fields - which are common to all of them - and their default values are:

The use of ambient lighting is a little bit complex: you should leave it's value of 0 when you don't need it, as we did it in the first lighting examples. If a light is on, its contribution to the scene's overall ambient lighting is computed (for each of red, green, and blue values) by multiplying the light's intensity by its ambientIntensity, and multiplying the result by the light's value for that color component. For example this PointLight node:
PointLight {
  on                TRUE
  intensity         .75  # three-quarters maximum brightness
  ambientIntensity  .5
  color             1 0 0  # red
}
contributes .75x; .5 x 1 = .375 to the red portion of the ambient lighting for the scene. All of the ambient light values for all of the lights in the scene are added up and applied to objects within the lights' scopes. Note that this means that changing the light's intensity also changes its cotribution to the scene's ambient lighting.

In the real world, light attenuates: it loses intensity the farther you are from the light source. VRML can simulate attenuation for lights that have a location using the attenuation field. Since directional lights have no specific location, only pointlights and spotlights have the attenuation field with the following default values:

The browser multiplies the attenuation factor by the light's intensity value to determine intensity at a given distance. Note that not all browsers can handle full lighting attenuation; if you use attenuation in your scene, some users may not experience it.
Note that you should manually turn off the "headlight" in the browser to see exactly the ligting effects when exploring the following examples: you will see later how to turn it off automatically using the NavigationInfo node.
Also note that despite of that you can find all the fields of the light sources (according to the VRML specification), but since some of them are not implemented in browsers, we will not use them in the examples.

4.1.1 DirectionalLight

Directional lights point in a specified direction from the infinite distance (they don't have a location). Directional lights have the following fields(and default values):

DirectionalLight {
	on TRUE 
	intensity 1.0 
	ambientIntensity 0.0 
	color 1.0 1.0 1.0 
	direction 1.0 0.0 0.0
}

In the following simple example we set up a directionallight lighting from the negative X to positive X direction with a red color. We left everything else on the default values in the PointLight node. The only object in the world is a "default cone" with a "default material" in its appearance node. The light and the object has to be in the same group(in this case a Transform group without any transformations):

Show the DirectionalLight example
#VRML V2.0 utf8
#DirectionalLight example
Transform {
children[
	DirectionalLight { 
		direction         1 0 0 #from -X to +X
		color             1 0 0 #the color is red
			}

	Shape {
		appearance Appearance{
		material Material { }
			}
		geometry Cone { }
	}
 ]
}

4.1.2 PointLight

Point lights have a location and they glow radially - just like a lightbublb. A point source emits light equally in all directions; that is, it is omnidirectional. PointLight nodes are specified in the local coordinate system and are affected by ancestor transformations.PointLights have the following fields(and default values):

PointLight {
	on TRUE 
	intensity 1.0 
	ambientIntensity 0.0 
	color 1.0 1.0 1.0 
	location 0.0 0.0 0.0
	radius 1.0
	attenuation 1.0 0.0 0.0
}

A PointLight node illuminates geometry within radius meters of its location. Both radius and location are affected by ancestors' transformations (scales affect radius and transformations affect location). The radius field shall be >= 0.0.
PointLight node's illumination falls off with distance as specified by three attenuation coefficients(see above).
In the following example we enlight a group of balls (you know them from the grouping-example) with a green pointlight source, located at -1 0 0(1 units left from the center). Note that all objects are in the same group with the light source.

Show the PointLight example
#VRML V2.0 utf8
#PointLight example

Group {
children[
	PointLight { 
		location 	-1.0 0.0 0.0#the light is 1 units left on the X axis 
		color       0 1 0 	#the color is green
			}

DEF 3balls Group {
  children [
	DEF ball Shape{
			appearance Appearance{
				material Material { }
					}
			geometry Sphere {
				radius  0.5  #radius in units  				}
				}
			}

  	  Transform {
  	    translation 2 0 0
  	    children   [ USE ball ]
 	   }
  	  Transform {
 	     translation -2 0 0
  	    children    [ USE ball ]
  	  }
	]
}

Transform {
	translation 0 2 0
  	   children   [ USE 3balls ]
 	   }

Transform {
	translation 0 -2 0
  	   children   [ USE 3balls ]
 	   }
 ]
}

4.1.3 SpotLight

Spotlights have a location and they illuminate in a cone pointed in a specified direction. The SpotLight node defines a light source that emits light from a specific point along a specific direction vector and constrained within a solid angle. Spotlights may illuminate geometry nodes that respond to light sources and intersect the solid angle defined by the SpotLight. Spotlight nodes are specified in the local coordinate system and are affected by ancestors' transformations. SpotLights have the following fields(and default values):

SpotLight {
	on TRUE 
	intensity 1.0 
	ambientIntensity 0.0 
	color 1.0 1.0 1.0 
	location 0.0 0.0 0.0
	radius 100
	attenuation 1.0 0.0 0.0
	direction 0 0 -1
	beamWidth 1.570796 #floating point angle in radians = 90 degree
	cutOffAngle 0.785398  #floating point angle in radians = 45 degree

}

The cutOffAngle field specifies the outer bound of the solid angle. The light source does not emit light outside of this solid angle. The beamWidth field specifies an inner solid angle in which the light source emits light at uniform full intensity. The intensity of the illumination drops off exponentially toward the edges of the cone.
In the following example we use the previous balls enlighted by a blue spotlight located at -4 0 0(left 4 units on the X axis), emitting in the positive X direction.

Show the SpotLight example
#VRML V2.0 utf8
#SpotLight example

Group {
children[
	SpotLight { 
		location 	-4.0 0.0 0.0#the light is 1 units left on the X axis 
		color       0 0 1 	#the color is blue
		direction 	1 0 0		#the direction is to +X
			}

DEF 3balls Group {
  children [
	DEF ball Shape{
			appearance Appearance{
				material Material { }
					}
			geometry Sphere {
				radius  0.5  #radius in units  				}
				}
			}

  	  Transform {
  	    translation 2 0 0
  	    children   [ USE ball ]
 	   }
  	  Transform {
 	     translation -2 0 0
  	    children    [ USE ball ]
  	  }
	]
}

Transform {
	translation 0 2 0
  	   children   [ USE 3balls ]
 	   }

Transform {
	translation 0 -2 0
  	   children   [ USE 3balls ]
 	   }
 ]
}

Spotlights are slow and take a lot of processing power. It's probably best to use them as little as youcan. Be sure to test for performance every time you add one to your world.

4.2 Appearance

Let's recall that Shape nodes describe geometry(form, or structure) and appearance(color and texture).

Shape {
              geometry   . . .
              appearance . . .
          }
In the previous examples we used an appearance node with an empty material field instead of the default emissive (glowing) white appearance, to provide a simple 3D shading. In this chapter you will see the most important facilities of the "Appearance" node: the use of the "material", the "texture" and the "textureTransform" fields. The Appearance-fields and their default values are:

Appearance { 
	SFNode material          NULL
	SFNode texture           NULL
	SFNode textureTransform  NULL
}

Textures and texturetransform nodes will be discussed later, since they work only with "coordinate-based geometry", you can't examine them on primitives.

4.2.1 Materials

The "Material properties" contol the object's basic appearance like color, shininess, and transparency. The colors of objects are influenced by the lights enlighting them: the fields in the Material node doesn't describe the object's color in the world, they determine how light reflects off an object to create colour:

The fields and their default values of the Material node are the following:

Material { 
  exposedField SFColor diffuseColor      0.8 0.8 0.8 # [0,1]
  exposedField SFColor emissiveColor     0 0 0       # [0,1]
  exposedField SFFloat shininess         0.2         # [0,1]
  exposedField SFColor specularColor     0 0 0       # [0,1]
  exposedField SFFloat transparency      0           # [0,1]
  exposedField SFFloat ambientIntensity  0.2         # [0,1]
}

All of the fields in the Material node range from 0.0 to 1.0. The colors specify a mixture of red, green, and blue by values between 0.0 and 1.0. For example:

Color Red Green Blue
White 1.0 1.0 1.0
Black 0.0 0.0 0.0
Yellow 1.0 1.0 0.0
Magenta 1.0 0.0 1.0
Brown 0.5 0.2 0.0

In the following example there are 5 spheres with different materials in front of a dark-gray background-box. The scene is enlightened by a white pointlight placed 4 units right+up+forward you, and possibly by the "headlight"(you can try to turn it on and off to see the effect on the shiny surfaces). You can examine the effects of the various material settings (some of them are effecting each other):

Show the Materials example
#VRML V2.0 utf8
#Materials example
Group {
children [
	PointLight { 
		location 	4.0 4.0 4.0 #from right+up+forward you 4 units 
		color       1 1 1 	#the color is white
			}
	Transform{
	translation 0 0 -1
	children[
		Shape{
		appearance Appearance{
			material Material {
					diffuseColor 0.1 0.1 0.1 #simple gray
						}
			}
		geometry Box {
				size 12.0 4.0 0.1  				}
			}
		}
	  ]
	}

	Transform {
	translation -4 0 1
	children[
		Shape{
			appearance Appearance{
				material Material { 
					emissiveColor     0 0 1 #glowing blue
					}
				}
			geometry Sphere {
				radius  0.5  #radius in units  				}
				}
			}
		]
	  }
	Transform {
	translation -2 0 1
	children[
		Shape{
			appearance Appearance{
				material Material { 
					diffuseColor     1 0 0 #simple red
					}
				}
			geometry Sphere {
				radius  0.5  #radius in units  				}
				}
			}
		]
	  }
	Transform {
	translation 0 0 1
	children[
		Shape{
			appearance Appearance{
				material Material { 
					diffuseColor     0 0 1 #blue
					shininess        0.8
					specularColor    1 0 0 #with red shiny spot	
					}
				}
			geometry Sphere {
				radius  0.5  #radius in units  				}
				}
			}
		]
	  }

	Transform {
	translation 2 0 1
	children[
		Shape{
			appearance Appearance{
				material Material { 
					diffuseColor     0 1 0	#green
					shininess        0.9
					specularColor    1 0 0	#with red shiny spot
					transparency     0.8	#high transparency
					}
				}
			geometry Sphere {
				radius  0.5  #radius in units  				}
				}
			}
		]
	  }

	Transform {
	translation 4 0 1
	children[
		Shape{
			appearance Appearance{
				material Material { 
					diffuseColor     0.5 0.5 0.5 #gray
					shininess        0.9
					specularColor    1 0 0 	#with red shiny spot
					transparency     0.5	#middle transparency	
					}
				}
			geometry Sphere {
				radius  0.5  #radius in units  				}
				}
			}
		]
	  }

  ]
}