Uniforms and UniformBuffers

My first time dealing with this, so couple of quick questions:

  • What is the best way to use a uniform to pass from BabylonJS a vec3 array? it can be defined and used in GLSL, but how do I set values to it from BabylonJS as I only see options to work with number arrays
  • Trying to use UniformBuffer, but only ShaderMaterial has method setUniformBuffer - that method is not present on CustomMaterial or PBRCustomMaterial. I can do material._uniformBuffer = ubo;, but I don’t like accessing private properties like that
  • UniformBuffer has addFloat2 and addFloat3, but where are primitives like addFloat?

Hello!

Custom Materials are mainly supported by @nasimiasl :slight_smile:

You could also rely on Materials plugins instead as they do support custom UBOs.

Thanks @carolhmj and @sebavan

My use case is that I wrote a custom skeleton bone shader and using CustomMaterial is perfect for me as I can just inject couple of required lines of GLSL into Babylon’s existing shader and keep it simple. Materials plugin seems a lot more work for what I need (and still doesn’t fully address the requirement).

Regarding uniforms, what I need is to pass several vec3 values for each skeleton bone (number of bones is known once skeleton is loaded, so it can be exactly defined in the shader that gets created at that time. and vec3 values are just colors used in GLSL mix operation combined with existing color, bone weights and some gradient).

This works just fine for a single bone, but i need to be able to set different color values for each different bone dynamically.

But that means typically (60ish * 3 * vec3) - that is too much to deal with as individual uniforms - thus the question how to pass arrays as uniforms from Babylon? GLSL itself works with uniform arrays just fine.

And none of the examples I found deal with arrays.

Btw, UniformBuffers were just my attempt of exploring how to deal with large sets of uniforms, but its not really required as uniform updates are rare (they’re not per frame, but only per specific user interaction). So any method is ok.

effect.setArray3 will be doing exactly this. We use it in our SSAO2 post process to set the uniform vec3 sampleSphere[SAMPLES];

1 Like

yes, i can make that work, but that means recreating vec3 array from float array on each shader pass.
thus my question can i pass vec3 array directly - simple api would avoid unnecessary processing inside the shader.

thing is you might want for perf and GC to keep everything in array from the beginning.

In GL the call will end up being _gl.uniform3fv(uniform, array) to set an array of float.

The main issue is it will upload all of it on each calls where as ubo “in theory” would be faster as you just change its reference. In practice we are not using it anymore in webgl2 for the mesh as it was slower the matrix uniform set :slight_smile:

1 Like

good tips - i might as well encapsulate all values i need in a single uniform matrix.

btw, this is the result so far - you can see bone shader at work (bone: Hips):

2 Likes