Support uniform array in shader material in Babylon Lite

I am migrating my previous BabylonJS project to Babylon Lite. And my shader material was using uniform array<vec4<f32>, 8> . And Lite doesn’t support this type.

So the modification is:

export type ShaderUniformType = "f32" | "u32" | "i32" | "vec2<f32>" | "vec3<f32>" | "vec4<f32>" | "mat4x4<f32>" | `array<vec4<f32>, ${number}>`;

export type WgslScalarType =
    | "f32"
    | "u32"
    | "i32"
    | "vec2<f32>"
    | "vec3<f32>"
    | "vec4<f32>"
    | "vec4<u32>"
    | "mat4x4<f32>"
    | `array<vec4<u32>, ${number}>`
    | `array<vec4<f32>, ${number}>`;

function isUniformType(type: string): type is ShaderUniformType {
    return (
        type === "f32" ||
        type === "u32" ||
        type === "i32" ||
        type === "vec2<f32>" ||
        type === "vec3<f32>" ||
        type === "vec4<f32>" ||
        type === "mat4x4<f32>" ||
        /^array<vec4<f32>,\s*\d+>$/.test(type)
    );
}
function elementCount(type: ShaderUniformType): number {
    switch (type) {
        case "f32":
        case "u32":
        case "i32":
            return 1;
        case "vec2<f32>":
            return 2;
        case "vec3<f32>":
            return 3;
        case "vec4<f32>":
            return 4;
        case "mat4x4<f32>":
            return 16;
        default: {
            const m = /^array<vec4<f32>,\s*(\d+)>$/.exec(type);
            if (m) {
                return Number(m[1]) * 4;
            }
            throw new Error(`ShaderMaterial: unsupported uniform type "${String(type)}".`);
        }
    }
}

I’ve finished the feature(including doc modification and tests) but I want to know your opinion on contributing to Babylon Lite, before creating a PR, especially on this kind of small enhancements because it doesn’t have a direct downstream consumer in Lite. Another thing is it seems this is a spec driven project, and what kind of constraints needed to express this(and future extensions) so that agents won’t drift away is not yet thoroughly considered.

And while writing the post I realise that there could be many basic combinations of uniform types if keeping on the current path… And not to mention the user defined struct. A proper recursive compute layout function is probably needed.

I’d like to know your opinions!

Edit: I was uploading f16 vertex attributes to GPU without conversion. That is another type to add in towards combinatoric explosion. And I can’t find the document that restraints agents to only use f32 vertex attributes? And since the minimum node version stays 18, I guess we can’t have native f16 conversion in Lite as well. Previous feature PR for BabylonJS: Support half-float (float16) vertex attribute type ( float16x2/float16x4 on WebGPU)

2 Likes

To do that we need a scene in bjs and a scene in lite. Create a test scene in bjs with all the combinations so it will be used as target and register it in the lab

Guidance.md should have all the info

1 Like

Even without considering f16, there are 42 of them in total.

  • Scalar — i32, u32, f32 = 3
  • Vectors — vec2/3/4 × {f32,i32,u32} = 3x3
  • matCxR, C,R∈{2,3,4} × {f32} = 3x3
  • array<E, N> where E could be any type listed above = 21

If my understanding is correct, that would be 42 types(switch cases) into each type definition and each function. I’ll try to make a PR first. I read about the GUIDANCE.md. Going to create a scene comparison of BabylonJS and Lite.

correct we can have 42 boxes on the screen so we ensure pixel prefect. We drive lite by having pixel comparison with bjs which is the stable ground truth

And thanks a lot for helping! I appreciate!

1 Like

One big constraint: if the feature is not used, it cannot change the bundle sizes of other scenes.

1 Like