Unity用Shader实现矩形mesh的边框,同时边框可以近大远小

这个shader原本是用做项目中矩形物体的描边,因为项目中需要描边的物体都是矩形面片,而且比较多,所以用这个比一般的描边插件要节省性能

近大远小的原理就是,计算相机空间下物体的中心的点和摄像机的距离,然后与描边宽度做权重算法

1
ShortSide是矩形的短边长度
1
SideRatio是矩形的宽高比(width/height)

下面是shader代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
Shader "UnlitEdge" {
    Properties{
        _Color("Main Color", Color) = (1,1,1,1)
        _OutlineColor("Outline Color", Color) = (1,1,1,1)
        _Outline("Outline Width", Range(0.001, 0.01)) = 0.005
        _ShortSide("Short Side", Float) = 1
        _SideRatio("SideRatio", Float) = 1
    }
 
        SubShader{
                Tags {"Queue" = "Transparent" "Queue" = "Overlay" }
                LOD 200
                ZTest Always
                Cull Off
                Cull Back
                Blend SrcAlpha OneMinusSrcAlpha
 
            Pass {
                CGPROGRAM
                    #pragma vertex vert
                    #pragma fragment frag
                    #pragma target 2.0
 
                    #include "UnityCG.cginc"
 
                    struct appdata_t {
                        float4 vertex : POSITION;
                        float2 texcoord : TEXCOORD0;
                        UNITY_VERTEX_INPUT_INSTANCE_ID
                    };
 
                    struct v2f {
                        float4 vertex : SV_POSITION;
                        float2 texcoord : TEXCOORD0;
                        float4 color : COLOR;
                        UNITY_VERTEX_OUTPUT_STEREO
                    };
 
                    float4 _Color;
                    float4 _OutlineColor;
                    float _Outline;
                    float _ShortSide;
                    float _SideRatio;
 
                    v2f vert(appdata_t v)
                    {
                        v2f o;
                        UNITY_SETUP_INSTANCE_ID(v);
                        UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
                        o.vertex = UnityObjectToClipPos(v.vertex);
                        o.texcoord = v.texcoord;
                        return o;
                    }
 
                    fixed4 frag(v2f i) : SV_Target
                    {
                        float3 center = float3(unity_ObjectToWorld._m03, unity_ObjectToWorld._m13, unity_ObjectToWorld._m23);
                        float dist = distance(_WorldSpaceCameraPos, center);
                        dist = clamp(dist / _ShortSide, 1, 50);
                        float widthX = dist * _Outline;
                        float widthY = widthX * _SideRatio;
                        if (i.texcoord.x < widthX || i.texcoord.y < widthY || i.texcoord.x >1 - widthX || i.texcoord.y > 1 - widthY)
                        {
                            i.color = _OutlineColor;
                        }
                        else
                        {
                            i.color = _Color;
                        }
                        return i.color;
                    }
                ENDCG
            }
        }
}

参考的文章:

https://blog.csdn.net/MonoBehaviour/article/details/82707795

https://blog.csdn.net/alla_Candy/article/details/129751758

https://blog.csdn.net/weixin_43933605/article/details/103815167

https://zhuanlan.zhihu.com/p/535452034

posted @   zerozabuu  阅读(176)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
点击右上角即可分享
微信分享提示