API

How Babylon.js Materials Work

How Materials Work

Materials are an encapsulation of shaders. They provide a simple way to configure and share shaders.

Cache and compilation

The first time a material is created, an internal object named effect is created. The effect is the host for the vertex and pixel (fragment) shaders. These shaders have to be compiled by the GPU from plain text to GPU machine code.

The compilation step is done synchronously on the main thread and could therefore cause a bit of lag in rendering.

As the process is a bit expensive, once compiled, an effect will remain in memory until you dispose of the engine.

Every time you change a property of a material (like adding a texture or enabling an option), a new effect will be compiled unless an equivalent can be found in the cache.

Rendering optimization

Since v5.0, meshes are sorted according to the uniqueId property of their material, in ascending order, and are rendered in this sorted order. This is to optimize state changes and reduce the number of times these states need to be changed. You can change this order by changing the uniqueId value, or by using the setRenderingOrder method of the scene.

Precompilation

By default, materials are compiled only when required. But you may want to precompile everything before rendering to get the smoothest experience possible.

To do so, you can just prepare your material with:

material.forceCompilation(mesh, function() {
// Do something when material is compiled
});

For instance, you could go through all your meshes and force compilation of all materials to get everything ready before the first frame.

Non blocking textures

You also have the option to flag textures as non-blocking. By default, a material will not be able to render a mesh until its effect is compiled and all textures are loaded.

You can choose to render your mesh even if textures are not loaded (the missing textures will be replaced by a 1x1 black texture). To do so, just call:

texture.isBlocking = false;