GLSL Shader Programs
Reference Manual > ShaderLab Reference > Writing shader programs > GLSL Shader ProgramsIn addition to using Cg shader programs, OpenGL Shading Language (GLSL) shaders can be written.
However, use of GLSL is only recommended for testing, or when you know you will only target Mac OS X. GLSL language is specific to OpenGL, whereas using Cg will compile shaders to both Direct3D and OpenGL. Using GLSL allows using more hardware features than possible with Cg, especially on recent hardware. On the other hand, at the moment GLSL implementations are somewhat lacking or buggy, so be warned!
GLSL snippets
GLSL program snippets are written between GLSLPROGRAM and ENDGLSL keywords.
In GLSL, all shader function entry points have to be called main(). When Unity loads the GLSL shader, it loads the source once for the vertex program, with VERTEX preprocessor define, and once more for the fragment program, with FRAGMENT preprocessor define. So the way to separate vertex and fragment program parts in GLSL snippet is to surround them with #ifdef VERTEX .. #endif and #ifdef FRAGMENT .. #endif. Each GLSL snippet must contain both a vertex program and a fragment program.
At the start of the snippet compilation directives can be given as #pragma statements. Directives recognized by Unity are:
- #pragma multi_compile_builtin - for pixel-lit shaders; this will tell Unity to compile dozens of permutations of this shader program to support all light types and all shadowing options.
- #pragma multi_compile_builtin_noshadows - for pixel-lit shaders that don't receive shadows; this will tell Unity to compile several permutations of this shader program to support all light types. This is faster to compile than the multi_compile_builtin pragma, and the resulting shader is smaller.
Standard include files match those provided for Cg shaders; they just have .glslinc extension: UnityCG.glslinc and AutoLight.glslinc.
Vertex shader inputs come from predefined GLSL variables (gl_Vertex, gl_MultiTexCoord0, ...) or are user defined attributes. Usually only the tangent vector needs a user defined attribute:
attribute vec4 Tangent;
Data from vertex to fragment programs is passed through varying variables, for example:
varying vec3 lightDir; // vertex shader computes this, fragment shader uses this