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;
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”);
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.
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.