实现Unity Scene选中物体后透视描边效果(初级版本)

@[TOC](实现Unity Scene选中物体后透视描边效果(初级版本))

这是Unity Scene视图选中物体后的描边效果
在这里插入图片描述

废话就不说了直接上代码

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Test/TestShader" {
    Properties {
        _MainTex ("Base (RGB)", 2D) = "white" {}
        _RimColor("Rim Color", Color) = (1,1,1,1)
        _RimRang("Rim Range",range(0,1)) = 0.1
    }

    SubShader {
//第一遍给正常渲染区域和遮挡区域设定模板值
        Pass
        {
            Stencil {  
                Ref 2                     //参考值为2,stencilBuffer值默认为0  
                Comp always               //stencil比较方式是永远通过  
                Pass IncrWrap              //pass的处理是加一  
                ZFail Replace            //ZFail的处理是替换  
            }  
        ZTest LEqual
        CGPROGRAM

        # include "UnityCG.cginc"

        struct v2f
        {
            float4 vertex:POSITION;
            float2 uv:TEXCOORD0;
        };
        
        sampler2D _MainTex;
        
        v2f vert(appdata_base v)
        {
            v2f o;
            o.uv = v.texcoord;
            o.vertex = UnityObjectToClipPos(v.vertex);
        
            return o;
        }

            fixed4 frag(v2f IN):COLOR
            {
                
                fixed4 c = tex2D(_MainTex, IN.uv);

                return c;
            }

            #pragma vertex vert
            #pragma fragment frag

        ENDCG
        }

//第二遍过大渲染范围,在遮挡区域不渲染,在超出和正常范围内渲染(此时渲染的就是边框,但还有缺陷)
        Pass
        {
            Stencil {
                Ref 2          //参考值为2,stencilBuffer值默认为0            
                Comp notEqual  //stencil比较方式是不等于则通过             
               
                Pass keep      //pass的处理是保持 
                ZFail decrWrap      //ZFail的处理是减一     
            }  
        Cull Front
        ZTest Always
		//ZWrite Off
        Tags { "Queue" = "Geometry-1" }

        CGPROGRAM

        #include "UnityCG.cginc"

        struct v2f
        {
            float4 vertex:POSITION;
        };

        float4 _RimColor;
        float _RimRang;

        v2f vert(appdata_base  v)
        {
            v2f o;
            fixed4 vertex = v.vertex;
            float d=distance(v.vertex.xyz,float3(0,0,0));
            vertex.xyz+=v.vertex.xyz*_RimRang;
            
            o.vertex = UnityObjectToClipPos(vertex);    

            return o;
        }

        fixed4 frag (v2f IN):COLOR
        {    
            return _RimColor;
        }

        #pragma vertex vert
        #pragma fragment frag

        ENDCG
        }

//在正常渲染范围内渲染模型(遮盖多余的边框)
    Pass
        {
            Stencil {  
                Ref 1                     //参考值为1,stencilBuffer值默认为0  
                Comp equal               //stencil比较方式是相同则通过  
                Pass replace              //pass的处理是替换,就是拿1替换buffer 的值  
                ZFail decrWrap            //ZFail的处理是溢出型减1  
            }
        Cull Back  
        ZTest NotEqual
        ZWrite Off
        CGPROGRAM

        # include "UnityCG.cginc"

        struct v2f
        {
            float4 vertex:POSITION;
            float2 uv:TEXCOORD0;
        };
        
        sampler2D _MainTex;
        
        v2f vert(appdata_base v)
        {
            v2f o;
            o.uv = v.texcoord;
            o.vertex = UnityObjectToClipPos(v.vertex);
        
            return o;
        }

            fixed4 frag(v2f IN):COLOR
            {
                
                fixed4 c = tex2D(_MainTex, IN.uv);

                return c;
            }

            #pragma vertex vert
            #pragma fragment frag

        ENDCG
        }
    }
    FallBack "Diffuse"

}

效果图:
在这里插入图片描述

复杂模型
在这里插入图片描述

在这里插入图片描述

这个效果算勉强实现上面的需求,但还有一些瑕疵,就是这个边框在不规则物体上会变得不太整齐.但优点是一个Shader搞定比较方便.

后面在进行优化升级

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值