This appendix presents a brief overview of the structure of surface shaders and Cg/HLSL programming.
Shaders in Unity can be written in one of the following three different ways:
Surface shaders will probably be your best bet. Write your shader as a surface shader if it needs to interact properly with lighting, shadows, projectors, and so on. Surface shaders also make it easy to write complex shaders in a compact way—it's a higher level of abstraction. Lighting for most surface shaders can be calculated in a deferred manner (except for some custom lighting models), which allows your shader to efficiently interact with many real-time lights. You write surface shaders in a couple of lines of Cg/HLSL and a lot more code gets autogenerated from that.
Vertex and fragment shaders will be required, if you need some very exotic effects that the surface shaders can't handle, if your shader doesn't need to interact with lighting, or if it's an image effect. Shader programs written this way are the most flexible way to create the effect you need (even surface shaders are automatically converted to a bunch of vertex and fragment shaders), but that comes at a price—you have to write more code and it's harder to make it interact with lighting. These shaders are written in Cg/HLSL as well.
Fixed function shaders need to be written for old hardware that doesn't support programmable shaders. You will probably want to write fixed function shaders as an nth fallback to your fancy fragment or surface shaders, to make sure your game still renders something sensible when run on old hardware or simpler mobile platforms. Fixed function shaders are entirely written in a language called ShaderLab, which is similar to Microsoft's
.FX
files or NVIDIA's CgFX.
Regardless of which type you choose, the actual meat of the shader code will always be wrapped in ShaderLab, which is used to organize the shader structure. It looks similar to the following code:
Shader "MyShader" { Properties { // All properties go here _MyTexture ("My Texture", 2D) = "white" { } } SubShader { // Choose your written style // - surface shader or // - vertex and fragment shader or // - fixed function shader } SubShader { // Optional - A simpler version of the SubShader above that can run on older graphics cards } }
However, we will only talk about the surface shaders, which we used in Project 3, The Hero/Heroine Part I—Models and Shaders.