Unity Shader Primer

Basic Shader Syntax

 

In the most basic sense the job of any shader is simply to provide detail to some mesh geometry. Shaders accomplish this through a set of inputs or properties exposed by the shader program to the engine. These inputs can hold various types of data such as textures, vectors, or values. Finally using these inputs the shader computes their affect combined with a lighting model to achieve a rendered scene.

The first line of a shader program contains the Shader keyword followed by the menu structure for unity to use within the editor, and last the name of your shader.

Shader “SubMenu/ShaderName”

Properties in any shader are exposed in the first section of the shader program, preceded by the keyword Properties. Within this code block variables are exposed using the syntax:

VariableName (“Variable Description“, Type) = Default Value

Once properties are defined the next code block is the SubShader. The subshader section contains the Tags section which defines the lighting model to be used with the shader, typically all that is required is “RenderType” = “Opaque” but there are many more models to experiment with.

Next within the subshader block is the #pragma section which tells the GPU which order to execute your shader functions in, as well as any other shader functions you want to include. Tags should be followed by the CGPROGRAM directive to alert the compiler where your shader starts.

The rest of the shader is similar to a C program wherein you would define a memory structure to access your game data along with declaring any other variables to access your property data. Within the shader function, in this case the surf function, you must pass in parameters to utilize the data you need such as UV coordinates, mesh position, time, ect. Also you must define an output for your function to send back to the GPU, in this example inout SurfaceOutput o receives the color data of the texture _MainTex at the UV location stored in IN.uv_MainTex, these variables are passed to a standard function tex2D which returns the color data to o.Albedo to be rendered by Unity.

Last you have the option of declaring a Fallback shader program just in case there is a problem with your custom shader.

Shader "Custom/ShaderExperiment1" {    
	Properties {
	  _MainTex ("Texture", 2D) = "white" {}
	}
	SubShader {
	  Tags { "RenderType" = "Opaque" }
	  CGPROGRAM
	  #pragma surface surf Lambert
	  struct Input {
		  float2 uv_MainTex;
	  };
	  sampler2D _MainTex;
	  void surf (Input IN, inout SurfaceOutput o) {
		  o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
	  }
	  ENDCG
	} 
	FallBack "Diffuse"
}