Allow modifying scene data during load

When loading .babylon files exported by other tools, e.g. Blender, it’s useful to inspect/modify meshes/materials before they are instantiated.

For example, I’m replacing some materials with ShaderMaterial at runtime. This is actually a bit complicated. We need to find all materials that need replacing, replace them with ShaderMaterials, and then find all meshes that reference them, and update their material references. Not to mention that CPU cycles are wasted creating those original materials.

This can be greatly simplified if there were a way to modify the JSON before the scene loader instantiates all the nodes from it. Something like a callback on SceneLoader.LoadAsync for each mesh/material JSON definition, that allows us to return a different one.

I’d like to call it like this:

SceneLoader.LoadAsync(..., (json: object, type: string) => {
    // type comes from the top-level nodes, e.g. materials|meshes|transformNodes|etc.
    if (type === "materials" && myMaterials.has(json['name']) {
        // return some other JSON to the loader
        return {name: ..., customType: 'BABYLON.ShaderMaterial', ...}
    }
    return json;
});

Why not working at the JSON level directly in this case ?

That would be fine, but there’s no method that accepts JSON, only a URL.

It could be possible to monkey-patch static function BABYLON.Material.Parse to intercept the loading of material.

const MaterialParse = BABYLON.Material.Parse;

BABYLON.Material.Parse = function Parse(parsedMaterial: any, scene: Scene, rootUrl: string): Nullable<Material> {
    if (myMaterials.has(parsedMaterial['name'])) {
        parsedMaterial = {name: ..., customType: 'BABYLON.ShaderMaterial', ...};
    }
    return MaterialParse.call(this, parsedMaterial, scene, rootUrl);
};

@bghgary was doing smthg similar for gltf. Could you share back your way of loading from JSON ?

One option is to load the URL as text first, parse, modify, stringify, then load the resulting string. It’s a pretty crappy solution though. It would make more sense to add a callback to be able to modify the parsed JSON object in the Babylon file loader.

1 Like