当前位置:网站首页>Unity shader (learn more about vertex fragment shaders)

Unity shader (learn more about vertex fragment shaders)

2022-07-07 09:25:00 heater404

Unity Shader( Learn more about vertex fragment shaders )

What is a rendering pipeline

It can be roughly divided into the following three stages :

  1. Application stage (Application Stage):

    It's our raw material preparation stage , Including our model 、 Mapping 、 Camera and light source, etc , After this stage, all materials will be converted into rendering elements and submitted to the next stage . This stage usually consists of CPU Responsible for implementation .

  2. Geometric stage (Geometry Stage):

    It mainly processes the data transmitted in the previous stage on the vertex , Including various matrix transformations and vertex coloring , After the final processing, the two-dimensional vertex coordinates of screen space will be output 、 Vertex shading and other information , And then submit to the next stage . This stage is usually in GPU On .

  3. Grating stage (Rasterizer Stage):

    This stage mainly determines which pixels in each rendering primitive should be drawn on the screen , It requires the vertex by vertex data obtained in the previous stage ( For example, texture coordinates 、 Vertex color, etc ) Interpolation , Then pixel by pixel processing . This stage is also in GPU Up operation .

Structure

 Insert picture description here

As shown in the figure above, the code , We put the vertex position information of the model in the application stage (float4 vertex : POSITION) Transmission to the geometric stage , Then use in vertex shaders UnityObjectToClipPos Matrix transformation transforms the vertex coordinates of the model from local to homogeneous clipping coordinates , And output the converted coordinates (SV_POSITION) To rasterization stage , Finally, in the rasterized slice shader, we return a color value to all pixels (_Color).

But when we think about it carefully, we will find some limitations , What if I want to pass multiple values in the application phase ? Besides vertex position, I also want to transfer vertex color 、uv What about coordinates and other information ? At the same time, now only vertex coordinates are output from the vertex shader in the geometric stage (SV_POSITION), What if I also want to pass other values to the slice shader ? It's time for the structure to come out .

Shader "Unlit/NewUnlitShader"
{
	Properties
	{
		_Color("I am Color", Color) = (1,1,1,1)// In turn RGBA(0-1)
	}
	SubShader
	{
        pass
        {
             CGPROGRAM
             //#pragma yes Unity Commands for built-in compilation instructions , stay Pass In, we use this command to declare the required vertex shaders and fragment shaders .
             #pragma vertex vert
             // Define vertex shaders , Usually it will be named vert.

             #pragma fragment frag
             // Define fragment shaders , Usually it will be named frag  

             // Structure of application stage 
             struct appdata
             {
                float4 vertex:POSITION; 
             };
             
             // The vertex shader is passed to the structure of the slice shader 
             struct v2f
             {
                float4 pos:SV_POSITION;
             };
             fixed4 _Color;

             // Vertex shaders in the geometry phase 
             v2f vert(appdata v)
             {
                 v2f o;
                 o.pos=UnityObjectToClipPos(v.vertex); 
                 return o; 
             } 
  
             // Fragment shaders in the rasterization phase 
             float4 frag():SV_TARGET0
             {
                 return _Color;
             }

             ENDCG          
        }       
	}
    FallBack "DIFFUSE"
}

Although compared with the previous version, it shows a lot more code , But this is more flexible and convenient .

Now we have some new ideas , Define multiple variables in the structure , For example, incoming vertices uv coordinate , Then we draw a checkerboard according to this information .

Shader "Unlit/NewUnlitShader"
{
	Properties
	{
        _Size("the checker's size",int) = 10// Don't end with a semicolon 
	}
	SubShader
	{
        pass
        {
             CGPROGRAM
             //#pragma yes Unity Commands for built-in compilation instructions , stay Pass In, we use this command to declare the required vertex shaders and fragment shaders .
             #pragma vertex vert
             // Define vertex shaders , Usually it will be named vert.

             #pragma fragment frag
             // Define fragment shaders , Usually it will be named frag  

             int _Size;
             // Structure of application stage 
             struct appdata
             {
                float4 vertex:POSITION; 
                float2 uv:TEXCOORD;
             };
             
             // The vertex shader is passed to the structure of the slice shader 
             struct v2f
             {
                float4 pos:SV_POSITION;
                float2 uv:TEXCOORD;
             };

             // Vertex shaders in the geometry phase 
             v2f vert(appdata v)
             {
                 v2f o;
                 o.pos=UnityObjectToClipPos(v.vertex); 
                 o.uv=v.uv;
                 return o; 
             } 

             float4 checker(float2 uv)
             {
                 uv=floor(uv * _Size)/2;
                 return frac(uv.x+uv.y)*2;// This function is built-in to find the decimal part 
             }
  
             // Fragment shaders in the rasterization phase 
             float4 frag(v2f i):SV_TARGET0
             {
                 return checker(i.uv);
             }

             ENDCG          
        }       
	}
    FallBack "DIFFUSE"
}

 Insert picture description here

UnityShader Built in functions

In fact, that is Cg Built in functions in the library , Official address: :Cg Standard Library Documentation (nvidia.cn), You can check the details when using .

Data passed into vertex shaders during the application phase

When the data in the application phase is transmitted , How can vertex shaders know who is the vertex data of the model and who is the discovery data of the model ? So we need a way to tell the computer what the variables we define represent .

    struct appdata
    {
        float4 vertex : POSITION;
    };

Here we declare a float4 Variable of type vertex, And gave him the semantics of vertex data ( Add a colon after the variable and a semantic ), in other words vertex Variables will represent the vertex data of the model, which is used and transferred by us . So what are the semantics ? as follows :

	struct appdata
	{
		float4 vertex : POSITION;		// The vertices 
		float4 tangent : TANGENT;		// Tangent line 
		float3 normal : NORMAL;			// normal 
		float4 texcoord : TEXCOORD0;	        //UV1
		float4 texcoord1 : TEXCOORD1;	        //UV2
		float4 texcoord2 : TEXCOORD2;	        //UV3
		float4 texcoord3 : TEXCOORD3;	        //UV4
		fixed4 color : COLOR;			// Vertex color 
	};

Vertex shader to fragment shader data

The vertex shader processes the data passed from the application stage , You will need to output and pass in fragment shaders , At this time, we also need to define a structure to carry the data , alike , The value output to the fragment shader also needs semantics to identify .

	struct v2f
	{
		float4 pos:SV_POSITION;
	};

It is stated here float4 Variable of type pos, And designated as SV_POSITION semantics , Express pos It is the vertex position under the screen clipping space output by the vertex shader . This statement is necessary , otherwise GPU The following rasterization processing cannot be performed .

原网站

版权声明
本文为[heater404]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202130625200338.html