This article starts learning Unity Shader from scratch.
Start by creating a Unity Shader (Surface Shader):
Shader "Custom/NewSurfaceShader"
{
Properties
{
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_Glossiness ("Smoothness", Range(0,1)) = 0.5
_Metallic ("Metallic", Range(0,1)) = 0.0
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
#pragma surface surf Standard fullforwardshadows
#pragma target 3.0
sampler2D _MainTex;
struct Input
{
float2 uv_MainTex;
};
half _Glossiness;
half _Metallic;
fixed4 _Color;
UNITY_INSTANCING_BUFFER_START(Props)
UNITY_INSTANCING_BUFFER_END(Props)
void surf (Input IN, inout SurfaceOutputStandard o)
{
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}
This Unity Shader code defines a custom Surface Shader that is used to render surfaces with basic physical properties such as color, glossiness, and metallic feel. Let's explain each part in detail:
Shader Declaration#
Shader "Custom/NewSurfaceShader"
This line declares a new Shader and names it "Custom/NewSurfaceShader". This name can be found and applied to game objects in Unity's material editor.
Properties#
This section of code defines the parameters that the Shader receives from the outside to modify in the Inspector panel.
To see the specific results, you need to create a new material first, then select the Shader created earlier in the Shader of the material's Inspector panel. After that, you can see the properties defined in the Properties section of the Shader code:
Let's analyze the syntax of Properties:
_PropertyName ("Display Name", PropertyType) = DefaultValue
The corresponding declaration in the Shader code can be explained as follows:
Properties {
_Color ("Color", Color) = (1,1,1,1) // Defines a color property with a default value of white.
_MainTex ("Albedo (RGB)", 2D) = "white" {} // Defines a 2D texture property with a default white texture.
_Glossiness ("Smoothness", Range(0,1)) = 0.5 // Defines a float property between 0 and 1 to represent the smoothness of the surface.
_Metallic ("Metallic", Range(0,1)) = 0.0 // Defines a float property between 0 and 1 to represent the metallic feel of the material.
}
SubShader#
The SubShader
block defines the actual rendering logic. If a Shader contains multiple SubShaders, Unity will choose the most suitable one based on hardware and performance.
Tags { "RenderType"="Opaque" }
: Specifies that this Shader is used for rendering opaque objects.LOD 200
: Sets the level of detail (LOD) of the Shader, which affects rendering performance and quality.
CGPROGRAM#
The code between CGPROGRAM
and ENDCG
is the actual Shader code written in Cg/HLSL.
#pragma surface surf Standard fullforwardshadows
Declares the lighting and shadow settings for this Shader.
In Unity's Shader code, #pragma directives are used to provide specific compilation instructions to the compiler.
#pragma surfaceasdasd
This part is specific to Surface Shaders, which tells Unity that this is a Surface Shader and begins to define the properties and behavior of this Shader.
surf
is a custom function defined after the Shader code, which Unity calls to determine various properties such as glossiness and color when rendering each pixel.
standard
indicates the use of the Physically Based Rendering (PBR) model in Unity, which is a commonly used rendering model.
fullforwardshadows
is an option that enables full shadow casting in the forward rendering path. This means that all types of lights, including directional lights, point lights, and spotlights, are correctly calculated for shadows in the Shader. This is particularly important for applications that require complex lighting and shadow effects in games or scenes. Not using this option may result in inaccurate shadow rendering under certain light sources or a decrease in shadow quality.
#pragma target 3.0
: Specifies Shader Model 3.0 to achieve better lighting effects.
sampler2D _MainTex;
defines a 2D texture sampler. In the Shader, texture sampling is used to read pixel data from textures, typically storing basic diffuse maps.
In CG, a texture map is generally a memory of 3 or 4 channels (depending on whether there is an alpha channel, each channel is 8 bits) and the sampler helps us automatically calculate the correspondence between each pixel and coordinate as well as the offset.
input
structure defines the input data structure. In this case, the input structure defines uv_MainTex
as a float2 type, representing the UV coordinates of the main texture.
half _Glossiness
defines a half
variable (a low-precision floating-point type that occupies less memory), which is used to control the smoothness of the material. Similarly, _Metallic
variable controls the metallic feel of the material. _Color
is of type fixed4
(a low-precision quaternion) and is used to store the base color of the material.
The next two lines about GPU instancing support instructions, pass.
The surf
function is the core of the Shader, which calculates the surface properties of the material and is responsible for shading the material.
surf function#
In Unity's Surface Shader, the surf
function is a core component that defines the visual properties of the material surface. This function processes the input and outputs the result to a specific data structure that describes how the surface of the object interacts with light.
Execution process:
Input: The surf
function takes an Input
structure as a parameter, which contains all the necessary input data, such as UV coordinates, normals, etc., depending on the Shader's definition. In your code example, the Input
structure contains uv_MainTex
, which represents the UV coordinates of the main texture.
Multiple invocations: During the rendering process, Unity calls the surf
function for each pixel or vertex. For each pixel, it uses the corresponding input data (such as texture coordinates and other available vertex data) to calculate the output of the surface.
Output: The output is achieved by modifying the second parameter of the surf
function, which is a writable SurfaceOutputStandard
structure. This structure contains various properties that determine the final appearance of the pixel, such as albedo, metallic, smoothness, and alpha. These properties simulate the behavior of real-world materials based on their physical properties.
Impact on material effect: The data output by the surf
function is used by Unity's rendering engine to calculate the final pixel color, taking into account the lighting model and lighting conditions in the scene. This way, the color of each pixel is dynamically calculated based on its specific surface characteristics and the lighting conditions in the scene.
The above is the complete code content of creating a new shader.