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
PBRCustomMaterial. I can do
material._uniformBuffer = ubo;, but I don’t like accessing private properties like that
addFloat3, but where are primitives like
Custom Materials are mainly supported by @nasimiasl
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.
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];
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
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):