Shader Material
ShaderMaterial
The ShaderMaterial object has the necessary methods to pass data from your scene to the Vertex and Fragment Shaders and creates a material that can be applied to any mesh. This material affects how the mesh looks based on the code in the shaders.
It is created with:
import { ShaderMaterial } from "@babylonjs/core/Materials/shaderMaterial";const myShaderMaterial = new 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:- object:
{ vertex: "custom", fragment: "custom" }, used withBABYLON.Effect.ShadersStore["customVertexShader"]andBABYLON.Effect.ShadersStore["customFragmentShader"]. - object:
{ vertexElement: "vertexShaderCode", fragmentElement: "fragmentShaderCode" }, used with shader code in<script>tags. - object:
{ vertexSource: "vertex shader code string", fragmentSource: "fragment shader code string" }, used with strings containing the shader code. - string:
"./COMMON_NAME", used with external files COMMON_NAME.vertex.fx and COMMON_NAME.fragment.fx, accessible through a file server (local or remote).
- object:
-
options: An object containingattributesanduniformsarrays, with their names as strings.
An example:
import { ShaderMaterial } from "@babylonjs/core/Materials/shaderMaterial";const myShaderMaterial = new 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
attributesarray. - The uniform
worldViewProjectionmust be declared in the Vertex Shader as typemat4and must be in theuniformsarray, 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
definesarray. - 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.
An example of passing a texture:
import { ShaderMaterial } from "@babylonjs/core/Materials/shaderMaterial";import { Texture } from "@babylonjs/core/Materials/Textures/texture";const myShaderMaterial = new ShaderMaterial("shader", scene, "./COMMON_NAME", { "attributes": ["position", "uv"], "uniforms": ["worldViewProjection"], "samplers": ["textureSampler"]});const amigaTexture = new Texture("amiga.jpg", scene);myShaderMaterial.setTexture("textureSampler", amigaTexture);Other uniforms are passed, for example, as
import { Vector3 } from "@babylonjs/core/Maths/math.vector";myShaderMaterial.setFloat("time", 0);myShaderMaterial.setVector3("direction", Vector3.Zero());where the set method's name depends on the type.
Passing and updating a Color3 uniform to a shaderTroubleshoot
When working with shaders, it is very useful to have a debug tool that can show the values passed to the shaders. For that purpose, you can use the Babylon Spector.js tool: https://github.com/BabylonJS/Spector.js, 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.

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