美文网首页
Unity3D 模板测试实现平面描边(一)

Unity3D 模板测试实现平面描边(一)

作者: 雄关漫道从头越 | 来源:发表于2019-07-23 21:34 被阅读0次

最近群里有个朋友想做个平面描边,使用模型的描边不起作用,想来应该是模型的描边是通过计算模型背面的法线向外扩散来实现描边的,而纯平面背面一般不存在顶点,所以无法实现描边。之前在学习opengl的时候,记得模板测试有个例子就是用模板测试来实现描边,于是按照同样的思路尝试在Unity3D中实现平面描边。其实核心思路非常简单,就是一个pass正常绘制,并写入一个模板缓存值,另一个pass将平面进行扩大,然后进行模板测试,扩大部分顶点可以测试通过,原来区域的顶点无法通常模板测试,得到一个外边框区域,填充上颜色就是需要的描边。

首先在Properties中加入_Expand 和_OutlineCol属性,分别用于调节描边的宽度和颜色

Properties {
     ... 
     _Expand ("Thickness", Range(1,1.5)) = 1.2//放大系数,影响描边的粗细
     _OutlineCol ("Outline Color", Color) = (0,1,0,1)//描边的颜色
}

第一个pass正常绘制,并且总是通过模板测试,然后将值1写入模板缓存区

//模板测试总是通过,并写入模板缓存区值为1
Stencil
{
     Ref 1
     Comp always
     Pass replace
     Fail keep
     ZFail keep
}

第二个pass中对顶点坐标三个轴向放大

fixed4 _OutlineCol;//描边的颜色
float _Expand;//放大系数,影响描边的粗细

v2f vert (appdata v)
{
    v2f o;
    v.vertex.xyz *= _Expand;//对象空间中将顶点坐标放大
    o.vertex = UnityObjectToClipPos(v.vertex);
    return o;
}

在第二个pass中对第一个pass中写入的模板值1进行反向测试,这样的目的就是为了使放大的区域通过模板测试,正常的区域丢弃。

Stencil
{
    Ref 1
    Comp notequal
    Pass decrWrap
    Fail keep
    ZFail keep
}

效果如下:

平面描边

可以通过Thickness 调节放大系数来调节描边的粗细,Outline Color调节描边的颜色。
好了,最后给出完整代码。 如果原来的平面有自带的shader,直接合并关键代码部分即可。

Shader "Custom/PlaneOutline" {
Properties {
    _MainTex ("Base (RGB)", 2D) = "white" {}
    _Color ("Color", Color) = (1,1,1,1)
    //------------关键代码---------
    _Expand ("Thickness",Range(1,1.5)) = 1.1
    _OutlineCol ("Outline Color", Color) = (0,1,0,1)
    //------------关键代码---------
}

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

    Pass {
        //------------关键代码---------
        //模板测试总是通过,并写入模板缓存区值为1
        Stencil
        {
            Ref 1
            Comp always
            Pass replace
            Fail keep
            ZFail keep
        }
        //------------关键代码---------

        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;
            UNITY_FOG_COORDS(1)
            UNITY_VERTEX_OUTPUT_STEREO
        };

        sampler2D _MainTex;
        float4 _MainTex_ST;
        fixed4 _Color;

        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 = TRANSFORM_TEX(v.texcoord, _MainTex);
            return o;
        }

        fixed4 frag (v2f i) : SV_Target
        {
            fixed4 col = tex2D(_MainTex, i.texcoord);
            col = col * _Color;
            UNITY_OPAQUE_ALPHA(col.a);
            return col;
        }
        ENDCG
    }

    //------------关键代码---------
    Pass {
        //模板缓存区的值与1比较,不相同即测试失败,并保持模板缓存区的值不变
        Stencil
        {
            Ref 1
            Comp notequal
            Pass decrWrap
            Fail keep
            ZFail keep
        }

        CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag
        #pragma target 2.0

        #include "UnityCG.cginc"

        struct appdata {
            float4 vertex : POSITION;
        };

        struct v2f {
            float4 vertex : SV_POSITION;
        };

        fixed4 _OutlineCol;
        float _Expand;

        v2f vert (appdata v)
        {
            v2f o;
            v.vertex.xyz *= _Expand;//对象空间中将顶点坐标放大
            o.vertex = UnityObjectToClipPos(v.vertex);
            return o;
        }

        fixed4 frag (v2f i) : SV_Target
        {
            return _OutlineCol;
        }
    ENDCG
    }
    //------------关键代码---------
}
}

相关文章

  • Unity3D 模板测试实现简单多边形描边(二)

    多边形或轮廓等距离外扩或收缩 前两天刚刚用模板测试实现了平面的描边效果,详见Unity3D 模板测试实现平面描边(...

  • Unity3D 模板测试实现平面描边(一)

    最近群里有个朋友想做个平面描边,使用模型的描边不起作用,想来应该是模型的描边是通过计算模型背面的法线向外扩散来实现...

  • CSS 文本描边效果

    text-shadow 实现文本描边 text-stroke 实现文本描边 text-stroke 是 ext-s...

  • Android TextView字体描边

    原文:链接地址 今天公司要求做一个字体描边功能,在网上搜到一个不错的,可以实现改变文字描边宽度和描边颜色,功能实现...

  • ios开发文字内描边效果

    实现了外描边效果之后,产品问内描边好做吗,我说简单!简单个蛋! 因为苹果本身的描边效果,是双向描边,不是单侧的,见...

  • AE实现内描边和外描边

    AE并没有直接提供内描边和外描边选项,不过可以通过“位移路径”实现。 点击“图层”下方“内容”的“添加”按钮。 选...

  • 使用CommandBuffer实现描边效果

    使用CommandBuffer实现描边效果 1.什么是CommandBuffer2.C#脚本常用命令3.描边实现思...

  • 【iOS UI篇】Label描边+发光字

    本文介绍如何给Label实现酷炫的描边+外发光效果,虽然实现简单,但是网上资料却是很少。 绘制实现描边 继承Lab...

  • kotlin 工厂方法

    写接口 创建模板 , 方便以后扩展功能 3)实现接口的 4)实现模板类 5)测试

  • ios 文字外描边效果

    设计提出文字描边效果,但是富文本自带的文字描边效果,是向文字内外同时描边 效果 所以需要自己实现,采用的方法是重写...

网友评论

      本文标题:Unity3D 模板测试实现平面描边(一)

      本文链接:https://www.haomeiwen.com/subject/mpvalctx.html