Unity Shader from getting started to**

Posted by squariegoes on Sun, 16 Jan 2022 01:15:41 +0100

1, Concept

Shader is actually a technology specially used to render graphics. Through shader, we can customize the algorithm of graphics card rendering to make the picture achieve the effect we want. Small to every pixel, large to the whole screen

Shader s fall into two categories:

1. Vertex Shader (3D graphics are composed of triangular patches. Vertex Shader is to calculate the vertices on each triangular patch and prepare for the final pixel rendering).
2. Pixel Shader, as its name implies, is a series of algorithms for calculating illumination and color in pixels. Several different graphics API s have their own shader languages. In DirectX, Vertex Shader is called Vertex Shader and Pixel Shader is called Pixel Shader; In OpenGL, Vertex Shader is also called Vertex Shader, but Pixel Shader is called Fragment Shader, that is, we often call Fragment Shader or Fragment Shader.

Shader programming language
Since Shader is a piece of code, it must be written in one language. At present, there are three mainstream languages:

OpenGL Shading Language Based on OpenGL, GLSL for short.
DirectX based High Level Shading Language, HLSL for short.
There is also C for Graphic of NVIDIA company, abbreviated as Cg language.
GLSL and HLSL are interfaces based on OpenGL and Direct3D respectively, and they cannot be mixed. The Cg language is the C language for graphics, which actually shows the original intention of the designers at that time, that is, to make the programming based on graphics hardware as convenient and free as C language programming. Just as the syntax of C + + and Java is based on C, the Cg language itself is also based on C. If you have used any of C, C + + and Java, the syntax of Cg is easy to master. Cg language strongly retains most of the semantics of C language and tries to free developers from hardware details. Cg also has the advantages of high-level language, such as code reusability and high readability.

Cg language is a collaboration between Microsoft and NVIDIA, which has reached an agreement on the syntax and semantics of standard hardware lighting language. Therefore, HLSL and Cg are actually the same language.

2, Study notes

1. Structure

Basic structure

Shader "MyFirstShader"
{
     Properties//attribute
     {     
     }
     SubShaders//Sub shader block (there can be multiple shader logic processing blocks)
     {
     }
     FallBack "Diffuse"//Spare material
     CutomEditor "EditorName"//Custom interface
}

1.1. attribute

format

[Attribute]_Name ("Display Name",Type) = Default Value
//[tag] variable name ("display name on Panel", type) = Default

1.1.1 attribute type

①. Color color

_Color("I am Color",color) = (1,1,1,1)

②. Int integer

//(even if decimals can be entered in the panel, the shader only takes the integer part)
_Int("I am Int",Int) = 1

③. Float float

_Float("I am Float",Float) = 0.5

Float related tags

//[Range]: limit parameter Range
_Float("I am Float", Range( 0 , 1)) = 0.5
//[IntRange]: round down
[IntRange]_Float("I am Float", Range( 0 , 1)) = 1
//[Toggle]: switch (0 = off, 1 = on)
[Toggle]_Float("I am Float", Range( 0 , 1)) = 1
//[Enum] drop down list
[Enum(UnityEngine.Rendering.CullMode)]_Float("I am Float", Float) = 1

④. Vector four dimension

_Vector("I am Vector",Vector) = (0,0,0,0)

⑤ . 2D texture

_MainTex("I'm 2 D texture",2D) = "white" {}

2D texture related markers

//[NoScaleOffset]: hides the Tiling and offset parameters
[NoScaleOffset]_MainTex("I'm 2 D texture", 2D) = "white" {}
//[Normal]: specify the parameter as Normal map
[Normal]_MainTex("I'm 2 D texture", 2D) = "white" {}

//Default value
//White white
//Black black
//gray grey
//bump normal graph

⑥ . 3D texture

_MainTex("I'm 3 D texture",3d) = "" {}

⑦. Cube texture

_MainTex("I am Cube texture", CUBE) = "" {}

General attribute tag

//[Header]: property description. After use, text will appear above the parameters in the panel
[Header(This is Header )]_Int("I am Int", Int) = 1

1.2 what's in subshaders

1.2.1 Pass

Pass means: render the model once
1. There is at least one SubShader in a Shader
2. Each subshader has at least one Pass

1.2.2 what is in pass

1.2.2.1 .CGPROGRAM and ENDCG

Each Pass must have CGPROGRAM and ENDCG, and the code is written between CGPROGRAM and ENDCG

1.2.2.2 #pragma

Declared vertex and fragment shaders
Keywords #pragma

//Define the vertex shader as name, which is usually called vert.
#pragma vertex name

//Define the fragment shader as name, which is usually called frag.
#pragma fragment name
1.2.2.3 implementation statement
float4 vert ( float4 vertex : POSITION ) : SV_POSITION
{
	return UnityObjectToClipPos(vertex);
}
fixed4 frag () : SV_Target
{
	return _Color;
}

Full shader

Shader "Unlit/MyFirstShader"
{
	Properties
	{
		_Color("Color", Color) = (1,1,1,1)
	}
	
	SubShader
	{
		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag

			fixed4 _Color;
			
			float4 vert ( float4 vertex : POSITION ) : SV_POSITION
			{
				return UnityObjectToClipPos(vertex);
			}
			
			fixed4 frag () : SV_Target
			{
				return _Color;
			}
			ENDCG
		}
	}	
}
ENDCG
1.2.2.4 use of attributes

//Again
fixed4 _Color;
We defined an attribute at the beginning_ Color, but if you want to use it in pass, you need to declare it again. The name should be consistent with the above
The keyword fixed4 represents a four-dimensional vector

There are several common keywords for declaring attributes in Cg/HLSL

