Erain 3D
advert here

Author: makc
Date: February 29th 2008
version: 3.0.2

Using PhongAttributes in Sandy3D v3.0.2

In some cases PhongAttributes look great, in some other cases they don't. Here I will try to cover all these cases, when you should and should not use this lighting attributes class.

Perfect use case

In case you did not read quick 3.0.2 lighting walkthrough, here is our starting point code to play with PhongAttributes:

package
{
	import flash.display.*
	import flash.events.*

	import sandy.core.*
	import sandy.core.scenegraph.*
	import sandy.materials.*
	import sandy.materials.attributes.*
	import sandy.primitive.*

	public class V302_Light extends Sprite
	{
		private var world:Scene3D = new Scene3D ("scene", this as Sprite, new Camera3D (200, 200), new Group ("root"));

		public function V302_Light ()
		{
			// set up light attributes
			var a:PhongAttributes = new PhongAttributes (true, 0.2, 15);
			a.diffuse = 0.5;
			a.specular = 1;
			a.gloss = 5;

			// show something
			var s:Sphere = new Sphere ("s", 100, 20, 20);
			var m:ColorMaterial = new ColorMaterial (0xFF, 1, new MaterialAttributes (a));
			m.lightingEnable = true; s.appearance = new Appearance (m);
			var g:Group = new Group ("root"); g.addChild (s); g.addChild (world.camera);
			world.root = g; world.light.setDirection (1, -1, 1); world.render ();
		}
	}
}
This code illustrates a situation where this attribute looks best - a shape with surface curved in both its dimensions.

Not so perfect use case

Let us reduce sphere polygon count and change light direction like this:

var s:Sphere = new Sphere ("s", 100, 4, 3);
...
world.light.setDirection (1, -1, 0);

As you see, while specular highlight still looks acceptable, diffuse shading is no longer smooth. This illustrates the fact that PhongAttributes does work better for higher polygon counts.

To work around this, use onlySpecular property to combine PhongAttributes specular highlight with diffuse GouraudAttributes:

var a1:GouraudAttributes = new GouraudAttributes (true, 0.3);
a1.diffuse = 0.5;
var a2:PhongAttributes = new PhongAttributes (true, 0, 15);
a2.diffuse = 0.5;
a2.specular = 1;
a2.gloss = 5;
a2.onlySpecular = true;
...
var m:ColorMaterial = new ColorMaterial (0xFF, 1, new MaterialAttributes (a1, a2));

What the hell is p_nQuality?

PhongAttributes use flash radial gradient to create lightmap, and the number of colors in that gradient is defined by p_nQuality constructor parameter. The overall effect of using lower quality is that “white haze”, ugly side effect of the way Sandy does shading currently, gets much more visible. As they say, a picture's worth of thousand of words, so here you go:

pattr_quality.jpg
In english, it means that you should use higher p_nQuality for smaller gloss values.

Flat out wrong use case

Using PhongAttributes on planes, or boxes, or any other bodies with completely flat surface is just wrong. Not only because PhongAttributes math cannot handle this and fails, but also because the shading is not supposed to be smooth in this case. We have good old LightAttributes for this purpose, so use them instead.

Half-flat models

Ok, but what about models with surface curved at least in one dimension, such as cylinder? This still confuses PhongAttributes math and, while it tries its best to find correct mapping, shading may turn out not smooth at all. For example, make these changes in our boilerplate code:

var s:Cylinder = new Cylinder ("c", 90, 180);
...
world.light.setDirection (1, -1, 4);

To work around this, use spherize property that, as the name suggests, treats shape surface as if it was curved more like a sphere:

// set spherize to small positive number
a.spherize = 0.1;

Hope this will answer some questions.