This is the first tutorial in a series of shaders tutorials in Unity 3D.
Open your Unity 3D project and using right click mouse add an Unlit shader to your project, see the image:
Rename your shader file and open this shader with right click mouse.
You will see the content of the default shader into your Visual Studio IDE.
Let’s see my shader example named NewUnlitShader :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | Shader "Unlit/NewUnlitShader" { Properties { _MainTex ("Texture", 2D) = "white" {} } SubShader { Tags { "RenderType"="Opaque" } LOD 100 Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag // make fog work #pragma multi_compile_fog #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; UNITY_FOG_COORDS(1) float4 vertex : SV_POSITION; }; sampler2D _MainTex; float4 _MainTex_ST; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = TRANSFORM_TEX(v.uv, _MainTex); UNITY_TRANSFER_FOG(o,o.vertex); return o; } fixed4 frag (v2f i) : SV_Target { // sample the texture fixed4 col = tex2D(_MainTex, i.uv); // apply fog UNITY_APPLY_FOG(i.fogCoord, col); return col; } ENDCG } } } |
When you write your first shader then you need to know some rules:
- take a look at this link to see the most common variables and HLSL type and rules;
- example: vec2 types with float2;
- example: mat2 with float2x2;
- example: vec3(1) is float3(1,1,1);
- example: mainImage(out vec4 fragColor, in vec2 fragCoord) is float4 mainImage(float2 fragCoord : SV_POSITION) : SV_Target;
- example:
- Shader “Unlit/NewUnlitShader” – the shader will add into your material from Unlit – NewUnlitShader;
- you can change the name NewUnlitShader, but you need to change the name of the file shader;
- the body of shader starts with word CGPROGRAM and end with word ENDCG;
- Shader Level of Detail (LOD) is a number (see doc);
- the Properties word is used for: inputs like a texture (see and _MainTex (“Texture”, 2D) = “white” {} );
- the SubShader word is used to start to define your settings for shader and the content of shader;
- the words like #pragma, #include, struct are reserved words and is used to set and make the body of shader;
- any shader comes with: vertex shader body and fragment shader body;
One simple example of settings for vertex and fragment body shader but also you can have pixel shader body:
1 2 3 | CGPROGRAM #pragma vertex vertex_shader #pragma fragment pixel_shader |
The next step is to add this to your shader:
1 2 3 4 5 6 7 8 | float4 vertex_shader(float4 vertex : POSITION) : SV_POSITION { ... } float4 pixel_shader(float4 vertex : SV_POSITION) : SV_TARGET { ... } |
Now, about vertex shader, this can manipulate the attributes of vertices.
The fragment shader is the same as a pixel shader.
The fragment/pixel shader is part of the rasterization steps.
You can see in my first example I used fragment shader not pixel shader: #pragma fragment frag
The result is this function :
1 2 3 4 | fixed4 frag (v2f i) : SV_Target { ... } |
This is the first part of this tutorials about shaders and you will need to learn all of this and make connections with my examples.