Shader Material


The ShaderMaterial object has the necessary methods to pass data from your scene to the Vertex and Fragment Shaders and returns a material that can be applied to any mesh. This returned material effects how the mesh will look based on the code in the shaders.

It is called by

const myShaderMaterial = new BABYLON.ShaderMaterial(name, scene, route, options);
  • name: A string, naming the shader

  • scene: The scene in which the shader is to be used

  • route: The route to the shader code. It can be any one of these:

    1. object: { vertex: "custom", fragment: "custom" }, used with BABYLON.Effect.ShadersStore["customVertexShader"] and BABYLON.Effect.ShadersStore["customFragmentShader"].
    2. object: { vertexElement: "vertexShaderCode", fragmentElement: "fragmentShaderCode" }, used with shader code in <script> tags.
    3. object: { vertexSource: "vertex shader code string", fragmentSource: "fragment shader code string" } using with strings containing the shader code.
    4. string: "./COMMON_NAME", used with external files COMMON_NAME.vertex.fx and COMMON_NAME.fragment.fx, accessible through a file server (local or remote).
  • options: Object containing attributes and uniforms arrays containing their names as strings.

An example:

const myShaderMaterial = new BABYLON.ShaderMaterial("shader", scene, "./COMMON_NAME",
attributes: ["position", "normal", "uv"],
uniforms: ["world", "worldView", "worldViewProjection", "view", "projection", "time", "direction" ],
samplers: ["textureSampler"],
defines: ["MyDefine"]
needAlphaBlending: true,
needAlphaTesting: true
  • Any attribute in the Vertex Shader code must appear in the attributes array.
  • The uniform worldViewProjection must be declared in the Vertex Shader as type mat4 and must be in the uniforms array, if it is to be used.
  • Attributes and uniforms named in the arrays and not used in the shader code are ignored.
  • If your shader code contains #define values, you can specify the ones you want to activate in the defines array.
  • Uniforms assigned to textures in the shader code must be present in the samplers array, all other uniforms must be present in the uniforms array.
Simplest Shader Material Accessing a shader code file from Github

An example of passing a texture:

const myShaderMaterial = new BABYLON.ShaderMaterial("shader", scene, "./COMMON_NAME", {
"attributes": ["position", "uv"],
"uniforms": ["worldViewProjection"],
"samplers": ["textureSampler"]
const amigaTexture = new BABYLON.Texture("amiga.jpg", scene);
myShaderMaterial.setTexture("textureSampler", amigaTexture);
Passing a texture sampler to a shader

Other uniforms are passed, for example, as

myShaderMaterial.setFloat("time", 0);
myShaderMaterial.setVector3("direction", BABYLON.Vector3.Zero());

where the set method's name is dependant on type.

Passing and updating a Color3 uniform to a shader


When working with shaders, it is very useful to have a debug tool which can show the values passed to the shaders. To that goal, you can use the Babylon Spector.js tool:, which works for any shader code, not just Babylon.js.

In some specific cases when you use post-processes, you might notice a slightly brighter color output than what you implemented in your shader. Read this if you want to know how to fix it.

Further reading

Introduction to Shaders
Dive deep into the inner workings of shaders in Babylon.js.
Introduction to Shaders
Putting Shader Code Into Babylon.js
Dive deep into the inner workings of how Babylon.js handles shaders.
Putting Shader Code Into Babylon.js