Creating a Material without adding it to the scene automaticly

I had a similar question about meshes: Creating a Mesh without adding to the scene
Now I’m asking if its possible to create a Material without adding it autoamticly to the default scene?

I try to make a TypeScript file, where I store my different Materials (one for cubes, one for cylinders etc).
The material creation at the moment looks like this:

let cubeMaterial= new StandardMaterial("myMaterial", scene);
cubeMaterial.disableLighting = true;
cubeMaterial.emissiveColor = Color3.FromHexString("#eb9e5b");
cubeMaterial.zOffset = 2;
cubeMaterial.alpha = 0.8;

And I want something like:

import { StandardMaterial } from "@babylonjs/core";
const materialDict: Record<string, StandardMaterial > = {};

materialDict["cube"] = new StandardMaterial("myMaterial", null);
materialDict["cube"].disableLighting = true;
materialDict["cube"].emissiveColor = Color3.FromHexString("#eb9e5b");
materialDict["cube"].zOffset = 2;
materialDict["cube"].alpha = 0.8;
export { materialDict };

But doing so results in adding the material to the default scene. Is there a way to define materials without adding them to the scene?
Also is “StandardMaterial” the best Material performance-wise? I couldn’t find a table or similiar which shows which Materials are aviable. The description of StandardMaterial says that its the best tradeoff between quality and performance. Which Material can I use for better performance and worse quality?

When this ts file is imported before a scene/engine (which is the usual case, since imports are way before scene creation) has been initialized I also get an error:

material.ts:667 Uncaught (in promise) TypeError: Cannot read property 'getMaterialByID' of null
    at StandardMaterial.Material (material.ts:667)
    at StandardMaterial.PushMaterial [as constructor] (pushMaterial.ts:20)
    at new StandardMaterial (standardMaterial.ts:725)

My goal is to create a “package-like” container with ready to use Materials, which I can use in multiple parts of my application.

You can add materials to a scene without adding them to a mesh or other asset, and thereby create a material library. But so far as I know you can not leave them out of the scene entirely, or else how would you ever reference something?

What I think you may be asking about doing is creating a simple material library. So I made one in typescript to demo this for you:

these are materials that all get created when the scene is initialized.Then using getMaterialByName("") you can assign it to a mesh or object like mesh.material = scene.getMaterialByName(“debugRed”);

1 Like

Thank you for your answer.
I’m porting a threejs app to babylon. If Materials wouldn’t be tied to a scene, setting mesh.material would still work (like in threejs). Only the place where the materials are saved is different.
I have several “services” which set the color or material of a mesh.
I’ve come up with a similiar example to yours, but then the Material Libary needs to know the scene. Thats means for every scene I would have an instance of the Material Library, or?

This is personal preference, but to me the cleanest way is to re-initialize the material library for each scene.

However, you can do what you want. When you call getMaterialByName(“someNameHere”) you are targeting that at a scene usually, scene.getMaterialByName("") is simply looking inside a scene class variable called scene. It easily could be scene1.getMaterial… or scene2.getMate… as long as you attach them to a variable when initializing.

Here is some help
Using Multiple Scenes | Babylon.js Documentation

It always felt more tricky to manage that way, and in my mind at least more costly, but give it a try. Scene is just a class, so you can reference it from its parent variable and likely reach in and grab and move or clone materials when needed.

I usually treat each scene as a separate thing as it always seemed better for performance to start with a clean sheet of paper (scene) so to speak. Obviously, that is done at the cost of loading time/bandwidth, but its just personal preference and mutli scene should work.

@Browork, you could rely on this Asset Containers | Babylon.js Documentation

At least the materials would be fully scene agnostics.