当前位置:网站首页>Unity shader learning (3) try to draw a circle

Unity shader learning (3) try to draw a circle

2022-07-04 14:06:00 ToDoNothing

On the first code

Shader "Unlit/shader4"
{
    
    Properties
    {
    

    }
    SubShader
    {
    
        Tags {
     "RenderType"="Opaque" }
        LOD 100

        Pass
        {
    
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag


            #include "UnityCG.cginc"
        struct v2f{
    
            float4 vertex:SV_POSITION;
            float4 position:TEXCOORD1;
            float2 uv:TEXCOORD0;
        };
        v2f vert(appdata_base v){
    
            v2f o;
            o.vertex=UnityObjectToClipPos(v.vertex);
            o.position=v.vertex;
            o.uv=v.texcoord;
            return o;
        }
           
        float circle(float2 uv,float2 center){
    
            float2 offset=uv-center;
            float len=length(offset);
            return step(len,0.2)-step(len,0.19);
        } 
           

            fixed4 frag (v2f i) : SV_Target
            {
    
               fixed4 col=circle(i.uv,float2(0.5,0.5));
                return col;
            }
            ENDCG
        }
    }
}

Here's an explanation
According to the second tutorial , We are Pass Two processing flows are defined in the block , Respectively vertex and fragment, Execute first vertex Vertex shader , Processing vertex information , Proceed again fragment Chip shader , Deal with color, illumination and other information . So we define a structure at the top , Information used to define a vertex :

   struct v2f{
    
            float4 vertex:SV_POSITION;
            float4 position:TEXCOORD1;
            float2 uv:TEXCOORD0;
        };

You can see , The defined structure contains two Texcoord, Texture information , Only two groups are read here . In addition to that SV_POSITION Is the position of the vertex , except SV_POSITION, There is another parameter called POSITION, There is not much difference between the two , As follows :
POSITION: Used to store , Model in local coordinates , In model space (objcet space) The coordinates of the vertices of , Coordinates before converting to clipping space coordinates ,unity Tell our model vertex coordinates , Not converted . Can be used as vertex shader (vertex shader) The input of 、 Output ; Chip shader (frag) The input of .
SV_POSITION: Used to store , The model is in the clipping space , Location information in projection space , That is, the fixed-point coordinates of the model space , Convert to the coordinates of the clipping space , Can be used as vertex shader (vertex shader) Output ; Chip shader (frag) The input of .

Next is the processing of vertex shaders , namely vert function , Corresponding to the above #pragma vertex Name , As shown below , Input appdata_base For defined built-in variables , Never mind , The whole function returns a structure , Internal variables have been re assigned .
Such as o.vertex, Through the built-in conversion function UnityObjectToClipPos, Model space , Convert to cutting space . About model space 、 The concept of cutting space , Reference resources Render several basic coordinate spaces in the pipeline ( Object space 、 World space 、 Camera space ( Observe the space )、NDC Space 、 Cutting space 、 Screen space )

   v2f vert(appdata_base v){
    
            v2f o;
            o.vertex=UnityObjectToClipPos(v.vertex);
            o.position=v.vertex;
            o.uv=v.texcoord;
            return o;
        }

When it's done , Handle the slice shader

   fixed4 frag (v2f i) : SV_Target
            {
    
               fixed4 col=circle(i.uv,float2(0.5,0.5));
                return col;
            }

The slice shader just runs a function , Color the current point , So let's look at this function

   float circle(float2 uv,float2 center){
    
            float2 offset=uv-center;
            float len=length(offset);
            return step(len,0.2)-step(len,0.19);
        } 

circle Function has parameters and return values , Input two coordinate information , One is the coordinates of the vertex , One is the center point of the circle , First , Calculate the distance between the vertex coordinate and the center point coordinate , Reuse step Function to process .
step The logic of the function is as follows :

step (a, b)
{
    
  if (a > b) 
  {
    
    return 0;
  }
  else
  {
    
    return 1;
  }
}

therefore , Its principle is to judge the distance between the current point and the central point , Whether it is within the appropriate range , If in , return 1, Indicates that colors can be filled , Here I use two step function , Make him form a circle , In this range , Just display the color , As shown in the figure below . Two Step Subtracting the , You can judge whether it is within this range .
 Insert picture description here
The specific effect is as follows :
 Insert picture description here
If you want to change the color , Radius and center , The code is as follows

Shader "Unlit/shader4"
{
    
    Properties
    {
    
    _Radius("Radius",Float)=0.1
    _Center("Center",Vector)=(0.5,0.5,0,0)
    _LineColor("LineColor",Color)=(1,1,1,1)
    }
    SubShader
    {
    
        Tags {
     "RenderType"="Opaque" }
        LOD 100

        Pass
        {
    
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag


            #include "UnityCG.cginc"
        struct v2f{
    
            float4 vertex:SV_POSITION;
            float4 position:TEXCOORD1;
            float2 uv:TEXCOORD0;
        };
        v2f vert(appdata_base v){
    
            v2f o;
            o.vertex=UnityObjectToClipPos(v.vertex);
            o.position=v.vertex;
            o.uv=v.texcoord;
            return o;
        }
        float _Radius;
        float4 _Center;
        fixed4 _LineColor;
        float circle(float2 uv,float2 center){
    
            float2 offset=uv-center;
            float len=length(offset);
            return step(len,_Radius+0.01)-step(len,_Radius);
        } 
           

            fixed4 frag (v2f i) : SV_Target
            {
    
                float2 center=float2(_Center.x,_Center.y);
               fixed4 col=circle(i.uv,center)*_LineColor;
                return col;
            }
            ENDCG
        }
    }
}

The effect is as follows
 Insert picture description here
 Insert picture description here

原网站

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