float
//High precision type, 32-bit, usually used for position, texture, UV in world coordinates, or scalar calculation involving complex functions, such as trigonometric functions, power operations, etc.
half
//Medium precision type, 16 bits, value range [- 60000, + 60000], usually used for position, direction vector, HDR color, etc. in local coordinates.
fixed
//Low precision type, 11 bits, value range [- 2, + 2], usually used for conventional color and mapping, as well as some operation variables between low precision, etc.

//On the PC platform, whether you write half or fixed in the Shader, it will be treated as a float. Half and fixed are only valid on some mobile devices.
//A common rule is to use half for all except float for position and coordinates. The main reason is that most modern GPU s only support 32-bit and 16 bit, that is, they only support float and half, not fixed.
interger
//Integer type, usually used for loop and array index.

//On Direct3D 9 and OpenGL ES 2.0 platforms, integers may be directly processed with floating-point numbers, and can be correctly processed with integer types on modern GPU s such as Direct3D 11 and OpenGL ES 3.
sampler2D,sampler3D And samplerCUBE
//Texture. By default, the texture on the mobile platform will be automatically converted to a low precision texture type. If you need medium precision or high precision, you need to declare it in the following way:
sampler2D_half(Medium precision 2 D texture)
sampler2D_float(High precision 2 D texture)
sampler3D_half(Medium precision 3 D texture)
sampler3D_float(High precision 3 D texture)
samplerCUBE_halft(Medium precision cube texture)
samplerCUBE_float(High precision cube texture)

1.2.2 struct

Keywords: struct
Function: store variables
Call: struct name + "."+ Variable name

struct appdata{
	float4 vertex:POSITION;
}
//You can also define these semantic variables
struct appdata
	{
		float4 vertex : POSITION;		//vertex
		float4 tangent : TANGENT;		//tangent
		float3 normal : NORMAL;			//normal
		float4 texcoord : TEXCOORD0;	//UV1
		float4 texcoord1 : TEXCOORD1;	//UV2
		float4 texcoord2 : TEXCOORD2;	//UV3
		float4 texcoord3 : TEXCOORD3;	//UV4
		fixed4 color : COLOR;			//Vertex color
	};

1.2.3 user defined functions

fixed checker(float2 uv)
{
	float2 repeatUV = uv*10;
	float2 c = fliir(repeatUV)/2;
	float checker = frac(c.x+c.y)*2;
	return checker;
}

Call of custom function in code

Shader "Unlit/MyFirstShader"
{
	Properties
	{
		_Color("Color", Color) = (1,1,1,1)
	}	
	SubShader
	{
		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			fixed4 _Color;			
			struct appdata
			{
				float4 vertex:POSITION;
				float2 uv:TEXCOORO;
			};
			struct v2f
			{
				float4 pos:SV_POSITION;
				float2 uv:TEXCOORO;
			};
			
			float4 vert ( float4 vertex : POSITION ) : SV_POSITION
			{
				v2f o;
				o.pos = UnityObjectToClipPos(vertex);
				o.uv = v.uv;
				return o;
			}

			foxed checker(float2 uv)
			{
				float2 repeatUV = uv*10;
				float2 c = floor(repeatUV)/2;
				float checker = frac(c.x+c.y)*2;
				return checker;
			}
			
			fixed4 frag (v2f i) : SV_Target
			{
				fixed col = checker(i.uv);
				return col;
			}
			ENDCG
		}
	}	
}
ENDCG

//About the semantics of fragment shaders

Shader "Unlit/MyFirstShader"
{
	Properties
	{
		_FrontTex("FrontTex", 2d) = "white"{}
		_BackTex("BackTex", 2d) = "white"{}
	}
	
	SubShader
	{
		cull off
		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#pragma target 3.0

			sampler2D _FrontTex;
			sampler2D _BackTex;

			struct appdata
			{
				float4 vertex : POSITION;
				float2 texcoord : TEXCOORD0;
			};


			struct v2f
			{
				float4 pos : SV_POSITION;
				float2 uv : TEXCOORD0;
			};
			
			v2f vert (appdata v)
			{
				v2f o;
				o.pos=UnityObjectToClipPos(v.vertex);
				o.uv=v.texcoord;
				return o;
			}
			
			fixed4 frag (v2f i,float face:VFACE) : SV_Target
			{
				fixed4 col=1;
				col = face > 0 ? tex2D(_FrontTex,i.uv) : tex2D(_BackTex,i.uv);
				return col;
			}
			ENDCG
		}
	}	
}

1.2.2 SubShader Tags

Tags in the SubShader must be placed in tags in the SubShader. The specific parameters are as follows:

1.Queue
//The rendering queue specifies when the object is rendered. Each queue is actually indexed by an integer.
There are the following values:

Background
//With a value of 1000, the objects in this queue are rendered first.
Geometry
//The default value of Queue is 2000. It is usually used for opaque objects, such as objects and characters in the scene.
AlphaTest
//The value is 2450, which is either completely transparent or completely opaque. It is mostly used to use maps to achieve the effect of edge transparency, which is often referred to as transparent pasting in art.
Transparent
//The value is 3000, which is often used for translucent objects. When rendering, render from back to front. It is recommended to put the objects that need to be mixed into this queue.
Overlay
//A value of 4000, this render queue is used for overlay effects. The final rendering should be placed here (such as lens halo, etc.).

example

Tags{ "Queue" = "Geometry" }
//↓ customize the rendering queue:
Tags{ "Queue" = "Geometry+1" }

2.RenderType
The built-in values are as follows:
Opaque
Transparent
TransparentCutout
Background
Overlay
TreeOpaque
TreeTransparentCutout
TreeBillboard
Grass
GrassBillboard

Original link: https://zhuanlan.zhihu.com/p/46745694

Topics: Unity Shader