Re: Can't Get Lighting to Work in Ardor3D
Posted by hedgehog on Mar 21, 2014; 4:14pm
URL: https://forum.jogamp.org/Can-t-Get-Lighting-to-Work-in-Ardor3D-tp4031971p4032026.html
Thanks for your replies.
If you look closely at the GridExample you will see that the vertex normals were computed.
I've re-jigged ManyLightsExample2 by adding the outward normals, and as expected it makes no difference. The spheres are still grey as the white lights pass by. So, it must be something else.
Indeed, if you look at com.ardor3d.scenegraph.shape.Sphere you'll see that the normals are computed for the stock Sphere object. However, there is no default assignment/building of the colour buffer. Thus, in theory the sphere normals shouldn't need to be generated a 2nd time.
***Spheres with outward normals***
import java.util.Random;
import com.ardor3d.bounding.BoundingSphere;
import com.ardor3d.example.ExampleBase;
import com.ardor3d.light.PointLight;
import com.ardor3d.math.ColorRGBA;
import com.ardor3d.math.MathUtils;
import com.ardor3d.math.Vector3;
import com.ardor3d.scenegraph.MeshData;
import com.ardor3d.scenegraph.Node;
import com.ardor3d.scenegraph.Spatial;
import com.ardor3d.scenegraph.controller.SpatialController;
import com.ardor3d.scenegraph.hint.LightCombineMode;
import com.ardor3d.scenegraph.shape.Sphere;
import com.ardor3d.util.ReadOnlyTimer;
import com.ardor3d.util.geom.BufferUtils;
/**
* A demonstration of randomly placed spheres being illuminated by numerious PointLight sources.
*/
public class ManyLightsExample2 extends ExampleBase {
private final Random rand = new Random();
private Node colornode;
private final double worldsize = 20;
public static void main(final String[] args) {
start(ManyLightsExample2.class);
}
@Override
protected void updateExample(final ReadOnlyTimer timer) {
_root.sortLights();
}
/**
* Create a randomly positioned light and lightsphere with a controller
*
* @param i
* Index of the light
*/
void randomLight(final int i) {
// Chose the color for the lights.
//final ColorRGBA lightColor = ColorRGBA.randomColor(new ColorRGBA());
final ColorRGBA lightColor = new ColorRGBA(1,1,1,1);
// Create a sphere to show where the light is in the demo.
final Sphere lightSphere = new Sphere("lightSphere" + i, 9, 9, .1f);
lightSphere.setModelBound(new BoundingSphere());
lightSphere.getSceneHints().setLightCombineMode(LightCombineMode.Off);
lightSphere.setDefaultColor(lightColor);
// Create a new point light and fill out the properties
final PointLight pointLight = new PointLight();
pointLight.setAttenuate(true);
pointLight.setConstant(.01f);
//pointLight.setConstant(.1f);
pointLight.setLinear(.001f);
pointLight.setQuadratic(.1f);
pointLight.setEnabled(true);
pointLight.setDiffuse(lightColor);
pointLight.setAmbient(new ColorRGBA(.1f, .1f, .1f, .1f));
//pointLight.setAmbient(new ColorRGBA(.9f, .9f, .9f, 1f));
_lightState.attach(pointLight);
lightSphere.addController(new SpatialController<Spatial>() {
double timeX = rand.nextDouble() * Math.PI * 8;
double timeY = rand.nextDouble() * Math.PI * 8;
double timeZ = rand.nextDouble() * Math.PI * 8;
double speed = MathUtils.nextRandomDouble();
public void update(final double tpf, final Spatial caller) {
timeX += tpf * speed;
timeY += tpf * speed;
timeZ += tpf * speed;
final double xPos = Math.sin(timeX * 0.4) * worldsize;
final double yPos = Math.cos(timeY * 0.5) * worldsize;
final double zPos = Math.sin(timeZ * 0.6) * worldsize;
caller.setTranslation(xPos, yPos, zPos);
pointLight.setLocation(xPos, yPos, zPos);
}
});
// Add the light to the world part 2.
colornode.attachChild(lightSphere);
}
/**
* Create a random sphere to be affected by the light
*
* @param i
* Index of the sphere
*/
void randomSphere(final int i) {
// Crate a sphere and position it.
final Sphere sphere = new Sphere("sphere" + i, 18, 18, MathUtils.nextRandomDouble() * 1.75 + 1.25);
sphere.updateModelBound();
sphere.setTranslation(new Vector3(rand.nextDouble() * worldsize * 2 - worldsize, rand.nextDouble() * worldsize
* 2 - worldsize, rand.nextDouble() * worldsize * 2 - worldsize));
Vector3 sphereCentre = sphere.getCenter();
ColorRGBA sphereColour = new ColorRGBA(1,0,0,1);
MeshData meshData = sphere.getMeshData();
int numberVertices = meshData.getVertexCount();
meshData.setColorBuffer(BufferUtils.createColorBuffer(numberVertices));
meshData.setNormalBuffer(BufferUtils.createFloatBuffer(3*numberVertices));
for (int index=0; index<numberVertices; index++)
{
double vx = meshData.getVertexBuffer().get(3*i+0);
double vy = meshData.getVertexBuffer().get(3*i+1);
double vz = meshData.getVertexBuffer().get(3*i+2);
Vector3 v = new Vector3(vx,vy,vz);
Vector3 outwardNormal = v.subtract(sphereCentre, null);
outwardNormal = outwardNormal.normalize(null);
float red = sphereColour.getRed();
float green = sphereColour.getGreen();
float blue = sphereColour.getBlue();
float alpha = sphereColour.getAlpha();
meshData.getColorBuffer().put(red).put(green).put(blue).put(alpha); // note *4 indexing into buffer
meshData.getNormalBuffer().put(outwardNormal.getXf()).put(outwardNormal.getYf()).put(outwardNormal.getZf());
}
meshData.getColorBuffer().rewind();
_root.attachChild(sphere);
}
@Override
protected void initExample() {
_lightState.detachAll();
_lightState.setTwoSidedLighting(true);
_lightState.setLocalViewer(true);
rand.setSeed(1337);
// Now add all the lights.
colornode = new Node("LightNode");
for (int i = 0; i < 40; i++) {
randomLight(i);
}
// Add the spheres.
for (int i = 0; i < 30; i++) {
randomSphere(i);
}
_root.attachChild(colornode);
}
}