Unity shader syntax

Previous article: TA Shader basics

shader syntax

ShaderLab+CG

Unity defines commonly used vertex-based data boxes

The default data of the following boxes is as follows, which can be flexibly changed by yourself and loaded with any data type (float, float2, float3, float4):
POSITION: location
NORMAL: normal
TANGENT: tangent
TEXCOORD0: texture coordinates
TEXCOORD(n): Define the content yourself. When the Shader Model is 2/3, there are up to 8 such boxes. If it is 4/5, there are up to 16 boxes.
COLOR0: color, in addition to COLOR1

The following are the designated uses of the system and it is best not to change:
SV_POSITION: The vertex position returned by the vertex shader
SV_Target: The color returned by the fragment shader shader to the rendering pipeline

How the vertex shader passes data to the shader shader

The vertex shader has an entry function vert, and its default passed parameter is a structure appdata. In the structure, we can assign the data in the data box (model-based vertex data) to its members. The default member is to pass the vertex Float4 vertex: POSITION for coordinates and float2 uv: TEXCOORD0; for passing texture coordinates. It is entirely up to us to decide which member variables store what data. Then we can use this structure in the vert function to perform calculations.
The data returned by vert is also a structure named v2f by default. The member variables of this structure define the data to be passed to the fragment shader shader. The storage box can be determined by yourself. The default is vertex:ST_POSITION and uv:TEXCOORD0 , where ST_POSITION is the fragment coordinate data returned to the system by the vertex shader. We do not need to modify it. Other variables such as uv are passed to the coloring shader and can be set by yourself. In the vert function, we need to calculate the data returned by v2f through the data passed in by appdata.
The vertex shader will perform triangle interpolation processing on the data v2f passed to the fragment shading shader. After interpolation, each fragment has v2f data in the same format as the vertex, and then the fragment shading shader will process the fragments one by one.

Fragment shading shader processing data

The fragment shading shader receives the interpolated data returned by the vertex shader and processes the fragments one by one.
During processing, the color that the fragment should display is calculated through information such as normal, light source position, and true color of the fragment.
After the processing is completed, the return value is the color of the fragment, which is returned to the rendering pipeline through ST_Target.

How does the CPU transfer data to the GPU

In the shader, the CPU passes data to the GPU through variables defined in CGProgram, for example:

sampler2D _MainTex;
float4 _MainTex_ST:
float3 _MyColor:
float _MyValue:

A uniform can be added in front of these variables, which can be omitted in Unity. These data are read-only and cannot be modified in the shader. However, for the convenience of operation, we can bind the data to the property panel of the material ball. Modification can be defined in the property list properties.

Properties
    {<!-- -->
        // variable name("display name", type) = default value
        _MainTex ("Texture", 2D) = "white" {<!-- -->}
        _MyPos("MyPos", Vector) = (1.0, 1.0, 1.0, 1.0)
        _MyColor ("MyColor", Color) = (1.0, 1.0, 1.0, 1.0)
        _MyValue ("MyValue", Range(0, 1.0)) = 0.5
    }

The following are the variables corresponding to the types in Properties:
Color,Vector –> float4,half4,fixed4
Range,Float –> float
2D –> Sampler2D
Cube –> SamplerCube
3D –> Sampler3D

Rendering pipeline configuration

A shader script can contain multiple SubShaders, but only one will be run. If the previous one cannot run, the later one will be run. If all SubShaders cannot run, you can specify the default shader at the end:

Fallback "VertexLit"

Each SubShader will contain several Passes, and each Pass is a complete rendering pipeline. The rendering pipeline status of the Pass can be set as follows (if written to SubShader, all SubShader Passes will be used):

Cull Back|Front|off //Set the raising mode: Cull back/front/off, the default is Back
Ztest Less|Greater|LEqual|GEqual|Equal|NotEqual|Alway //Set the rules used for depth testing
Zwrite On|Off //Turn on/off deep writing
Blend SrcFactor DstFactor //Turn on and set the blending mode

Names can be defined in pass:

name "myShader"

This way you can call it directly using this name.

Tag

