The node-counts given by "analyze" and PStats

In short, do the node-counts reported by a call to “analyze()” and by PStats reflect the total number of nodes in a scene (i.e. before culling) or the number of nodes being rendered (i.e. after culling)?

I’m trying to deal with a large amount of time being spent, as reported by PStats, in “garbageCollectStates”. And while this isn’t necessarily tied to the number of nodes present, I do also see that I have rather a lot of nodes reported by both PStats and “analyze”. I’m thus thinking that reducing the number of nodes might also reduce the number of states to be garbage-collected.

However, the numbers reported by PStats and “analyze” are surprisingly high, and so I’m wondering whether I’m not perhaps seeing the count for the full scene, even those parts out of view…

The node count reported by analyze() is the total number of nodes in the scene, ie. before culling.

The node count reported by PStats is the number of nodes visited by the cull traverser. If this number is higher than the number of nodes in view, you may have an excessively flat scene graph; if all your nodes are parented under render without any grouping, the cull traverser will still have to visit each node to determine whether it is view or not, rather than being able to visit a common group node and discard the whole group as being out of view.

Geoms and Batches is interesting to determine how many draw calls are actually making it to the GPU.

A lot of time spent in garbageCollectStates indicates that you have a lot of (changing) states, see:
https://docs.panda3d.org/1.10/cpp/optimization/performance-issues/too-many-state-changes

You may benefit from disabling the render state or transform cache, but it’s a trade-off.

Ah, interesting, and thank you!

Hmm, possibly… Most of my objects are parented beneath “room”-nodes, so there should be some hierarchy in place–but there is one class of nodes that I don’t think that I’m so parenting, which might be making things worse than they need be…

Hmm… Based on a quick test of a problem-location, I’m seeing about 162 Geoms, and about 550 Primitive batches.

Indeed. I was hoping that by simply reducing the number of nodes present, I would reduce the number of states, and thus the number of changes in state…

If not… then things get trickier! Finding a way to have more state be shared between nodes could be difficult, when there are various nodes having shaders and shader-inputs assigned, even if the shaders may be the same in some cases…

I actually tried this (via “loadPrcFileData”, passing in “state-cache 0” and “transform-cache 0” respectively), but found little benefit, funnily enough.

This is fine. It’s interesting that the primitive batch count is significantly higher than the geom count, though, so it might be worth it to examine why this is (a lot of separate GeomPrimitive objects that could be combined into one, perhaps).

In any case, it’s not going to explain a lot of time spent in garbageCollectStates.

You don’t reduce the number of states by reducing the number of nodes, nodes can also have an empty state which makes them not contribute to the state count.

You can examine the RenderState cache for yourself via various static RenderState methods and get an idea for why there are so many of them. Same for the TransformState cache.

Noted, and thank you.

Fair enough.

Well, my thinking was that I tend to have models with various elements of state applied–shaders, textures, etc.–and which might thus each produce separate states. Thus reducing nodes might, in such a case, reduce states.

But in all fairness, there are also various “intermediate” nodes that have no state–nodes just intended to aid in the transform being applied to an object, or the hierarchy of the scene, etc.

Ah, noted, and thank you–I’ll give that a look I intend!

[edit 3]
This is becoming a topic other than the original, so I’m splitting off the matter of RenderState counts and “garbageCollectStates” into a thread of its own…