when writing a CG or HLSL shader program, we need to use semantics (Semantic) to indicate the "intent" of the input and output variables.
For example, this section of the shader code:
shader "CUSTOM/VF" {Properties {_maintex ("Base (RGB)", 2D) = "white" {}} subshader {Tags {"R Endertype "=" Opaque "} LOD $ Pass {Tags {" Lightmode "=" forwardbase "} cgprogram #pragma multi_ Compile_fwdbase #pragma vertex vert #pragma fragment frag #include "unitycg.cginc" sampler2d _main
Tex;
FLOAT4 _maintex_st;
struct A2V {float4 vertex:position;
Fixed3 Normal:normal;
Fixed4 texcoord:texcoord0;
Fixed4 Color:color;
};
struct V2F {float4 pos:position;
FLOAT2 uv:texcoord0;
};
v2f Vert (a2v v) {v2f o;
Transform the vertex to projection space O.pos = Mul (UNITY_MATRIX_MVP, V.vertex);
Get the UV coordinates o.uv = Transform_tex (V.texcoord, _maintex);
return o;
} float4 Frag (v2f i): COLOR {fixed4 texcolor = tex2d (_maintex, I.UV);
return texcolor; } ENDCG}} FallBack "Diffuse"}
The A2V structure where the variables are separated by colons is semantics.
A2V as input to the Vert function, the semantics it identifies are used to tell unity what kind of data we need.
Also, we see that the color semantics are added to the Frag method name, which tells unity that the method outputs a color value, and unity can then write the color value to the GPU.
You may notice that the vert output Frag input v2f the variables in the structure also use semantics. Most of the semantics you can use freely, in order to facilitate the transfer of data between Vert and Frag, but with one exception, is:
FLOAT4 pos:position;
This must be declared as FLOAT4 type, and add Position (or sv_position, the difference will be discussed later). Because the GPU needs to know the coordinates of the vertex transition to the clipping space (refer to the shader (16) coordinate space and the transformation matrix), this coordinate is provided by vertex shader.
Direct3D 10 defines a new type of semantics called System numerical Semantics (system-value semantics), all of which begin with Sv_. For example POSITION corresponds to sv_position,color corresponding to sv_target,depth corresponding to sv_depth (depth). Although there is no obvious difference between them for developers, the compatibility between platforms has caused us problems, such as that Xbox One only supports SV semantics, and Direct3D 9 does not support SV semantics (so Windows has its own home fight). So the development of the time also need to pay attention.
In addition, there are several special semantics:
vpos: screen pixel coordinates, for fragment shaders, need to add #pragma target 3.0 compilation instructions. For example:
Shader "Unlit/screen Position" {Properties {_maintex ("Texture", 2D) = "white" {}} Subshader
{Pass {cgprogram #pragma vertex vert #pragma fragment Frag #pragma target 3.0//Note:no sv_position in this struct struct v2f {float
2 uv:texcoord0;
}; v2f Vert (Float4 vertex:position,//vertex POSITION input float2 uv:texcoord0,//TE
xture coordinate input out FLOAT4 outpos:sv_position//Clip space POSITION Output)
{v2f o;
O.UV = UV;
Outpos = Unityobjecttoclippos (vertex);
return o;
} sampler2d _maintex; Fixed4 Frag (v2f i, Unity_vpos_type screenpos:vpos): sv_target {//Screenpos.xy would conta In Pixel integer COORdinates.
Use them to implement a checkerboard pattern that skips rendering//4x4 blocks of pixels
Checker value would be negative for 4×4 blocks of pixels//in a checkerboard pattern
Screenpos.xy = Floor (SCREENPOS.XY * 0.25) * 0.5;
float Checker =-frac (SCREENPOS.R + SCREENPOS.G);
Clip HLSL instruction stops rendering a pixel if value is negative clip (checker);
For pixels that were kept, read the texture and output it fixed4 C = tex2d (_maintex, I.UV);
return C; } ENDCG}}}
Because for most platforms, the vPOS semantic adornment's screen coordinate variable type is FLOAT4, but for Direct3D9 it does FLOAT2, so use Unity_vpos_type as the Screenpos type.
Vface: If the rendered face is facing the camera and is used for the fragment shader, the #pragma target 3.0 compiler directive needs to be added. For example:
Shader "Unlit/face Orientation"
{
Properties
{
_colorfront ("Front color", Color) = (1,0.7,0.7,1)
_colorback ("Back Color", color) = (0.7,1,0.7,1)
}
Subshader
{
Pass
{
cull off//Turn off backface culling
cgprogram
#pragma vertex vert
#pragma fragment Frag
#pragma target 3.0
float4 vert (float4 vertex:position): sv_position
{
return Unityobjecttoclippos (vertex);
}
Fixed4 _colorfront;
Fixed4 _colorback;
Fixed4 frag (fixed facing:vface): Sv_target
{
//Vface input positive for frontbaces,
//negative for BA Ckfaces. Output one
//of the colors depending on that.
Return facing > 0? _colorfront: _colorback;
}
ENDCG
}}}
Sv_vertexid: This is an unsigned shaping variable that represents the ID of the vertex for the vertex shader and needs to add the #pragma target 3.5 compilation instructions. For example:
Shader "Unlit/vertexid"
{
subshader
{
Pass
{
cgprogram
#pragma vertex vert
# pragma fragment Frag
#pragma target 3.5
struct V2F {
fixed4 color:texcoord0;
FLOAT4 pos:sv_position;
};
v2f Vert (
float4 vertex:position,//vertex POSITION input
uint VID:SV_VERTEXID//vertex ID, needs to BES u int
)
{
v2f o;
O.pos = Unityobjecttoclippos (vertex);
Output funky colors based on vertex ID
float f = (float) vid;
O.color = Half4 (sin (f/10), sin (f/100), sin (f/1000), 0) * 0.5 + 0.5;
return o;
}
Fixed4 Frag (v2f i): Sv_target
{
return i.color;
}
ENDCG
}}}