美文网首页
模型描边OutLine

模型描边OutLine

作者: LEO_青蛙 | 来源:发表于2020-06-07 00:17 被阅读0次
描边效果

GitHub项目地址

模型描边的思路在于使用两个Pass:
第一个Pass:正常渲染模型(优化:只渲染正面)
第二个Pass:法线外扩实现描边(优化:只渲染背面)
注意:这两个Pass的顺序是有讲究的,把描边放在第二个Pass,可以通过深度测试减少overdraw。

Shader "Custom/OutLineShader"
{
    //法线外扩实现描边
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _Outline("Outline",float) = 0.1
        _OutlineColor("OutlineColor",Color) = (0,0,0,1)
    }
    SubShader
    {
        //Queue设置为Transparent-1,放在天空盒之后,透明物体之前渲染
        Tags { "RenderType"="Opaque" "Queue" = "Transparent-1" }
        LOD 100
        //正常阶段
        Pass
        {
            Cull Back
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv :TEXCOORD0;
            };
            struct v2f
            {
                float4 vertex : SV_POSITION;
                float2 uv:TEXCOORD0;
            };
            sampler2D _MainTex;     
            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                return o;
            }   
            fixed4 frag (v2f i) : SV_Target
            {
                return tex2D(_MainTex,i.uv);
            }
            ENDCG
        }
        //描边阶段放在第二个Pass,可以通过深度测试减少overdraw
        //描边阶段,法线外扩,渲染背面
        Pass
        {
            //只需要边缘外扩
            Cull Front
            ZWrite Off
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            struct appdata
            {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
            };
            struct v2f
            {
                float4 vertex : SV_POSITION;
            };
            float _Outline;
            float4 _OutlineColor;           
            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                //把法线转换到视图空间
                float3 vnormal = mul((float3x3)UNITY_MATRIX_IT_MV,v.normal);
                //把法线转换到投影空间
                float2 pnormal_xy = mul((float2x2)UNITY_MATRIX_P,vnormal.xy);
                //朝法线方向外扩
                o.vertex.xy = o.vertex.xy + pnormal_xy * _Outline;
                //如果想描边大小不会随着深度而变化,则乘以o.vertex.w,因为裁剪空间到屏幕空间会做齐次除法
                //o.vertex.xy = o.vertex.xy + pnormal_xy * o.vertex.w * _Outline;
                return o;
            }
            fixed4 frag (v2f i) : SV_Target
            {
                return _OutlineColor;
            }
            ENDCG
        }
    }
}

相关文章

网友评论

      本文标题:模型描边OutLine

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