ShaderLab
is a shader wrapper language designed for the Galacean engine. It allows developers to write custom shaders using familiar GLSL
syntax while providing additional high-level abstractions and management features to enhance development efficiency. With ShaderLab
, developers can more easily define material properties, rendering configurations, and other effects. Although ShaderLab
introduces convenience for shader development, it does not replace GLSL
but remains compatible with it. Developers can write native GLSL
code blocks within the ShaderLab
framework to leverage the combined advantages of both.
The basic structure of ShaderLab
syntax is as follows:
Shader "ShaderName" {
...
Editor {
...
}
...
SubShader "SubShaderName" {
...
Pass "PassName" {
...
}
...
}
...
}
Syntax Module | Description |
---|---|
Shader | Declares a shader object in ShaderLab . Developers can add material properties, bind Shader UI scripts, and declare global variables within this module. |
Editor | Customizes the material Inspector panel through the Editor module. |
SubShader | Specifies Tags, adds shader passes, and uses the UsePass directive within SubShader . |
Pass | Declares a ShaderPass object via the Pass module. |
Shader "ShaderName" {
Editor {
Properties {
material_BaseColor("Main Color", Color) = (0, 0, 0, 1);
material_BaseTexture("Texture", Texture2D);
material_AlphaCutoff("Alpha Cutoff", Range(0, 1, 0.01)) = 0;
Header("Common"){
isTransparent("Transparent", Boolean) = false;
renderFace("Render Face", Enum(Front:0, Back:1, Double:2)) = 0;
blendMode("Blend Mode", Enum(Normal:0, Additive:1)) = 0;
}
}
UIScript "${uiScriptPath}";
}
SubShader "Default" {
UsePass "pbr/Default/ShadowCaster"
Pass "Pass0" {
DepthState {
WriteEnabled = depthWriteEnabled;
}
BlendState {
Enabled = blendEnabled;
SourceColorBlendFactor = sourceColorBlendFactor;
DestinationColorBlendFactor = destinationColorBlendFactor;
SourceAlphaBlendFactor = sourceAlphaBlendFactor;
DestinationAlphaBlendFactor = destinationAlphaBlendFactor;
}
RasterState{
CullMode = rasterStateCullMode;
}
RenderQueueType = renderQueueType;
struct Attributes {
vec3 POSITION;
vec2 TEXCOORD_0;
vec4 JOINTS_0;
vec4 WEIGHTS_0;
};
struct Varyings {
vec2 uv;
};
#include "Common.glsl"
#include "Skin.glsl"
#include "Transform.glsl"
vec4 material_BaseColor;
float material_AlphaCutoff;
sampler2D material_BaseTexture;
VertexShader = vert;
FragmentShader = frag;
Varyings vert(Attributes attr) {
Varyings v;
vec4 position = vec4(attr.POSITION, 1.0);
// Skin
#ifdef RENDERER_HAS_SKIN
mat4 skinMatrix = getSkinMatrix(attr);
position = skinMatrix * position;
#endif
gl_Position = renderer_MVPMat * position;
v.uv = attr.TEXCOORD_0;
return v;
}
void frag(Varyings v) {
vec4 baseColor = material_BaseColor;
#ifdef MATERIAL_HAS_BASETEXTURE
vec4 textureColor = texture2D(material_BaseTexture, v.uv);
#ifndef ENGINE_IS_COLORSPACE_GAMMA
textureColor = gammaToLinear(textureColor);
#endif
baseColor *= textureColor;
#endif
#ifdef MATERIAL_IS_ALPHA_CUTOFF
if( baseColor.a < material_AlphaCutoff ) {
discard;
}
#endif
gl_FragColor = baseColor;
#ifndef ENGINE_IS_COLORSPACE_GAMMA
gl_FragColor = linearToGamma(gl_FragColor);
#endif
}
}
}