Custom bonesVertex shader in PBRCustomMaterial?


I am trying to implement instanced rigged models. Something similar to the last post by usoban in: InstancedMesh With Separate Skeleton ??? - Questions & Answers - HTML5 Game Devs Forum

I would like to avoid changing Babylon.js library. I created a PBRCustomMaterial that has properties of the original PBRMaterial used by the meshes of a rigged model, and I can pass the joint matrix of the key frames as texture to this PBRCustomMaterial.

What I want to achieve is to replace the existing implementation in src/Shaders/ShadersInclude/bonesVertex.fx. Instead of reading the transformation matrix from boneSampler, I want the bonesVertex shader to use dynamically calculated worldJointMatrix * invertedBindingMatrix in the shader. I want to know if this is a feasible approach or if there is any other way to do it?

I am not sure if CUSTOM_VERTEX_UPDATE_POSITION in Babylon.js/pbr.vertex.fx at master · BabylonJS/Babylon.js · GitHub the right place to do such customization, or it is too early to do bone vertex modification?

@nasimiasl and @MackeyK24 might be able to help as they are the biggest users of the custom mat.

you can use positionUpdated and normalUpdated for change local
position and normal in custom material

and you can define any uniform use with AddUniform

like this sample for bind the bones data

also i guess you need define some public method you can use
Vertex_Begin for define any new extension or include any shader

Hi nasimiasl,

Thanks for helping and happy new year. I am sorry that I didn’t express my question clearly. I am aware of Vertex_Before_PositionUpdated and AddUniform. I read code in pbr.vertex.fx when I tried to understand where Babylon applies weighted joint matrix to vertex. And it makes me hesitating continue my approach as explained below. The following code taken from lines 182-197 of pbr.vertex.fx.




#if defined(PREPASS) && defined(PREPASS_VELOCITY) && !defined(BONES_VELOCITY_ENABLED)
    // Compute velocity before bones computation
    vCurrentPosition = viewProjection * finalWorld * vec4(positionUpdated, 1.0);
    vPreviousPosition = previousViewProjection * previousWorld * vec4(positionUpdated, 1.0);


    vec4 worldPos = finalWorld * vec4(positionUpdated, 1.0);
    vPositionW = vec3(worldPos);

Like you suggested, I was planing to apply my own transformation matrix to the vertex in CUSTOM_VERTEX_UPDATE_POSITION, which can be customized by Vertex_Before_PositionUpdated(). But after this vertex position update, the original weighted joint matrix are applied to vertex position change is still executed:


I am not sure if the final positions are still correct if both my custom position update and bonesVertex.fx are applied. Also I am a bit worried that any other code between CUSTOM_VERTEX_UPDATE_POSITION and bonesVertex could also impact the position. So my actual question is trying to find out if my worries are actually valid. Or if there is better way to overwrite bonesVertex?

i guess this part is your answer but you most have instancesVertex’s file in same direction of pbr shader

Hi @nasimiasl,

I am not sure I get what you mean. But I find the following approach is working for me. It allows me to replace the original bonesVertex shader with a custom implementation. But of course it will stop working if pbr vert shader changed this line #include<bonesVertex>, and this solution will need to update as well.

const customBoneVert = require("../shaders/bone.vert");
BABYLON.Effect.ShadersStore['pbrVertexShader'] = BABYLON.Effect.ShadersStore['pbrVertexShader'].replace('#include<bonesVertex>', customBoneVert.default);