Vertex and Fragment Shader Programming

A Pass represents a single GPU rendering process, so each Pass must include both a vertex shader and a fragment shader. In ShaderLab, the VertexShader and FragmentShader keywords specify their entry functions.

...
Pass "0" {
  ...
  VertexShader = vert;
  FragmentShader = frag;
 
  v2f vert(a2v o) {
    ...
  }
 
  ...
 
  void frag(v2f i) {
    ...
  }
  ...
}

Attribute and Varying Variable Declarations

Like traditional GLSL shaders, ShaderLab uses Attribute and Uniform variables to receive rendering data from the CPU. Varying variables are used to pass data between vertex and fragment shaders. Unlike traditional GLSL, ShaderLab declares these variables using structs and shader entry function signatures.

struct Attributes {
  vec3 POSITION;
  vec4 COLOR_0;
  ...
}
 
struct Varyings {
    vec2 uv;
    vec3 position;
    ...
}
...
Varyings vert(Attributes attr) {
    Varyings vary;
    ...
    vary.position = attr.Position;
    ...
    return vary;
}
 
void frag(Varyings vary) {
    ...
    gl_FragColor = vary.COLOR_0;
}
 
...
VertexShader = vert;
FragmentShader = frag;

MRT (Multiple Render Targets)

ShaderLab supports both GLSL 100 and GLSL 300 syntax, so you can use either approach to specify MRT:

1. Using gl_FragData[i]

void main(v2f input) {
  gl_FragData[0] = vec4(1.,0.,0.,1.);     // render target 0
  gl_FragData[1] = vec4(1.,0.,0.,1.);     // render target 1
}

2. Using a Return Struct

struct mrt {
  layout(location = 0) vec4 fragColor0;   // render target 0
  layout(location = 1) vec4 fragColor1;   // render target 1
}
 
mrt main(v2f input) {
  mrt output;
  output.fragColor0 = vec4(1.,0.,0.,1.);
  output.fragColor1 = vec4(1.,0.,0.,1.);
  return output;
}

Macros

ShaderLab currently supports the following GLSL macro operations:

MacroDescription
#defineSame as GLSL
#undefSame as GLSL
#ifSame as GLSL
#ifdefSame as GLSL
#ifndefSame as GLSL
#elseSame as GLSL
#elifSame as GLSL
#endifSame as GLSL
definedSame as GLSL
#includeShaderLab-specific: Used for code segment inclusion. See documentation for details

All macros except #include follow standard GLSL behavior. For detailed usage, refer to the GLSL specification.

ShaderLab macros are expanded during the preprocessor phase and cannot affect ShaderLab structure parsing. This means keywords like Shader, SubShader, Pass, EditorProperties, and EditorMacros cannot appear inside conditional macros like #ifdef.

Was this page helpful?