6.1.2 Shader structure

The following code shows a very simple vertex and fragment shader that contains most of the elements required in vertex or fragment shader.

The shader example is written in Cg. Unity also supports the HLSL language for shader snippets.
Shader "Custom/ctTextured"
{
	Properties
	{
		_AmbientColor ("Ambient Color", Color) = (0.2,0.2,0.2,1.0)
		_MainTex ("Base (RGB)", 2D) = "white" {}
	}

	SubShader
	{
		Pass
		{
			CGPROGRAM
        	#pragma target 3.0
			#pragma glsl
			#pragma vertex vert  
			#pragma fragment frag 
          	
			#include "UnityCG.cginc"
         	
			// User-specified uniforms
			uniform float4 _AmbientColor;
			uniform sampler2D _MainTex;
			
			struct vertexInput
			{
				float4 vertex : POSITION;
				float4 texCoord : TEXCOORD0;
			};
			struct vertexOutput
			{
				float4 pos : SV_POSITION;
				float4 tex : TEXCOORD0;
			};
		 
			// Vertex shader.
			vertexOutput vert(vertexInput input) 
			{
				vertexOutput output;
				
				output.tex = input.texCoord;
				output.pos = mul(UNITY_MATRIX_MVP, input.vertex);
				return output;
			}

			// Fragment shader.
			float4 frag(vertexOutput input) : COLOR
			{
				float4 texColor = tex2D(_MainTex, float2(input.tex));  
				return _AmbientColor + texColor;
			}
			
			ENDCG
		}
	}
	Fallback "Diffuse"
}
		
The first key word is Shader followed by the path/name of the shader. The path defines the category where the shader is displayed in the drop down menu when you are setting a material. The shader from the example is displayed under the category of Custom shaders in the drop down menu.
The Properties{} block lists the shader parameters that are visible in the inspector and what parameters you can interact with.
Each shader in Unity consists of a list of subshaders. When Unity renders a mesh, it looks for the shader to use, and selects the first subshader that can run on the graphics card. This way shaders are executed correctly on different graphics cards that support different shader models. This feature is important because GPU hardware and APIs are constantly evolving. For example, you can write your main shader targeting a Mali Midgard GPU to make use of the latest features of OpenGL ES 3.0, while in a separate subshader, write a replacement shader for graphics cards supporting OpenGL ES 2.0 and below.
The Pass block causes the geometry of an object to be rendered one time. A shader can contain one or more passes. You can use multiple passes on old hardware, or to achieve special effects.
If Unity cannot find a subshader in the body of the shader that can render the geometry correctly it rolls back to another shader defined after the Fallback statement. In the example this is the Diffuse built-in shader.
Cg program snippets are written between CGPROGRAM and ENDCG.
Non-ConfidentialPDF file icon PDF versionARM 100140_0201_00_en
Copyright © 2014, 2015 ARM. All rights reserved.