I am working on the ability to have more then 8 lights inside a light state. To do this the state will have to fined the 8 lights that are most visible and display the. To do this inside update the apply function needs to have the spatal it is aplying to as a parameter. I will also need to add a method inside light that returns a nuber corresponding to it’s affect on a spatial. If less then 8 light are used then there should be little effect on the performance. Are these mortifications ok with you?
If you have any secessions I would be happy to hear them. If you know of any articles about the opengl lighting motel please tell me. I know anofe to do the modifications but more information would be nice.
Why is the AmbientLight of the scene stored in a child of light and not a property of LightState? Using it as a light limits you to only 7 lights active at a time if you use AmbientLight. Can I change this method when I am doing my updates to the lighting system?
I don’t understand what you are doing Badmi? 8 lights (at a given moment in time) is an OpenGL limit. In JME you can create and put as many lights in a scene as you want (using multiple lightstates) and have different objects be affected by different lights. What is it you are trying to accomplish that is different?
I am making a system that lets you give a light state more then 8 lights then the light state will automatically find the one that will be best for the spatial and use them. This is helpful if you have a large seean and many lights. You only have to make one lightstate for the root and JME will automatically sort the sean each frame. Doing this yourself in a game would be hard because you would have to redo the lighting manually each time something moves. So far the system works well with a large number of lights and with a good frame rate. I am sorry if I was not clear.
To summaries you only would have to give jme one list of lights for a large seean and jme would do the rest.
If you want I can post a picture.
I don’t think this is an efficient system Badmi. You should be required to set lights spatial by node. Dumping them into the root node is not how a user should handle his lighting sytem. Lights are physical objects that affect other physical object’s appearance. They have physical locations, therefore, they should be set up in the scene graph as such.
Right, it defeats the whole point of having a scenegraph… Perhaps a utility would be a better format for what you are trying to write?
Putting them inside the node would give problems if the lights move. You can put the light nodes inside the spiral but it is better to put the lights in the root or close to it. The light node would be able to move like a object. If I used a utility it would be slower then the system I have now. I get 30 fps with this example in a obsolete computer.
Hear is the test program I am using, lights move like you want:
public class TestMoreThenMaxLight extends SimpleGame{
boolean fowerd;
float dist;
SimpleLightNode ln;
SimpleLightNode ln2;
PointLight pl;
PointLight p2;
Sphere sp1;
Node colornode;
final static float worldsize=60;
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
TestMoreThenMaxLight app = new TestMoreThenMaxLight();
app.setDialogBehaviour(ALWAYS_SHOW_PROPS_DIALOG);
app.start();
}
protected void simpleUpdate() {
if(super.input.getKeyBindingManager().isValidCommand("StopMoving",false))
{
deactivate(rootNode);
}
}
void deactivate(com.jme.scene.Spatial s)
{
for(int i=0;i<s.getControllers().size();i++)
s.getController(i).setActive(!s.getController(i).isActive());
if(s instanceof Node)
{
Node n=(Node)s;
for(int i=0;i<n.getQuantity();i++)
deactivate(n.getChild(i));
}
}
void randomLight(int i)
{
ColorRGBA mc=ColorRGBA.randomColor();
Sphere sp2=new Sphere("lp"+i,10,10,.1f);
sp2.setModelBound(new BoundingSphere());
sp2.updateModelBound();
sp2.setLightCombineMode(com.jme.scene.state.LightState.OFF);
sp2.setSolidColor(mc);
pl=new PointLight();
pl.setAttenuate(true);
pl.setConstant(/*FastMath.rand.nextFloat()*/.1f);
pl.setLinear(/*FastMath.rand.nextFloat()**/.1f);
pl.setQuadratic(/*FastMath.rand.nextFloat()*/.1f);
pl.setEnabled(true);
pl.setDiffuse(mc);
//pl.setSpecular(mc);
pl.setAmbient(new com.jme.renderer.ColorRGBA(.1f,.1f,.1f,.1f));
// this.lightState.detachAll();
this.lightState.attach(pl);
Node mnod=new Node("P"+i+" Light pos");
ln =new SimpleLightNode("ln"+i,pl);
//ln.setLocalTranslation(new Vector3f(FastMath.rand.nextFloat()*worldsize*2-worldsize,FastMath.rand.nextFloat()*worldsize*2-worldsize,FastMath.rand.nextFloat()*worldsize*2-worldsize));
mnod.attachChild(sp2);
SpatialTransformer st=new SpatialTransformer(1);
// I tell my spatial controller to change pivot
st.setObject(mnod,0,-1);
int num=FastMath.rand.nextInt(10)+1;
for(int inom=0;inom<num;inom++)
{
st.setPosition(0,inom*4,new Vector3f(FastMath.rand.nextFloat()*worldsize*2-worldsize,FastMath.rand.nextFloat()*worldsize*2-worldsize,FastMath.rand.nextFloat()*worldsize*2-worldsize));
}
st.setRepeatType(st.RT_CYCLE);
// Prepare my controller to start moving around
st.interpolateMissing();
// Tell my pivot it is controlled by st
mnod.addController(st);
mnod.attachChild(ln);
colornode.attachChild(mnod);
}
void randomeSphear(int i)
{
sp1=new Sphere("sp"+i,10,10,1);
sp1.setModelBound(new BoundingSphere());
sp1.updateModelBound();
sp1.setLocalTranslation(new Vector3f(FastMath.rand.nextFloat()*worldsize*2-worldsize,FastMath.rand.nextFloat()*worldsize*2-worldsize,FastMath.rand.nextFloat()*worldsize*2-worldsize));
rootNode.attachChild(sp1);
}
protected void simpleInitGame() {
this.lightState.detachAll();
colornode=new Node("LightNode");
for(int i=0;i<60;i++)
{
this.randomLight(i);
}
for(int i=0;i<80;i++)
{
this.randomeSphear(i);
}
LightState nl=com.jme.system.DisplaySystem.getDisplaySystem().getRenderer().createLightState();
nl.setEnabled(false);
colornode.setRenderState(nl);
rootNode.attachChild(colornode);
super.input.getKeyBindingManager().set("StopMoving",com.jme.input.KeyInput.KEY_P);
}
}
Also there is no mandatory change to the interface or speed so you can use it as you want.
Lights can move. Take a look at LightNode.
Lets say you have a man walking around a world with many lights. As he moves form one area to another he will need to be lit by different lights. If the lights move then we have the same problem. As one of the lights get closer to the man and another gets farther then, with the curing system, one must be removed from the state and the other must be added. With my system all you have to do is add all the lights to one state and let JME do the rest, you do not have to were about witch one of the 8 lights the man is closer to.
You are right, you have to do a little bit of work. You have to setTarget and remove as something moves through the scene. But it’s a price you pay working with a scene graph. Placing lights in the root node requires all lights be processed seperately from the nodes they affect, creating an efficiency problem. Currently, only those lights that affect visible things are processed in anyway.
Currently, there is no means to easily move scene nodes around the graph (including lights), so a system that attached/detached automatically would be a better way to go.
My system is very fast. I was suppressed by how little the fps dropped when I added 52 lights. Only around 3-5 fps. And this is with 10-30 spatials on a slow computer.
Even so, attaching a light to root just makes no sense in a scene graph perspective. If I have a fire in a room that is casting a light, I’d attach the light to the fire node. Not to the world node.
I still maintain there is a better way to handle the issue. Especially where the issue you are referring to is greater than just lights. Moving a node in the scene graph is not handled currently. The lights are a subset of this issue, so solving the issue as a whole would take care of the lights.
You do not have to attach all the lights on to a root node with my code. All my code dose is fined the best lights inside a state and uses them, it is up to the programer to decide how to use it. My example of attaching all the lights to a root node is one simple way of using my code. You will be able to use the light node in the may way as you can now but the limit of only having 8 lights will be removed.
Right, you would have to manually use setTarget when a node moves into an area that is affected by lights. But there are also many other things that have to be considered when moving nodes. That’s what I am trying to get at. This can be solved by a controller that handles node switching. You have to detach/attach children, lights, etc. So all this can be handled from a central location.
I agree that the situation needs to be taken care of, I just think there is a better way to do it and a way that will handle everything for a moving node.
Just curious, what other things are there? Light and fog are 2. I can’t think of any others off the top of my head though for a Spatial that moves around the world. Both of those would be distance type things. When you’re 100ft from where that light or fog is at, it affects you.
Well, I was thinking more of the lines of if I move a node I have to:
- detach it from my parent.
- attach it to the new parent.
- reset renderstates that were inherited to default.
- set texture states (due to merging down the tree)
- set light states (due to merging down the tree)
- update scene graph (new boundings for nodes)
- update all renderstates to obtain ancestors states.
That seems like overkill for what he wants, and isn’t really what’s going on. The SimpleLightNode stays where it is because the “fire’s light” doens’t move. It’s the “Light” object that needs to be moved to the correct LightStates.
Or rather, don’t go through all the trouble of detaching and reattaching a lightnode somewhere. Just move the "Light"s around.