shader学习记录——SDF绘制图形

参考链接

Shader "Unlit/SDFShader"
{
    
    
    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;


            float sdCircle(float2 p,float r)
            {
    
    
                return length(p)-r; //到圆表面的距离
            }
   
            float sdBox(float2 p,float2 b)
            {
    
    
                float2 d = abs(p) - b;
                return length(max(d,0))+min(max(d.x,d.y),0);
            }
     
            float sdBoxRadius(float2 p, float2 b, float radius)
            {
    
    
                float2 d = abs(p) - b;
                return length(max(d,0)) + min(max(d.x, d.y),0) - radius;
            }

            //通过端点和宽度绘制矩形
            float sdOrientedBox(float2 p, float2 a, float2 b, float th)
            {
    
    
                float l = length(b - a);
                float2 d = (b - a) / l;
                float2 q = (p - (a + b) * 0.5);
                q = mul(float2x2(d.x, -d.y, d.y, d.x), q);
                q = abs(q) - float2(l, th) * 0.5;
                return length(max(q, 0.0)) + min(max(q.x, q.y), 0.0);
            }
            float sdSegment(float2 p, float2 a, float2 b)
            {
    
    
                float2 pa = p - a, ba = b - a;
                float h = clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0);
                return length(pa - ba * h);
            }

            //菱形
            float ndot(float2 a, float2 b) {
    
     return a.x * b.x - a.y * b.y; }
            float sdRhombus(float2 p, float2 b)
            {
    
    
                p = abs(p);
                float h = clamp(ndot(b - 2.0 * p, b) / dot(b, b), -1.0, 1.0);
                float d = length(p - 0.5 * b * float2(1.0 - h, 1.0 + h));
                return d * sign(p.x * b.y + p.y * b.x - b.x * b.y);
            }
            //梯形
            float dot2(float2 v) {
    
     return dot(v, v); }
            float sdTrapezoid(float2 p, in float r1, float r2, float he)
            {
    
    
                float2 k1 = float2(r2, he);
                float2 k2 = float2(r2 - r1, 2.0 * he);
                p.x = abs(p.x);
                float2 ca = float2(p.x - min(p.x, (p.y < 0.0) ? r1 : r2), abs(p.y) - he);
                float2 cb = p - k1 + k2 * clamp(dot(k1 - p, k2) / dot2(k2), 0.0, 1.0);
                float s = (cb.x < 0.0 && ca.y < 0.0) ? -1.0 : 1.0;
                return s * sqrt(min(dot2(ca), dot2(cb)));
            }
            //三角形
            float sdTriangle(float2 p, float2 p0, float2 p1, float2 p2)
            {
    
    
                float2 e0 = p1 - p0, e1 = p2 - p1, e2 = p0 - p2;
                float2 v0 = p - p0, v1 = p - p1, v2 = p - p2;
                float2 pq0 = v0 - e0 * clamp(dot(v0, e0) / dot(e0, e0), 0.0, 1.0);
                float2 pq1 = v1 - e1 * clamp(dot(v1, e1) / dot(e1, e1), 0.0, 1.0);
                float2 pq2 = v2 - e2 * clamp(dot(v2, e2) / dot(e2, e2), 0.0, 1.0);
                float s = sign(e0.x * e2.y - e0.y * e2.x);
                float2 d = min(min(float2(dot(pq0, pq0), s * (v0.x * e0.y - v0.y * e0.x)),
                    float2(dot(pq1, pq1), s * (v1.x * e1.y - v1.y * e1.x))),
                    float2(dot(pq2, pq2), s * (v2.x * e2.y - v2.y * e2.x)));
                return -sqrt(d.x) * sign(d.y);
            }
            //水滴形
            float sdUnevenCapsule(float2 p, float r1, float r2, float h)
            {
    
    
                p.x = abs(p.x);
                float b = (r1 - r2) / h;
                float a = sqrt(1.0 - b * b);
                float k = dot(p, float2(-b, a));
                if (k < 0.0) return length(p) - r1;
                if (k > a * h) return length(p - float2(0.0, h)) - r2;
                return dot(p, float2(a, b)) - r1;
            }
            //扇形
            float sdPie(float2 p, float2 c, float r)
            {
    
    
                p.x = abs(p.x);
                float l = length(p) - r;
                float m = length(p - c * clamp(dot(p, c), 0.0, r)); // c=sin/cos of aperture
                return max(l, m * sign(c.y * p.x - c.x * p.y));
            }
            //圆角三角形
            float sdTriangleRadius(in float2 p, in float2 p0, in float2 p1, in float2 p2, float cornerRadius)
            {
    
    
                float2 e0 = p1 - p0, e1 = p2 - p1, e2 = p0 - p2;
                float2 v0 = p - p0, v1 = p - p1, v2 = p - p2;
                float2 pq0 = v0 - e0 * clamp(dot(v0, e0) / dot(e0, e0), 0.0, 1.0);
                float2 pq1 = v1 - e1 * clamp(dot(v1, e1) / dot(e1, e1), 0.0, 1.0);
                float2 pq2 = v2 - e2 * clamp(dot(v2, e2) / dot(e2, e2), 0.0, 1.0);
                float s = sign(e0.x * e2.y - e0.y * e2.x);
                float2 d = min(min(float2(dot(pq0, pq0), s * (v0.x * e0.y - v0.y * e0.x)),
                    float2(dot(pq1, pq1), s * (v1.x * e1.y - v1.y * e1.x))),
                    float2(dot(pq2, pq2), s * (v2.x * e2.y - v2.y * e2.x)));
                return -sqrt(d.x) * sign(d.y) - cornerRadius;
            }



            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;
            }

            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.0,1.0,0.0,1);
                float4 color = float4(0.6,0.6,0.6,1);//背景色
                float pct = 0.0;

                //pct = sdCircle(i.uv,_SinTime.z);

                color = lerp(color,line_color,pct);

                //color = lerp(color, line_color,1-smoothstep(0,0.01,pct));

                //pct = sdBox(i.uv,float2(0.3,0.3));
                //pct = sdBoxRadius(i.uv, float2(0.3,0.3), 0.02);
                //pct = sdOrientedBox(i.uv, float2(-0.3, -0.3),float2(0.3,0.6), 0.02);
                //pct = sdSegment(i.uv,float2(-0.3,-0.3),float2(0.3,0.6));
                //pct = sdRhombus(i.uv, float2(0.5, 0.3));
                //pct = sdTrapezoid(i.uv, 0.4, 0.2, 0.4);
                //pct = sdTriangle(i.uv, float2(-0.3, 0.0), float2(0.3, 0.0), float2(0.0, 0.5));
                //pct = sdUnevenCapsule(i.uv, 0.3, 0.2, _SinTime.z*0.5);
                //pct = sdPie(i.uv, float2(_SinTime.z*0.3, 0.1), 0.3);
                pct = sdTriangleRadius(i.uv, float2(-0.3, 0.0), float2(0.3, 0.0), float2(0.0, 0.4), 0.05);

                color = lerp(color, line_color, 1 - smoothstep(0, 0.01, pct));


                return color;
            }
            ENDCG
        }
    }
}

猜你喜欢

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