flattenStrong() darkens models.

Hi to all,

As the subject says, calling flattenstrong() on a nodePath makes it darker in appearance than it was before. The below screenshot should show what I mean:


The models are all procedurally generated [aesthetics suck, cause I’m just testing functionality… ], and the ones labeled “incorrect” are the darkened ones, whereas the ones labeled “correct” are okay. Here is the code I use to flatten:

root_node=render.attachNewNode("root_node")
copy_noda=vaki.copyTo(root_node)
root_node.clearModelNodes()#<-for loaded models, not for the procedural ones.
root_node.flattenStrong()

I get a series of nodepaths with the same texture and then parent them to “root_node”. Then after that, I flatten the “root_node”. But after that, the now flattened “root_node” is darkened. Any ideas as to why this is happening?

Thanks.

I noticed that, if I scale the models up before parenting them to “root_node” and then flattening them, that the darkening effect is less pronounced…

Check the length of the vertex normals after flattening:

vertex_data = my_model.node().getGeom(0).getVertexData()
normal_reader = GeomVertexReader(vertex_data, "normal")
normal_length = normal_reader.getData3f().length()

This looks suspiciously like the bug I once reported for a Panda version prior to 1.9.1, where flattening a scaled model would lead to vertex normals being scaled instead of being normalized. If a model was scaled down before flattening it, the vertex normals (which affect how the model is lit) would end up being shorter than unit-length, hence the darker appearance of the model.

This bug was fixed in version 1.9.1, so perhaps you are using an older version?

Hello, thanks for the reply.

Well calling getGeom() on “root_node” yielded an attribute error:

  File "g_S.py", line 433, in cluster_instancer
    vertex_data = root_node.node().getGeom(0).getVertexData()
AttributeError: 'panda3d.core.PandaNode' object has no attribute 'getGeom'

I suppose because of this:

root_node=render.attachNewNode('root_node')

and then re-parenting the actual procedural models onto it before flattening it. But calling flattenStrong() on an individual procedural model without re-parenting it, and then comparing the normal lengths, before and after shows this:

NORMAL LENGTH BEFORE FLATTENING:  0.999999970198
NORMAL LENGTH AFTER FLATTENING:  0.0300000133241

So the length becomes shorter after flattening. I really don’t know what to make of it though, or what to do with this information to fix the darkening. I am actually using version 1.10 [this one specifically I think: 2015-12-31T20:08:11Z - Add normal/depth information to box-box test to make it work with the pusher ].

Hmm, I can’t seem to reproduce the issue, either with a loaded smiley model or with a procedurally created cube, with that particular Panda version installed.

It might be worthwile to try and generate a very basic model (e.g. consisting of just a single box without anything else attached to it, like children or collision geometry) that has this issue. Then you could write it out to .bam (using NodePath.writeBamFile) and upload it so I can take a look at it.

Okay, I’ve uploaded the flattened and unflattened versions of the same model within the zipped folder.
cube_bams.zip (1.99 KB)

I presume that a flattenLight() is enough to make the issue appear?

You presume correctly.

And I’ve found the cause :slight_smile: ! After some digging, it turned out that a custom GeomVertexFormat is the culprit.
It consists of 2 arrays; the first one has “vertex”, “normal” and “color” columns, while the second one has only a “texcoord” column.
If you change the vertex format of the GeomVertexData to the standard GeomVertexFormat.getV3n3cpt2(), the vertex normals are correctly normalized.

@Game_Starter: so for the time being you can solve the problem by doing:

vertex_format = GeomVertexFormat.getV3n3cpt2()
my_model.node().modifyGeom(0).modifyVertexData().setFormat(vertex_format)

(where “my_model” is a procedural model) or simply use that format when you create the models, of course.

In order to get scales correctly applied during flattens, you need to have your normal columns set to CNormal (and not CPoint or CVector) in the GeomVertexFormat. The default columns are configured correctly.

Thanks for both responses. Yes setting the normal columns like so:

array.addColumn(InternalName.make('normal'), 3,Geom.NTFloat32, Geom.CNormal)

Did fix the darkening issue. I, as always, appreciate the swift response and help! :smiley: