Problem with instancedBuffers in Babylon React Native

@bghgary @Cedric I’m having trouble with instancedBuffers in Babylon React Native, specifically changing UVs per instance, which results in unpredictable changing of vertex position rather than UVs, but no error.

I found this open issue:

But there’s also a mention of some work having been done on this in the merged PR:

So I’m a bit confused about the status.

Here’s some PG examples of the types of instancedBuffers usage I’m experiencing trouble with:

I’ll let @Cedric take this one.

1 Like

Instancing with BabylonNative/BabylonReactNative is very limited because of constraints on our rendering back end.
Basically, you can only instanciate the world matrix and the color. That’s a total of 5 vec4.
For now, it’s not possible to instanciate uv or anything else.
If you need different UV per instance, I would try to store an UV offset in the color. Like an index in an atlas texture.
So, with this technic, you will have to write your vertex shader accordingly.

2 Likes

Thanks @Cedric

So just use a vec4 and instancedBuffer of stride length 4? Name can be anything, so I could call it uvOffset4?

Something like the following?

mesh.registerInstancedBuffer("uvOffset4", 4);

// Dynamically set uOffset and vOffset somewhere ...

instance.instancedBuffers.uvOffset4 = new Vector4(uOffset, vOffset, 0, 0);

Then in the shader, something like:

attribute vec4 uvOffset4;
vec2 uvOffset = vec2(uvOffset4[0], uvOffset4[1]);
vMainUV1 = uvUpdated + uvOffset; 

Is that right?

No, create a buffer named color, just like if you want to instanciate colors.
Then, in the shader, get the color vec4 value and use it to store something else than colors.

Ok, I thought maybe the name doesn’t matter, but all good, I will use color.

Thanks again @Cedric !

Will just update that code snippet in case someone else stumbles on it.

mesh.registerInstancedBuffer("color", 4);
// Dynamically set uOffset and vOffset somewhere ...
instance.instancedBuffers.color = new Color4(uOffset, vOffset, 0, 0);

Then in the shader, something like:

attribute vec4 color;
vec2 uvOffset = vec2(color[0], color[1]);
vMainUV1 = uvUpdated + uvOffset; 

Better?

yes! and it leaves you 2 floats for more instancing infos :slight_smile:

1 Like

Hi @Cedric, I’ve tried this in Babylon React Native but am now getting a shader compilation error:

BJS - [20:53:19]: Error: Exception in HostFunction: ERROR: 0:158: 'color' : redefinition

I am creating this shader as a material plugin for StandardMaterial.

Then I tried commenting out attribute vec4 color; and got the warning WARNING: Fail to create vertex buffer. Number of vertex buffers higher than max count or too many instanced streams.

Do I need to apply this workaround just with a simple shader, not a material plugin of a StandardMaterial?

Do you have other buffers set as instance buffers?
can you share access to your PG code?

No that color instanced buffer is the only one I’ve set in the entire codebase.

Here’s a PG that replicates the issue, so I’ve done something wrong …

Could try setting useVertexColors to false on the mesh so that the standard material doesn’t use the color attribute.

1 Like

Thanks @Blake !

Hmmm, sorry me again @Cedric , but I just can’t seem to get this working in Babylon React Native. Here’s an adjusted PG showing exactly what I’m trying to do in the way it’s implemented in Babylon React Native (as per all the suggestions above). This code works fine in the playground, but in my Babylon React Native codebase the geometry is messed up and just unlit black but no errors or warnings.

I’m taking a closer look.

I did it a bit differently:

I removed https://playground.babylonjs.com/#3BU7P2 and changed slightly CUSTOM_VERTEX_MAIN_END

Then, I used thinInstanceSetBuffer And I got it working with native.

3 Likes

Thanks for looking into this @Cedric

So I need to use thin instances rather than instances?

For native, yes.