Tag can be set in SubShader or Pass:
Format: Tag{“Key”=”Value” “Key2″=”Value2”}
Queue: rendering queue Qpaque/Transparent, the value of the rendering queue can be set in the material panel, its default value is based on Qpaque (2000), Tansparent (3000)
RanderType: Classifies shaders, opaque shaders/translucent shaders Qpaque/Transparent
DisableBatching: Indicate whether to use batch processing for this object “DisableBatching” = True
ForceNoShadowCasting: Controls whether shadows will be cast
IgnoreProjector: If set to True, the object will not be affected by Projector, used for translucency
CanUsePriteAtlas: If used for sprites, set to False
PreviewType: How the material is displayed in the properties panel. The default is ball. It can be set to Plane or SkyBox.
LightMode: Defines the role of this Pass in the rendering pipeline

Shader data type

Floating point type

Mainly including float (32), half (16), fixed three kinds of precision
All platform graphics cards support float, some fixed graphics cards do not support it, but if the code uses it, it will automatically replace it with float. Under normal circumstances, we can just use float.

Floating point numbers are used to represent vectors or colors:

  1. Color can be represented by 3 to 4 floating point numbers, float3–>rgb, float4–>rgba
  2. Vectors can be divided into three types (two-dimensional, three-dimensional, four-dimensional), corresponding to (x, y), (x, y, z), (x, y, z, w)

initialization:

float3 color = float3(1,0,0)
float4 view = float4(1,1,1,1)

Access (dimensionality reduction and dimensionality addition):

color.r
color.g
color.b
color.rgb // Will output three-dimensional floating point numbers
view.x
view.y
view.z
view.w
view.xy
view.xyz
float value = float4(view.xyz,1.0)
Structure
struct temp_data{<!-- -->
    int a;
    float2 b;
    uint c;
}
struct temp_data temp;
temp.a = 10
temp.b = float2(10.0,10.0)
Texture types and sampling functions
//Three texture types
sampler2D a;
samplerCUBE b;
sampler3D c;
// sampling function
float4 col = tex2D(a,i.uv);
float3 col2 = texCUBE(b,float3(1.0,0.0,0.0));
float3 col3 = tex3D(c,float3(1.0,0.0,0.0));

Color

There are two ways to describe color, and both can be converted into each other.

  1. Three components of red, green and blue, referred to as RGB
  2. Hue, saturation, brightness, or HSV for short
Bool, conditional judgment, loop statement
bool isSelf = false
int mask = 0xff
int value = 0xffffffff
// AND or NOT: & amp; & amp; || !
// Bit operations: Left shift << Right shift >> Bitwise OR | Bitwise AND & amp; Bitwise negation~ Bitwise XOR^
if(isSelf) // Conditions and loop statements are consistent with C#
{<!-- -->
    mask = mask | value;
}
else if(mask==value){<!-- -->
}
int i = 0;
while(i < 10){<!-- -->
    i + + ;
}
for(int k = 0;k < 10;k + + ){<!-- -->
}
Matrix

A matrix is a mathematical tool that describes linear transformations. By multiplying a matrix by a vector, we can map this vector to another vector. Matrix in Unity often represents the transformation of a point in N-dimensional space. Including but not limited to zoom, translation, rotation. In Unity matrices are only 4×4 at most.

//Definition of matrix
float2x2 a = float2x2(1,0,0,1);
float3x3 b = float2x2(1,0,0,1,1,0,0,1,1);
float2x3 c = float2x3(1,0,0,1,1,0);
float4 v1 = float4(1,0,0,0);
float4x4 d = float4x4(v1,v1,v1,v1);
float value = d[3][3]

Commonly used built-in functions (Cg and GLSL)

radians(degrees) // degrees to radians
degrees(radians) // radians to degrees
sin
cos
tan
asin
acos
atan
pow
exp
log:e is the base
exp2:2 to several powers
log2:2 as base
sqrt
inversesqrt: the inverse of the root sign
abs
sign
floor: round down
ceil: round up
fract: take the decimal part
mod: pass in x, y, return x-y*floor(x/y)
min
max
clamp
mix: pass in x, y, a, return x*(1-a) + y*a
step: Pass in edge,x, x is greater than or equal to edge and return 1, otherwise return 0
smoothstep: pass in edge0, edge1, x, t=clamp((x-edge0)*(edge1-edge0),0,1), return t*t*(3-2*t)
matrixCompMult(mat x,mat y): Multiply the corresponding elements of two matrices, which is not common sense matrix multiplication.
//Vector related
lessThan
lessThanEqual
greaterThan
greaterThanEqual
equal
any
all
not
// Material search
texture2D
texture2DProj
texture2DLod
texture2DProjLod
textureCube
textureCubeLod
//Geometry function
distance
faceforward
length
normalize
reflect
refract