Materials are an encapsulation on top of shaders. They provide a simple way to configure and share shaders.
The first time a material is created, an internal object named effect will be 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 a process that will be done synchronously on the main thread and thus could cause a bit of lag in the rendering.
As the process is a bit expensive, once compiled an effect will remain in memory until you dispose the engine.
Everytime you will 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.
By default, materials are compiled only when required. But you may want to precompile everything before running your rendering in order to get the smoother 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 in order to get everything ready before the first frame.
You also have the opportunity 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 decide to still 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;