md5reader2 Lighting

Hi,



I’m using a collada-based level with my characters as md5 models (using the md5reader2 cvs code). The level works fine, but the models have very broken lighting.

It seems that the lighting is somehow inverted (from the bottom when the light is on the top and vice-versa), and doesn’t change when the model changes its local rotation. I’m using a single spotlight for testing right now.

I’ve enabled normalizing the normals, but that didn’t change anything.

You can see the problem in my other thread.



Does anybody have an idea what I could do to fix that problem?

Perhaps the normals are inverted, that is a fairly common problem with importers/exporters. Try pressing 'n' if you are using SimpleGame yo see the normals.

Since the marine model also shows this behavior (see the link to my other posting), I don't think the model is the problem…

I tried to move around a newly created ligth in the MarineTest.java example and I got nothing unespected. Maybe there is something to tune corretcly in your project. Try to verify your scenegraph hierarchy.



The new org.md5reader2.util.AxisLines class can be useful to debug lights positions.

Have you ever tried using md5reader2 with a shadow render pass? Maybe the problem comes from that one…



The problem is that as the app becomes more complex, more and more things (or combinations of multiple) could cause a certain behavior…

I am trying now to set up a SimplePassGame based on mixing MarineTest.java and TestShadowPass.java (of the jME test package). Till now the only problem I got is that I am not able to show on the scene a Box I made as a test floor.



The application continues to output this problem.



20-feb-2008 10.40.51 com.jme.renderer.lwjgl.LWJGLRenderer draw
GRAVE: missing indices on geometry object: The floor shape 2: Batch 0



But the Marine still renders correctly.

Unfortunatelly I don't know what is actually needed to setup a ShadoPass based scene in jME.

EDIT: ok I have been able to setup everithing with the MarineTest.java and now subclassing on SimplePassGame class. The Marine model does not give any problem. The light casts in the correct direction and the marine is illuminated correctly.

Please controll your setup.

Thanks for checking this! Since I suspected my field of view render pass, I removed it, but that still doesn't fix the lighting…



I'm kinda running out of ideas on what to remove… I'm using a point light, maybe that could cause problems? I'll try to remove the whole collada file and try to generate some geometry programatically to replace it.

Collada? Which model is loaded using Collada?



Though, the approach I use to debug it have been to disable every element (every Node, Geometry and Light) comment out code and then enableing elements one by one, and running the application each time you enable a new element to see what happens. Also jME logging can help understanding.

Ender said:

Collada? Which model is loaded using Collada?


The whole map is loaded from a collada file, the models are md5. The map lighting is perfect, the md5 lighting is totally broken...

Ok, I think I know what happens, but not why: The lighting position is set in object space, not in eye space or world space. My object is scaled way down, so for lighting calculations for the model, the whole scene is between the two feet of the model, including the point light. For the collada scene it doesn't matter, because the light is in the same space as the whole scene.



Since glLight(GL_POSITION) multiplies the current modelview matrix with the parameter and then stores the position in eye space, I guess the modelview matrix is simply the wrong one at the time this call happens every frame.



This looks more like a bug in jme than my code, but I can't quite believe that such a bug would go unnoticed…



EDIT: I found the problem & fixed it! The cause was that I was using the eye linear texture coordinate generation mode for my shadow mapping implementation. However, this is broken in jme, since this state has to be applied after the object matrix is loaded, but it is done in world space. Thus, I switched this around in the renderer. What I didn't think about is that the light state needs the world space. So I reverted to the original (with broken texture coordinate generation) way, and now the lighting works fine.



This is a jme bug after all. You can't apply all states at once, since not all of them need the same modelview matrix. Maybe something to tackle on for 2.0?

Edit: Wow! You posted your fix just a second before i post this one… :smiley:


anlumo said:
Ok, I think I know what happens, but not why: The lighting position is set in object space, not in eye space or world space. My object is scaled way down, so for lighting calculations for the model, the whole scene is between the two feet of the model, including the point light. For the collada scene it doesn't matter, because the light is in the same space as the whole scene.


Do you mean that your marine model is in another branch of the scenegraph? If so, why do not you simply move it to the right one?

If not, consider one thing: scaling/stretching is never a good choice. I am not sure on how jME manages scaling, but in Blender, for example, if you scale/stretch a parent object you can see odd children behaviors.
Then, you could try to detach your light from your object Node's LightState, and attach it to rootNode's LightState.

anlumo said:
Since glLight(GL_POSITION) multiplies the current modelview matrix with the parameter and then stores the position in eye space, I guess the modelview matrix is simply the wrong one at the time this call happens every frame.


Everything is possible, though this part is still quite far from my knowledges. I still have a poorly knew OpenGL specification. For example I still do not know well how OpenGL manages matrix data. I also saw that OpenGL offers something like a limited stack of matrices available for computations; but I have still not investigated how they actualy have to be used. Though is an approach quite different from the tipical CPU based computations. Moreover I still do not know well how OpenGL manages system coordinates and if it is aware of local space, object space or world space. So I cannot be helpful in this considerations.
Though, consider the possibility that the bug were LWJGL but not jME.

Glad you figured out the lighting "bug". :slight_smile:



Maybe you could elaborate more on the texture coordinate generation needs?  We've used eye linear without issues for a number of techniques.  Perhaps a code sample showing the problem?

renanse said:

Maybe you could elaborate more on the texture coordinate generation needs?  We've used eye linear without issues for a number of techniques.  Perhaps a code sample showing the problem?


A code sample is a bit complicated, since I used this for generating the texture coordinates in my shadow mapping implementation (and failed). My final code doesn't use the state functionality any more and just sets the eye planes itself:
[pre]
matRecord.switchMode(GL11.GL_MODELVIEW);
GL11.glPushMatrix();
((LWJGLCamera)DisplaySystem.getDisplaySystem().getRenderer().getCamera()).doFrameChange(); // ensure that the modelview matrix only contains the view matrix

GL11.glTexGeni(GL11.GL_S, GL11.GL_TEXTURE_GEN_MODE, GL11.GL_EYE_LINEAR);
GL11.glEnable(GL11.GL_TEXTURE_GEN_S);
GL11.glTexGeni(GL11.GL_T, GL11.GL_TEXTURE_GEN_MODE, GL11.GL_EYE_LINEAR);
GL11.glEnable(GL11.GL_TEXTURE_GEN_T);
GL11.glTexGeni(GL11.GL_R, GL11.GL_TEXTURE_GEN_MODE, GL11.GL_EYE_LINEAR);
GL11.glEnable(GL11.GL_TEXTURE_GEN_R);
GL11.glTexGeni(GL11.GL_Q, GL11.GL_TEXTURE_GEN_MODE, GL11.GL_EYE_LINEAR);
GL11.glEnable(GL11.GL_TEXTURE_GEN_Q);
projectionMatrix.fillFloatBuffer(eyePlane);
GL11.glTexGen(GL11.GL_S, GL11.GL_EYE_PLANE, eyePlane);
eyePlane.position(4);
GL11.glTexGen(GL11.GL_T, GL11.GL_EYE_PLANE, eyePlane);
eyePlane.position(8);
GL11.glTexGen(GL11.GL_R, GL11.GL_EYE_PLANE, eyePlane);
eyePlane.position(12);
GL11.glTexGen(GL11.GL_Q, GL11.GL_EYE_PLANE, eyePlane);
[/pre]

Take a look at the OpenGL manpage, and search for "If the texture generation function is GL_EYE_LINEAR". Compare that formula with the one required for shadow mapping and projective texturing, for example in this tutorial.