Shader Material
ShaderMaterial
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:- 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" }
using 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
: 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 typemat4
and must be in theuniforms
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.
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);
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 shaderTroubleshoot
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: 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.