ShaderLab

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.

Syntax Overview

The basic structure of ShaderLab syntax is as follows:

Shader "ShaderName" {
  ...
  Editor {
    ...
  }
  ...
  SubShader "SubShaderName" {
    ...
    Pass "PassName" {
      ...
    }
    ...
  }
  ...
}

Main Syntax Modules in ShaderLab

Syntax ModuleDescription
ShaderDeclares a shader object in ShaderLab. Developers can add material properties, bind Shader UI scripts, and declare global variables within this module.
EditorCustomizes the material Inspector panel through the Editor module.
SubShaderSpecifies Tags, adds shader passes, and uses the UsePass directive within SubShader.
PassDeclares a ShaderPass object via the Pass module.

Unlit ShaderLab Example

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
        }
    }
}

Was this page helpful?