shader学习记录——画线

参考链接

Shader "Custom/LineShader"
{
    
    
    Properties
    {
    
    
        _MainTex ("Texture", 2D) = "white" {
    
    }
    }
    SubShader
    {
    
    
        Tags {
    
     "RenderType"="Opaque" }
        LOD 100

        Pass
        {
    
    
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog

            #include "UnityCG.cginc"

            struct appdata
            {
    
    
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
    
    
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            v2f vert (appdata v)
            {
    
    
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                UNITY_TRANSFER_FOG(o,o.vertex);
                return o;
            }

            //绘制斜线 k=斜率,t=偏移值
            float line_kx(float2 uv,float k,float t,float line_width)
            {
    
    
                float y = k * uv.x + t;//直线公式 y=kx+b
                return step(y, uv.y) - step(y+line_width,uv.y);
            }
            
            float line_kx_smooth(float2 uv,float k,float t,float line_width)
            {
    
    
                float y = k * uv.x + t;
                return pow(smoothstep(y-line_width,y,uv.y)-smoothstep(y,y+line_width,uv.y),20);
            }

            //利用点乘绘制两点间直线
            float line_segment_with_two_point(float2 uv, float2 start, float2 end, float line_width) {
    
    
                float2 line_vector_from_end = normalize(start - end);//结束点指向起始点的向量
                float2 line_vector_from_start = -line_vector_from_end;//起始点指向结束点的向量
                float2 st_vector_from_end = uv - float2(end.x, end.y); //结束点指向画布中任意点的向量
                float2 st_vector_from_start = uv - float2(start.x, start.y);//起始点指向画布中任意点的向量

                float proj1 = dot(line_vector_from_end, st_vector_from_end);
                float proj2 = dot(line_vector_from_start, st_vector_from_start);

                if (proj1 > 0.0 && proj2 > 0.0) {
    
    //通过点乘结果>0判断是否同相,过滤掉线段两头超出部分

                  //求结束点指向画布中任意点的向量与结束点指向起始点的向量的夹角
                    float angle = acos(dot(line_vector_from_end, st_vector_from_end) / (length(st_vector_from_end) * length(line_vector_from_end)));
                    //屏幕上任意点到直线的垂直距离
                    float dist = sin(angle) * length(st_vector_from_end);

                    return pow(1-smoothstep(0.0, line_width/2 , dist), 6.0);
                }
                else {
    
    
                    return 0.0;
                }
            }
            //正弦曲线
            float sinLine(float2 uv, float line_width) {
    
    

                // 振幅
                float amplitude = 0.08;

                // 角速度(控制波浪的周期)
                float angularVelocity = 12.0;

                // 偏距
                float b = 0.5;

                // 初相位
                float initialPhase = 0.5;

                float frequency = 12.0;
                initialPhase = frequency * _Time.y;

                float y = amplitude * sin((angularVelocity * uv.x) + initialPhase) + b;
                return smoothstep(y - line_width / 2.0, y, uv.y) - smoothstep(y, y + line_width / 2.0, uv.y);
            }

            float powLine(float2 uv, float line_width) {
    
    
                float y = pow(uv.x, 3);
                return smoothstep(y - line_width / 2.0, y, uv.y) - smoothstep(y, y + line_width / 2.0, uv.y);
            }



            fixed4 frag(v2f i) : SV_Target
            {
    
    
                 sample the texture
                //fixed4 col = tex2D(_MainTex, i.uv);
                 apply fog
                //UNITY_APPLY_FOG(i.fogCoord, col);
                i.uv -= float2(0.5,0.5);//移动中心点

                float4 line_color = float4(1,1,0,1);//线的颜色
                float4 col = float4(0.6,0.6,0.6,1);//背景色

                //横线
                //if (i.uv.y>0&&i.uv.y<0.02)//y坐标范围
                //{
    
    
                //    col = line_color;
                //}

                //float pct = step(0, i.uv.y)- step(0.02,i.uv.y);
                col = col *(1-pct)+ line_color * pct;
                //col = lerp(col,line_color,pct);//等于上一行效果,pct=0取col,pct=1取line_color

                //pow加速收敛
                float pct =pow(smoothstep(0,0.01, i.uv.y),10) -pow( smoothstep(0.01,0.02,i.uv.y),100);
                col = lerp(col, line_color, pct);

                //垂直线
                pct = pow(smoothstep(0, 0.01, i.uv.x), 10) - pow(smoothstep(0.01, 0.02, i.uv.x), 100);
                col = lerp(col, line_color, pct);

                //斜线
                pct = line_kx(i.uv,1,0,0.02);
                col = lerp(col,line_color,pct);

                pct = line_kx(i.uv,1,-0.3,0.02);
                col = lerp(col,line_color,pct);

                pct = line_kx_smooth(i.uv,-0.5,0,0.04);
                col = lerp(col,line_color,pct);

                pct = line_kx_smooth(i.uv,-0.5,0.3,0.04);
                col = lerp(col,line_color,pct);

                //两点间直线
                pct = line_segment_with_two_point(i.uv, float2(-0.1, 0.2), float2(0.4, 0.3), 0.04);
                col = lerp(col, line_color, pct);

                //正弦曲线
                i.uv.y += 0.5;
                pct = sinLine(i.uv, 0.04);
                col = lerp(col, line_color, pct);

                i.uv.y -= 0.3;
                pct = powLine(i.uv, 0.04);
                col = lerp(col, float4(0,1,1,1), pct);


                return col;
            }
            ENDCG
        }
    }
}

猜你喜欢

转载自blog.csdn.net/chillxiaohan/article/details/128205126
今日推荐