Dynamic face colour adjustment

I’m trying to dynamically adjust a single side of a mesh’s face colour. The reason for this is I don’t want to regenerate the whole mesh. Most of my modelling/mesh adjustment technique has been to modify the base values (mostly vertices) of elements by tweening them for nice animations.

Now that I have a need to adjust the face colour I hit a bit of a snag. I’ve developing a picture frame that has dynamic details you can customise. In this case the user should be able to modify the bevel colour of a “mat” element:

The black stroke is the bevel element. The mesh itself is generated from an ExtrudedPolygon:

const horizontalStick = MeshBuilder.ExtrudePolygon('HS1', {
  shape: standardShape,
  depth: this.matDepth,
  faceUV,
  faceColors
});

My face colours are generated like so:

[
    new Color4(1, 1, 1, 1),
    colour == null ?
    new Color4(0.75, 0.75, 0.75, 0.1) :
    Color4.FromHexString(colour),
    new Color4(1, 1, 1, 1)
]

This works well. Now when I want to dynamically adjust the colour, according to the docs I have to grab the vertice’s data, adjust it then re-set it:

let positions = mat.getVerticesData(VBuffer.ColorKind);
... (adjust the values here)...
mat.getVerticesData(VBuffer.ColorKind, positions)

When I log the positions I get a buffer of values:

[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

I’m assuming that’s a buffer representation of the face colours. I suspect I have to find the position that represents the black part of my frame (likely the 1’s in the buffer) and replace them with rgb values of my new colour?

The question is what positions within this buffer do I need to modify? Is there a more efficient way of doing this?

you could go thru all the vertex colors in sets of 3, when you find they are the numbers of the color you are looking for, replace them, then update vertex values to get them to gpu.

This way does not require you to deal the indexed way AR stored

Yup, that was the assumption I was making. I tried to splice out the values but the real question is where’s the documentation that outlines the structure of the buffer as it relates to the mesh? ie. what’s the positional mapping? Just from the example above I assumed my faces existed where all the 1’s were but when I replace them it seems that I’m not correct.

Note that black is (0,0,0) ((1,1,1) = White).

Maybe a PG would help?

Specific structure depends on how the mesh was constructed. General info

https://doc.babylonjs.com/How_To/Custom

@Evgeni_Popov yup, right still not used to the 0 to 1 representation of RGBA. Sigh. Didn’t need to use a PG afterall.

@JohnK that did it. Thanks. Had to understand the EP value. In the end it was a 92 length array, so the values after the 32nd position in blocks of 4 (Color4) represented my colour. The documentation suggestion for replacing colour was confusing me. I likely just misread it (Update Vertices - Babylon.js Documentation).

For any future folk reading this, here was the solution as simple as:

for(var p = 0; p < positions.length; p += 4) {
  if (p > 32) {
    positions.splice(p, 4, c3.r, c3.g, c3.b, 1);
    positions2.splice(p, 4, c3.r, c3.g, c3.b, 1);
  }
}

At first I was cursing the Vector Buffer but now that I know the structure I’m appreciating it a lot more. Makes tweening the values with my GSAP Timeline much, much easier.

Thanks yet again!