1.9.4 and Vertex Colours


#1

Given that I’m making my own build from the source, how easy would it be to back-port Panda3D 1.10’s handling of vertex colours–specifically, that a model lacking vertex colours is treated as having white vertex colours in shaders that attempt to access them–into Panda3D 1.9.4? How involved would it be, and where should I look for the relevant code?


#2

Not particularly difficult. The file in question is panda/src/glstuff/glShaderContext_src.cxx although it has changed quite a bit, so the surrounding code will look different.

Here are the relevant commits:

github.com/panda3d/panda3d/comm … ec00789a5a
github.com/panda3d/panda3d/comm … 3fbf789e42


#3

Ah, excellent, and thank you! That does indeed look pretty straightforward. :slight_smile:


#4

Hmm… I seem to have hit a snag:

I have a particular model that includes vertex colours. It worked as expected under the standard version of 1.9.4. Under my custom build, I seem to get white instead of the expected colours. Other objects seem to work as expected–although it’s possible that I’ve missed one or more that don’t.

Examination of the code and a quick experiment seem to indicate that the problem lies with the the first part of the “if”-statement below, from glShaderContext_src.cxx:

int num_elements, element_stride, divisor;
      bool normalized;
      if ((p != _color_attrib_index || color_attrib->get_color_type() == ColorAttrib::T_vertex) &&
          _glgsg->_data_reader->get_array_info(name, array_reader,
                                               num_values, numeric_type,
                                               normalized, start, stride, divisor,
num_elements, element_stride)) {

That is, if I remove “(p != _color_attrib_index || color_attrib->get_color_type() == ColorAttrib::T_vertex) &&” from the above, I seem to get vertex colours as expected.

Given this, where do you think that the problem lies? Am I perhaps missing some other piece of code that would set something in that “if”-statement correctly?

I note that the problematic section doesn’t seem to have been present in baseline 1.9.4; would it be safe to simply omit it in my build, do you think?


#5

Is this issue not there if you properly set ColorAttrib.make_vertex() ?

The point of the new vertex color handling is that the value of the color vertex attribute is now dependent on the ColorAttrib state.


#6

This particular model doesn’t use programmatically-assigned vertex colours, I believe–it’s just a model, loaded from an egg file, that happens to have such colours. Unless I should be calling “make_vertex()” for such models, too?

Could some other piece of code–such as activating transparency on the object, hiding it from a camera, or assigning a shader to it–be adding or changing a ColorAttrib in such a way that the code is tripping over those conditions?


#7

The egg loader automatically uses make_vertex() on any model that has vertex colors applied, unless all vertices have the same colour, in which case it uses a fixed color for the whole model using nodepath.set_color(). This shouldn’t make a difference in 1.10.

I don’t think any of the things you mentioned should modify the ColorAttrib. But you should be able to see this by inspecting the scene graph with ls().


#8

Here’s the output of “ls()”, called from within the game:

ModelRoot brassBowl.egg S:(ColorAttrib)
  GeomNode Circle.001 (1 geoms: S:(ColorAttrib CullBinAttrib MaterialAttrib TextureAttrib)) [noShadows shader transparency] S:(ColorBlendAttrib ShaderAttrib TransparencyAttrib) (per-camera hidden)
  GeomNode Circle (1 geoms: S:(MaterialAttrib TextureAttrib))

The first GeomNode, “Circle.001” is the one that’s showing the problem, I believe. I note that it reports a “ColorAttrib” (as does the parent node), although why this is so I’m not sure.

Oddly, while calling “getAttrib(ColorAttrib)” on the model-node returns a “ColorAttrib” (with the colour (1, 1, 1, 1)), doing so on either of its children returns None. o_0


#9

Thus far, omitting the above-mentioned condition seems to produce the expected results. Is there any reason that anyone sees to put it back? Might it impact performance, for example?


#10

Did you at all call setColor on the node, or something like that? If you do, a ColorAttrib with a flat color gets assigned (as you are noticing), which may be overriding the ColorAttrib.make_vertex() and causing the vertex colors to get overridden by the constant color.

getAttrib() by default returns the attribute set on that node; use getNetState().getAttrib() to get the effective ColorAttrib on that node including the effects of any ColorAttrib assigned to higher nodes.


#11

Ah, you’re right! While my initial searching of the code didn’t turn up anything, a more careful hunt revealed that I had a forgotten method that was assigning a colour to the actor! A little more testing suggests that I’m not actually using this functionality in the game as it stands, so I’ve removed it.

I feel silly for having missed that–thank you for prompting me to check again! ^^;

I’ve rebuilt the SDK with the condition back in place, and it does indeed seem that removing the above function solves the problem. Thank you very much for your help! :slight_smile: