Custom shaders let you control how objects look in a game. They help create special effects like shiny surfaces or glowing lights.
Custom shader fundamentals in Unity
Shader "Custom/ExampleShader" { Properties { _Color ("Color", Color) = (1,1,1,1) } SubShader { Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag struct appdata { float4 vertex : POSITION; }; struct v2f { float4 pos : SV_POSITION; }; fixed4 _Color; v2f vert (appdata v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex); return o; } fixed4 frag (v2f i) : SV_Target { return _Color; } ENDCG } } }
The Properties block defines inputs you can change in the editor.
The SubShader contains the actual code that runs on the GPU.
Shader "Custom/SimpleColor" { Properties { _Color ("Color", Color) = (1,0,0,1) } SubShader { Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag struct appdata { float4 vertex : POSITION; }; struct v2f { float4 pos : SV_POSITION; }; fixed4 _Color; v2f vert(appdata v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex); return o; } fixed4 frag(v2f i) : SV_Target { return _Color; } ENDCG } } }
Shader "Custom/TextureShader" { Properties { _MainTex ("Texture", 2D) = "white" {} } SubShader { Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag sampler2D _MainTex; struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float4 pos : SV_POSITION; float2 uv : TEXCOORD0; }; v2f vert(appdata v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex); o.uv = v.uv; return o; } fixed4 frag(v2f i) : SV_Target { return tex2D(_MainTex, i.uv); } ENDCG } } }
This shader colors any object with a blue color by default. You can change the color in the Unity editor. It uses a simple vertex and fragment program to set the color.
Shader "Custom/BasicColorShader" { Properties { _Color ("Color", Color) = (0, 0.5, 1, 1) } SubShader { Tags { "RenderType"="Opaque" } Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag struct appdata { float4 vertex : POSITION; }; struct v2f { float4 pos : SV_POSITION; }; fixed4 _Color; v2f vert(appdata v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex); return o; } fixed4 frag(v2f i) : SV_Target { return _Color; } ENDCG } } FallBack "Diffuse" }
Always test your shader on simple objects first to see how it looks.
Use the Unity editor's material inspector to tweak shader properties live.
Shaders run on the graphics card, so small mistakes can cause no rendering or errors.
Custom shaders let you control how objects look by writing small programs.
They use a Properties block for inputs and a SubShader block for GPU code.
Start simple, then add effects like textures or lighting step by step.
Practice
Solution
Step 1: Understand the role of shaders
Shaders define how surfaces appear by controlling colors, lighting, and textures.Step 2: Identify what custom shaders do
Custom shaders let you write small programs to control object appearance beyond built-in options.Final Answer:
To control exactly how objects look by writing small programs -> Option AQuick Check:
Custom shader = control object look [OK]
- Confusing shaders with 3D modeling
- Thinking shaders handle game logic
- Assuming shaders manage input
Solution
Step 1: Recall Unity shader syntax
Unity shaders use CGPROGRAM to start the programmable shader code block.Step 2: Check options for correct keyword
Only CGPROGRAM is the valid keyword to begin the shader code section.Final Answer:
CGPROGRAM -> Option CQuick Check:
Shader code block starts with CGPROGRAM [OK]
- Using made-up keywords like StartShader
- Confusing CGPROGRAM with other terms
- Misspelling the keyword
fixed4 frag() : SV_Target {
return fixed4(1, 0, 0, 1);
}Solution
Step 1: Analyze the returned color vector
The function returns fixed4(1, 0, 0, 1), which means red=1, green=0, blue=0, alpha=1.Step 2: Interpret color components
Red is full intensity, green and blue are zero, alpha is fully opaque.Final Answer:
Solid red color -> Option AQuick Check:
fixed4(1,0,0,1) = red [OK]
- Mixing up color channel order
- Ignoring alpha channel
- Assuming zero means white
Shader "Custom/Simple" {
Properties {
_Color ("Color", Color) = (1,1,1,1)
}
SubShader {
Pass {
CGPROGRAM
fixed4 frag() : SV_Target {
return _Color;
}
ENDCG
}
}
}Solution
Step 1: Check Properties block syntax
The property declaration is correct: no semicolon needed, parentheses balanced.Step 2: Verify shader code block
Properties like _Color must be declared inside CGPROGRAM as 'uniform fixed4 _Color;' to be used; direct use causes undeclared identifier error.Final Answer:
_Color cannot be used directly in fragment shader -> Option BQuick Check:
Properties need uniform declaration [OK]
- Assuming semicolons are needed in Properties
- Not declaring uniform for _Color
- Thinking ENDCG is incorrect
Solution
Step 1: Understand input semantics
To access vertex position in fragment shader, use input parameter with semantic POSITION.Step 2: Check code correctness
fixed4 frag(float3 pos : POSITION) : SV_Target { return pos.x > 0 ? fixed4(1,0,0,1) : fixed4(0,0,1,1); } correctly declares pos with POSITION semantic and uses conditional operator to return red or blue.Step 3: Identify errors in other options
fixed4 frag(float3 pos) : SV_Target { if (pos.x > 0) return fixed4(1,0,0,1); else return fixed4(0,0,1,1); } lacks semantic, fixed4 frag(float3 pos : TEXCOORD0) : SV_Target { return pos.x > 0 ? fixed4(1,0,0,1) : fixed4(0,0,1,1); } uses TEXCOORD0 which is wrong for position, fixed4 frag() : SV_Target { if (POSITION.x > 0) return fixed4(1,0,0,1); else return fixed4(0,0,1,1); } uses POSITION as variable incorrectly.Final Answer:
fixed4 frag(float3 pos : POSITION) : SV_Target { return pos.x > 0 ? fixed4(1,0,0,1) : fixed4(0,0,1,1); } -> Option DQuick Check:
Use POSITION semantic for position input [OK]
- Missing POSITION semantic in input
- Using wrong semantic like TEXCOORD0
- Referencing POSITION as variable directly
Ready to prove it?
Pass the test and this pattern moves unknown
