Putting Shader Code Into Babylon.js
Putting Shader Code in BabylonJS
Here are four ways of putting shader code into your scene:
- Use BabylonJS Create Your Own Shader (CYOS) and download a zip file;
- Write the Vertex and Fragment Shader Code into <script> tags
- Write, save and import a Vertex and Fragment Shader file of type .fx into your code;
- Use the shaderBuilder extension of BabylonJS.
Methods 1, 2 and 3 use BABYLON.ShaderMaterial to pass data to the shaders.
BabylonJS CYOS Download
This site allows you to write code for a Vertex Shader and a Fragment Shader and see the results on a variety of meshes. Downloading a zip file produces a folder containing and index.html file and some image files for texture.
The index.html file contains the shader code in the correct format to apply as a material.
Within the HTML page the shader code becomes (in Javascript)
BABYLON.Effect.ShadersStore["customVertexShader"]= "\r\n"+"precision highp float;\r\n"+"// Attributes\r\n"+"attribute vec3 position;\r\n"+"attribute vec2 uv;\r\n"+"// Uniforms\r\n"+"uniform mat4 worldViewProjection;\r\n"+"// Varying\r\n"+"varying vec2 vUV;\r\n"+"void main(void) {\r\n"+" gl_Position = worldViewProjection * vec4(position, 1.0);\r\n"+" vUV = uv;\r\n"+"}\r\n";BABYLON.Effect.ShadersStore["customFragmentShader"]= "\r\n"+"precision highp float;\r\n"+"varying vec2 vUV;\r\n"+"uniform sampler2D textureSampler;\r\n"+"void main(void) {\r\n"+" gl_FragColor = texture2D(textureSampler, vUV);\r\n"+"}\r\n";
the Javascript code to use the shader as a material is
var shaderMaterial = new BABYLON.ShaderMaterial("shader", scene, {vertex: "custom",fragment: "custom",},{attributes: ["position", "normal", "uv"],uniforms: ["world", "worldView", "worldViewProjection", "view", "projection"]});
and the Javascript code to set a texture to the material is
var mainTexture = new BABYLON.Texture("amiga.jpg", scene);shaderMaterial.setTexture("textureSampler", mainTexture);
and to use the material on a mesh is
mesh.material = shaderMaterial;
Extracting the appropriate sections of Javascript code allows you to transfer them to your own scenes.
This method can easily be used in the Playground.
Playground Example From CYOSShader Code in <script> Tags
In the index.html file the Javascript code for the shaders is
<script type="application/vertexShader" id="vertexShaderCode">#ifdef GL_ESprecision highp float;#endif// Attributesattribute vec3 position;attribute vec2 uv;// Uniformsuniform mat4 worldViewProjection;// Normalvarying vec2 vUV;void main(void) {gl_Position = worldViewProjection * vec4(position, 1.0);vUV = uv;}</script><script type="application/fragmentShader" id="fragmentShaderCode">#ifdef GL_ESprecision mediump float;#endifvarying vec2 vUV;uniform sampler2D textureSampler;void main(void) {gl_FragColor = texture2D(textureSampler, vUV);}</script>
the Javascript code to use the shader as a material becomes
var shaderMaterial = new BABYLON.ShaderMaterial("shader", scene, {vertexElement: "vertexShaderCode",fragmentElement: "fragmentShaderCode",},{attributes: ["position", "normal", "uv"],uniforms: ["world", "worldView", "worldViewProjection", "view", "projection"]});
Shader Code in fx Files
Save your code in two files, one for the Vertex Shader and one for the Fragment Shader.
These files must be in the same folder as your index.html page and the names of the files must follow this format
COMMON_NAME.vertex.fx
COMMON_NAME.fragment.fx
The Javascript code to use the shader as material becomes
var shaderMaterial = new BABYLON.ShaderMaterial("shader", scene, "./COMMON_NAME",{attributes: ["position", "normal", "uv"],uniforms: ["world", "worldView", "worldViewProjection", "view", "projection"]});
Note: ./
is necessary before the COMMON_NAME
It is also possible to access the fx files from an URL by giving the full address of the URL, provide CORS is enabled for them.
Shader Includes
When building shaders sometimes you have parts of your code that will be reused between multiple shaders. This is usually things like reused uniforms, functions, structs etc. A powerful method that users have at their disposal is to accomplish this task is the
BABYLON.Effect.IncludesShadersStore["includeName"] = "..."
Already loaded in the includes are all the common shader elements for babylons StandardMaterial, PBR Materials, ProceduralTextures and more. See the github https://github.com/BabylonJS/Babylon.js/tree/master/src/Shaders/ShadersInclude for a complete list of shader includes packaged with BJS.
Additionally you can add anything you want to the IncludesShadersStore pre or post compilation of the scene. To access these includes simply call:
#include<includeName>
In the appropriate section of your shader code to have them injected into your shader when it is compiled see example.
Shader Builder
This is an extension to BabylonJS. Copy and save the source code for the extension and add as
<script src="Babylonx.ShaderBuilder.js"></script>
The Shader Builder engine needs to be initialised
BABYLONX.ShaderBuilder.InitializeEngine();
The format for writing a ShaderBuilder is fluent coding and it deals with attributes and BabylonJS uniforms automatically.
An example for the shader code used in 1 to 3 above would be
mesh.material = new BABYLONX.ShaderBuilder().Map({ path: 'textures/amiga.jpg' }).BuildMaterial(scene);
Guide Example using ShaderBuilder
This method can be used in the Playground. However it does require the loading of the ShaderBuilder Javascript file and an onLoad
function before it can be called.