When upgrading my osgEarth-based application from 2.8 to 3.0 I am having issues with some of my models. In the 2.8 version I placed all my models for vehicles into LocalGeometryNodes and everything worked fine. I didn't see how to do that with the newer API so I switched to using ModelNode. Unfortunately now the models do not look right. They look fine in osgViewer so I am assuming it is my usage of the ModelNode API. Here is what the differences look like. Any thoughts as to what I am missing?
I don't know if this will help in debugging but if I do the following the display issue goes away:
m_modelNode = new osgEarth::ModelNode(cfg, 0L);
The downside of doing that is the RTTPicker no longer works so I can't use this as a solution. I need the shader to do the object id-related stuff so the picker works but not whatever is changing the appearance of the model.
ModelNode, LocalGeometrynode, et al are really there to support the Annotation subsystem. If you don't need symbology, it would indeed be simpler and more straightforward to just use GeoTransform as in the osgearth_transform example.
Also, modes like GL_RESCALE_NORMAL and GL_LIGHTING are unnecessary since the osgEarth shader pipeline will take care of that stuff.
Thanks for the tip on GeoTransform. I have got that route that mostly working although my models still don't look right. For some reason it's only the models that were originally in FBX format that have this issue. Other models where I started out with OBJ or 3DS first before converting to IVE look fine.
After the mod to use GeoTransform I am doing almost nothing to manipulate the node for the model after it is read in from the file. Now I call readDB(), do an
to pass the data in to another class, and do m_node.accept() with the ShaderGenerator. It shows correctly in osgViewer so I will just have to trace through the code and see what's different about the various settings. I thought I remembered seeing something about the IVE format being deprecated now but if that was the issue it seems like it wouldn't display correctly in the viewer.
Right now I am only using symbology for the terrain clamping in the AltitudeSymbol. I have some older code that can do it via an osgEarth::TerrainCallback instead so I can migrate that to 3.0 if the classes it uses are still available.
Unfortunately I cannot share models since this is for proprietary work so I will have to debug it from my end. I did notice a difference when I turned the lighting for the sky layer on/off. If the sky lighting is on I can see the features of the model a little better. As an experiment I ran osgviewer and hit 'l' to turn off the lighting and got the same result that I see in my application. So lighting is definitely a factor.
I thought even without the sky layer there was some degree of ambient light that would illuminate the models. If I query the main view for some of its light parameters I get a lighting mode of HEADLIGHT and an ambient light of (0.0, 0.0, 0.0, 1.0). That's completely off, right? In earlier versions of my 2.8-based app I didn't have a sky layer and things still showed up. Maybe the defaults changed?
I figured out the issue so I will post the solution here in case anyone else runs into this problem. Previously in v2.8 I used LocalGeometryNode which inherits from GeoPositionNode. In the constructor for GeoPositionNode the init() function gets called. Inside GeoPositionNode::init() there is this line:
In v3.0 I used ModelNode which also inherits from GeoPositionNode. When the constructor for GeoPositionNode is invoked GeoPositionNode::construct() gets called since there is no longer a GeoPositionNode::init() in v3.0. GeoPositionNode::construct() is very similar to the older GeoPositionNode::init() but it does not have that setMode() call for GL_LIGHTING.
So instead I tried this:
m_modelNode = new osgEarth::ModelNode(mapNode, m_style);
Now the models look correct whether the lighting for the sky layer is on or off.
I am running into one issue with this solution. It worked yesterday evening but when I tried this morning it still exhibited the same behavior as before. As an experiment I tried adding an hours variable to the sky layer in the earth file instead of using the system clock. I set it to 20 since the object was in Japan. Once I did that the model appeared correctly.
If I have turned off the lighting for the sky node via:
why does changing the hour variable have an impact on whether or not I can see the model correctly? What is controlling the ambient light of the scene?
In both the 2.8 and 3.0 versions I have taken the sky layer out of the earth file. Is it true that in this case the only light that should be present is the light associated with the primary view? There are no osg::Light objects in the scene graph if I use a FindNodeVisitor from the root.
In the 2.8 version the model is illuminated but in the 3.0 version it is not. I am no longer turning off the GL_LIGHTING in the state set in the 3.0 version so that is not the issue. The ambient, diffuse, and specular components for the single light in the view are the same for both versions. The position and direction are also the same. In both versions the ShaderGenerator gets invoked when the model is loaded.
So is there another light I am unaware of that is acting on my model in the 2.8 version? Has there been a change to the shaders used that could potentially cause this?
I played around with the ModelNode constructor for a bit and this block in ModelNode.cpp is what makes the difference:
if (_shaderPolicy == SHADERPOLICY_GENERATE)
// generate shader code for the loaded model:
else if (_shaderPolicy == SHADERPOLICY_DISABLE)
osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE);
If the block for the 'generate' option is executed then my models do not appear correct unless the sky layer is on and my models happen to be in or near the sunlight portion of the globe.
If the block for the 'disable' block is executed then my model appears correct regardless of whether the sky layer is present or not. The only downside of this is that my RTTPicker no longer works because I guess the object ids don't get applied if you don't generate the shader.
How can I modify the shader such that the RTTPicker will still work but the appearance of my model will not change?