# Node material instance U, V offset and color?

**URL:** <https://forum.babylonjs.com/t/node-material-instance-u-v-offset-and-color/40783>\
**Category:** Questions\
**Tags:** material, nme, instances, nodematerial\
**Created:** [May 14, 2023, 6:22am UTC](https://forum.babylonjs.com/t/node-material-instance-u-v-offset-and-color/40783 "2023-05-14T06:22:36Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![inteja](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/inteja/32/22553_2.png) [@inteja](https://forum.babylonjs.com/u/inteja)\
**Post date:** [May 14, 2023, 6:22am UTC](https://forum.babylonjs.com/t/node-material-instance-u-v-offset-and-color/40783/1 "2023-05-14T06:22:36Z")

</div>

Hi @PatrickRyan

In relation to your great article [Creating Variations in Instances Using Node Materials](https://babylonjs.medium.com/creating-variations-in-instances-using-node-materials-eb96f4053a54), I’m wanting to have different UVs or UV offsets per instance, but also different colors per instance, which I’ll blend with a texture.

I’m confused by the use of `mesh.color` as I thought that was for vertex color, whereas `mesh.instanceColor` is what I thought I’d have to use?

If I wanted unique U and V offsets, and colors per instance, can this be achieved with node material?

I’m basically trying to achieve a similar result to this PG, but using `NodeMaterial` instead.

> **[Babylon.js Playground](https://www.babylonjs-playground.com/#64K1I1%237)**
>
> Babylon.js playground is a live editor for Babylon.js WebGL 3D scenes

---

<div class="post-metadata">

**Author:** ![inteja](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/inteja/32/22553_2.png) [@inteja](https://forum.babylonjs.com/u/inteja)\
**Post date:** [May 14, 2023, 6:27am UTC](https://forum.babylonjs.com/t/node-material-instance-u-v-offset-and-color/40783/2 "2023-05-14T06:27:18Z")

</div>

For context, what I’m trying to do is create a virtual keyboard where each keycap is an `InstancedMesh` with a single `NodeMaterial` that allows individual keycap color change and UV offsets to determine which legend/glyph is displayed on top of the keycap.

---

<div class="post-metadata">

**Author:** ![inteja](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/inteja/32/22553_2.png) [@inteja](https://forum.babylonjs.com/u/inteja)\
**Post date:** [May 15, 2023, 7:24am UTC](https://forum.babylonjs.com/t/node-material-instance-u-v-offset-and-color/40783/3 "2023-05-15T07:24:17Z")

</div>

I’m not sure if it’s the “right” way to do it, but following your article @PatrickRyan I was able to use a `Color4` (which I’ll change to mesh `InstanceColor` or `Color`), split that with a `VectorSplitter`, use `x` and `y` for the UV offsets and `z=1` or `z=0` to select between 2 different user-defined colors for instanced keycaps on a single themed keyboard, like this:

 ![image](https://us1.discourse-cdn.com/flex024/uploads/babylonjs/original/3X/a/2/a21e89bbecdfbbe7d04725e9caff8aa1a712e1d6.png)

I only have the 2 keycap colors per keyboard theme, so it seems to work.

Am I on the right track or is there an even better way?

---

<div class="post-metadata">

**Author:** ![sebavan](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/sebavan/32/57_2.png) [@sebavan](https://forum.babylonjs.com/u/sebavan)\
**Post date:** [May 15, 2023, 2:55pm UTC](https://forum.babylonjs.com/t/node-material-instance-u-v-offset-and-color/40783/4 "2023-05-15T14:55:18Z")

</div>

cc @Evgeni_Popov who can help on this.

---

<div class="post-metadata">

**Author:** ![PatrickRyan](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/patrickryan/32/3417_2.png) [@PatrickRyan](https://forum.babylonjs.com/u/PatrickRyan)\
**Post date:** [May 15, 2023, 5:19pm UTC](https://forum.babylonjs.com/t/node-material-instance-u-v-offset-and-color/40783/5 "2023-05-15T17:19:09Z")

</div>

@inteja, the reason I am using `mesh.color` in the example is because I created all of my random values with `instance.instancedBuffers.color` which would be accessed with `mesh.color`. Basically, I am creating an array of values, one color set for each instance, and then the node material is accessing the correct color value set based on the instance’s position in the buffer.

You could do something similar and instead of creating an instanced buffer of random values, you could assign one of the two user-defined colors to each instance. Then you would access them in the same way and you would have control over which instance receives which color. The trick here is that you need to store the colors of the individual instances somewhere to render them correctly, and the `instancedBuffers.color` is a good place to do so. You can then use the color from the buffer as your albedo/base color for the individual key cap, or you can multiply it with a greyscale texture value if you need to add variation in the key cap color.

I hope this makes sense, but please let me know if you have more questions.

---

<div class="post-metadata">

**Author:** ![inteja](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/inteja/32/22553_2.png) [@inteja](https://forum.babylonjs.com/u/inteja)\
**Post date:** [May 15, 2023, 7:23pm UTC](https://forum.babylonjs.com/t/node-material-instance-u-v-offset-and-color/40783/6 "2023-05-15T19:23:21Z")

</div>

Thanks @PatrickRyan

My only remaining questions are:

1. In NME there’s `mesh.color` and `mesh.instanceColor` nodes with the tooltip for the former saying it’s for vertex color, so I’m unsure why this is used in this case rather than the latter, or is the tooltip incorrect?
2. There’s a limit to the number of instance buffers I can create and use with NME right? It’s only color? So I can’t register a `uvOffset` instanced buffer and use that because there’s no NME node corresponding to that?

---

<div class="post-metadata">

**Author:** ![PatrickRyan](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/patrickryan/32/3417_2.png) [@PatrickRyan](https://forum.babylonjs.com/u/PatrickRyan)\
**Post date:** [May 15, 2023, 9:33pm UTC](https://forum.babylonjs.com/t/node-material-instance-u-v-offset-and-color/40783/7 "2023-05-15T21:33:01Z")

</div>

@inteja, I agree with you that the tool tip for instance color is misleading. But the answers to your questions are:

1. The reason that we are using `mesh.color` in the example is because we are setting custom [VertexBuffers](https://doc.babylonjs.com/typedoc/classes/BABYLON.VertexBuffer) for vertex color on each instance. Because we’ve written a custom color into the vertices, we access them with `mesh.color`. For `mesh.instanceColor`, if my memory serves me correctly (but @sebavan or @Evgeni_Popov can correct me if I am wrong) this mesh parameter refers only to thin instances so there was a differentiator from `mesh.color`. We should update the tooltip to be clearer.
2. As you can see in the vertex buffers link above, there are many different “KINDS” of mesh attributes that can be stored as a custom buffer. [As you can see in this code example](https://doc.babylonjs.com/features/featuresDeepDive/mesh/copies/instances#custom-buffers), the `VertexBuffer` is being defined as `BABYLON.VertexBuffer.ColorKind`, but it could just as easily be defined as `BABYLON.VertexBuffer.UVKind` or any of the six UV sets that the engine supports. In this case, you would add the final value with UV offset applied to the value to the buffer and your `mesh.uv` block should pass the correct value.

The reason I chose to use color in the example I did was that `mesh.color` does not affect anything in the mesh if I don’t reference the vertex color in the node material. Changing other parameters like UV, Position, Normal, etc. would have an effect on the final mesh. However, if you want to control your color and UVs per instance, then you have all the tools you need by writing custom buffers for each and then accessing them with the appropriate mesh parameter input blocks. Does this make more sense?

---

<div class="post-metadata">

**Author:** ![inteja](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/inteja/32/22553_2.png) [@inteja](https://forum.babylonjs.com/u/inteja)\
**Post date:** [May 15, 2023, 10:22pm UTC](https://forum.babylonjs.com/t/node-material-instance-u-v-offset-and-color/40783/8 "2023-05-15T22:22:06Z")

</div>

Thanks @PatrickRyan

That answers my questions. I think I just misunderstood the docs and examples to mean that there was some hard limit to only `color` when using instance buffers with NME. I will try registering custom UV instance buffers and modify my node material accordingly.

---

<div class="post-metadata">

**Author:** ![Evgeni\_Popov](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/evgeni_popov/32/4432_2.png) [@Evgeni\_Popov](https://forum.babylonjs.com/u/Evgeni_Popov)\
**Post date:** [May 16, 2023, 10:05am UTC](https://forum.babylonjs.com/t/node-material-instance-u-v-offset-and-color/40783/9 "2023-05-16T10:05:24Z")

</div>

`instanceColor` is actually the instance color, and `color` is the vertex color.

The reason `color` works as an instance color in the example is that the vertex color buffer is created with a `registerInstancedBuffer("color", 4);` call, which creates an instance buffer for “color”. Before `instanceColor` existed (feb 2022), this was the only way to have a per-instance color, and it was not possible to have an instance color + a vertex color at the same time.

To make the instance color work with thin instances, you have to use the `instanceColor` attribute, because `thinInstanceRegisterAttribute("color", 4)` will actually be translated to `thinInstanceRegisterAttribute("instanceColor", 4)` (we did this to retain backward compatibility). So, overall, `instanceColor` should always be used when you want to use a per-instance color, and you should register the buffer by calling `registerInstancedBuffer("instanceColor", 4);` / `thinInstanceRegisterAttribute("instanceColor", 4)`.

Here is an example that shows how to create a custom attribute for use in the NME:

> [@Using shaders exported from Node Material Editor](https://forum.babylonjs.com/t/using-shaders-exported-from-node-material-editor/15628/5):
>
> You can also inject a new attribute in a node material by using the same technic than described here: [Thin instances, node material and custom attribute](https://forum.babylonjs.com/t/thin-instances-node-material-and-custom-attribute/11110)[https://playground.babylonjs.com/#NICGSS#10](https://playground.babylonjs.com/#NICGSS#10)

---

<div class="post-metadata">

**Author:** ![inteja](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/inteja/32/22553_2.png) [@inteja](https://forum.babylonjs.com/u/inteja)\
**Post date:** [May 16, 2023, 10:28am UTC](https://forum.babylonjs.com/t/node-material-instance-u-v-offset-and-color/40783/10 "2023-05-16T10:28:03Z")

</div>

Thanks for explaining the distinction between and history behind `color` vs `instanceColor`. I switched to using `instanceColor` and that works fine too.

Thanks also for the link on how to inject custom attributes for use in NME. That’ll be handy for the future, but I think for my current use case, although the naming isn’t ideal, I’m just using one of the unused UV channels (`uv3`) as the UV offset for one of the in use UV channels, which requires less code and complexity.
