I'm not sure exactly what you're seeing, but it sounds right. Normally,
when the renderer is computing the lighting at a vertex, it ignores all
lights that shine on the back side of the vertex (ie, the dot product
between the vertex normal and the light-to-vertex direction is >= 0). When
setBackfaceNormalFlip is true, the vertex normal is flipped for these
lights. The lighting equation uses abs(normal dot direction) rather than
-min(normal dot direction, 0). Conceptually, rather than saying that the
renderer is flipping the vertex normal, we could say that the renderer is
flipping the light-to-vertex direction. Therefore, for directional lights,
your scene will look as if each light is actually two lights shining in
opposite directions. For point lights the light-to-vertex direction
changes for each vertex, but the same idea holds true: for each vertex,
each point light looks as if it is actually two point lights, one in the
original position and one on the opposite side of the vertex.
In your case, your scene will look like it is lit by two lights, one along
+X, one along -X. Hope that helps.
Brian
At 04:13 AM 12/29/98 -0800, Ian wrote:
>My apologies for an earlier posting in which I said that setNormalFlip
>wan't illuminating both sides of a polygon. After caful examination it
>turns out it is illuminating both sides of a polygon but it is doing so in
>a strange way.
>
>My program creates two squares with normals pointing in opposite directions
>and a light source shining down the X axis.
>
>When the program is run, both sides of both squares respond to
>illumination, but one square appears to be illuminated from the +ive X axis
>the
>other square appears to be illuminated from the -ive X axis. It doesn't
>mater if I
>use a directional light source or a point light source, the same thing
>happens.
>
>Is this supposed to happen?
>
>Here is an example program to illustrate the problem. It has one
>directional light shining in the -ive X direction. Notice that one the
>squares illuminate as if the light sources were coming from opposite
>directions.
>
>// beginning of file
>
>import java.applet.Applet;
>import java.awt.BorderLayout;
>import java.awt.event.*;
>import java.awt.GraphicsConfiguration;
>import com.sun.j3d.utils.applet.MainFrame;
>//import com.sun.j3d.utils.geometry.ColorCube;
>import com.sun.j3d.utils.universe.*;
>import javax.media.j3d.*;
>import javax.vecmath.*;
>
>// an appearance class that sets all the attrubutes I believe are
>// necessary to render two sided shaded polygons
>class PCHAppearance extends Appearance{
> Color3f PATCH_COLOR = new Color3f(0.3f,0.3f,1.0f);
>
> public PCHAppearance(){
> PolygonAttributes polyatt = new PolygonAttributes();
> polyatt.setPolygonMode(PolygonAttributes.POLYGON_FILL);
> polyatt.setCullFace(polyatt.CULL_NONE);
> polyatt.setBackFaceNormalFlip(true);
> setPolygonAttributes(polyatt);
>
> RenderingAttributes ra = new RenderingAttributes();
> ra.setDepthBufferEnable(true);
> setRenderingAttributes(ra);
>
> ColoringAttributes c = new ColoringAttributes();
> c.setShadeModel(c.SHADE_FLAT);
> c.setColor(PATCH_COLOR);
> setColoringAttributes(c);
>
> setMaterial( new Material(PATCH_COLOR, new Color3f(0.1f, 0.1f, 0.1f),
>PATCH_COLOR, new Color3f(0.0f, 0.0f, 0.0f), 80.0f ));
> }
> }
>
>public class HelloUniverse extends Applet {
> static final int NUM_VERTS = 4;
>
> // Create the root of the branch graph
> public BranchGroup createSceneGraph() {
> BranchGroup objRoot = new BranchGroup();
> TransformGroup objTrans = new TransformGroup();
> objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
> objRoot.addChild(objTrans);
>
>//------------------------------------
> // Create a universal bounds for the light source, and behaviors
>influence
> BoundingSphere uniBounds = new BoundingSphere(new Point3d(0.0,0.0,0.0),
>10 );
>
> // Set up the global, ambient light
> Color3f alColor = new Color3f(0.2f, 0.2f, 0.2f);
> AmbientLight aLgt = new AmbientLight(alColor);
> aLgt.setInfluencingBounds(uniBounds);
> objRoot.addChild(aLgt);
>
> // Set up the directional (infinite) light source
> Color3f lColor1 = new Color3f(0.9f, 0.9f, 0.9f);
> Vector3f lDir1 = new Vector3f(-1.0f, 0.0f, 0.0f);
> DirectionalLight lgt1 = new DirectionalLight(lColor1, lDir1);
> lgt1.setInfluencingBounds(uniBounds);
> objRoot.addChild(lgt1);
>
> // Set up a Point light source
>// Color3f lColor1 = new Color3f(0.9f, 0.9f, 0.9f);
>// Vector3f lDir1 = new Vector3f(1.0f, 1.0f, -1.0f);
>// PointLight lgt1 = new PointLight(lColor1, new Point3f(5.0f, 0.0f,
>0.0f), new Point3f(1.0f, 0.0f, 0.0f) );
>// lgt1.setInfluencingBounds(uniBounds);
>// objRoot.addChild(lgt1);
>
>// ----------------------
> // This section creates a pair of TriangleStripArrays
> int[] strips = new int[1];
> strips[0] = NUM_VERTS;
> Point3f verts[] = new Point3f[NUM_VERTS];
> Vector3f norms[] = new Vector3f[NUM_VERTS];
>
> // set up patch 1
> TriangleStripArray p1 = new TriangleStripArray(NUM_VERTS,
>GeometryArray.COORDINATES | GeometryArray.NORMALS , strips);;
> for(int i = 0; i < NUM_VERTS; i++){
> verts[i] = new Point3f(0.0f, 0.0f, 0.0f);
> norms[i] = new Vector3f(1.0f, 0.0f, 0.0f);
> }
>
> verts[0] = new Point3f(0.0f, 0.5f, 0.0f);
> verts[1] = new Point3f(0.5f, 0.5f, 0.0f);
> verts[2] = new Point3f(0.0f, 0.0f, 0.0f);
> verts[3] = new Point3f(0.5f, 0.0f, 0.0f);
>
> for(int i = 0; i < NUM_VERTS; i++){
> norms[i] = new Vector3f(0.0f, 0.0f, 1.0f);
> }
>
> p1.setCoordinates(0,verts);
> p1.setNormals(0, norms);
>
> // set up patch 2 offset on the x axis with normals reversed
> TriangleStripArray p2 = new TriangleStripArray(NUM_VERTS,
>GeometryArray.COORDINATES | GeometryArray.NORMALS , strips);;
>
> verts[0] = new Point3f(-0.5f, 0.0f, 0.0f);
> verts[1] = new Point3f(0.0f, 0.0f, 0.0f);
> verts[2] = new Point3f(-0.5f, -0.5f, 0.0f);
> verts[3] = new Point3f(0.0f, -0.5f, 0.0f);
>
> for(int i = 0; i < NUM_VERTS; i++){
> norms[i] = new Vector3f(0.0f, 0.0f, -1.0f);
> }
>
> p2.setCoordinates(0,verts);
> p2.setNormals(0,norms);
>
>
>// create a pair of objects with Appearances
> objTrans.addChild(new Shape3D(p1, new PCHAppearance()));
> objTrans.addChild(new Shape3D(p2, new PCHAppearance()));
> // ------------------------------
>
>
> // Create rotation behavior
> Transform3D yAxis = new Transform3D();
> Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE,
> 0, 0,
> 4000, 0, 0,
> 0, 0, 0);
>
> RotationInterpolator rotator =
> new RotationInterpolator(rotationAlpha, objTrans, yAxis,
> 0.0f, (float) Math.PI*2.0f);
> BoundingSphere bounds =
> new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
> rotator.setSchedulingBounds(bounds);
> objTrans.addChild(rotator);
>
> // Have Java 3D perform optimizations on this scene graph.
> objRoot.compile();
>
> return objRoot;
> }
>
> public HelloUniverse() {
> setLayout(new BorderLayout());
> GraphicsConfiguration config =
> SimpleUniverse.getPreferredConfiguration();
>
> Canvas3D c = new Canvas3D(config);
> add("Center", c);
>
> // Create a simple scene and attach it to the virtual universe
> BranchGroup scene = createSceneGraph();
> SimpleUniverse u = new SimpleUniverse(c);
> u.getViewingPlatform().setNominalViewingTransform();
> u.addBranchGraph(scene);
> }
>
> // The following allows HelloUniverse to be run as an application
> // as well as an applet
> public static void main(String[] args) {
> new MainFrame(new HelloUniverse(), 256, 256);
> }
>}
>// end of file
>=====================================================================
>To subscribe/unsubscribe, send mail to [EMAIL PROTECTED]
>Java 3D Home Page: http://java.sun.com/products/java-media/3D/
>
=====================================================================
To subscribe/unsubscribe, send mail to [EMAIL PROTECTED]
Java 3D Home Page: http://java.sun.com/products/java-media/3D/