Unity Shader 轮廓线实现异常

试图用shader代码实现轮廓线的渲染
实现思路:采用两次渲染,将顶点延法线外扩实现轮廓线

具体代码如下:

Shader "Unlit/coonShader"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _OutlineWidth("Outline Width", Range(0.01, 1)) = 1 //轮廓线宽度和颜色接口
        _OutLineColor("OutLine Color", Color) = (0.5,0.5,0.5,1)
    }
    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;

            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);
            return col;
        }
        ENDCG
    }

             
             Pass
        {
            // 开启前向剔除 表示剔除前面 只显示背面
           Cull Front
            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;
            // 法线
            float3 normal : NORMAL;
        };

        struct v2f
        {
            float2 uv : TEXCOORD0;
            float4 vertex : SV_POSITION;
        };

        sampler2D _MainTex;
        float4 _MainTx_ST;

        // 线条宽度
        float _OutlineWidth;
        // 线条颜色
        float4 _OutLineColor;



        v2f vert(appdata v)
        {
            v2f o;
            UNITY_INITIALIZE_OUTPUT(v2f, o);
            // 顶点沿着法线方向外扩(放大模型)
            float4 newVertex = float4(v.vertex.xyz + v.normal * _OutlineWidth * 0.01 ,1);
            // UnityObjectToClipPos(v.vertex) 将模型空间下的顶点转换到齐次裁剪空间
            o.vertex = UnityObjectToClipPos(newVertex);
            return o;
        }

        fixed4 frag(v2f i) : SV_Target
        {
            // 返回线条色彩
            return _OutLineColor;
}

     ENDCG
}
        


       
    }
}
在初次应用的过程中,发现无论如何调整轮廓线粗细,无法看见效果,如下图

img


多次尝试无果,于是将代码中pass的部分前后交换,发现有了效果,对outline width调整也有效果,但是黑色部分完全遮盖住了纹理,如下图

img

希望知道如和能实现正确的轮廓线效果,并且我明明是跟着教程一样的操作,怎么会出现这样的问题

我在尝试的过程中加入了下图方框中的代码

img


结果就是出现了轮廓描边,但是纹理颜色又无法显示了

img

还是得靠我自己(傲娇)
总体上来说还是渲染管线上的问题。我使用的是URP,在URP中是并不建议使用两个pass的,因此确实需要更改某些模式:
正常的Pass需要加入Tags { "LightMode" = "UniversalForward" }
而对于需要额外的Pass时则需要加入Tags { "LightMode" = "SRPDefaultUnlit" }
具体这方面的介绍在Unity官方文档中:https://docs.unity3d.com/cn/Packages/com.unity.render-pipelines.universal@12.1/manual/urp-shaders/urp-shaderlab-pass-tags.html@12.1/manual/urp-shaders/urp-shaderlab-pass-tags.html
但是同时又产生了个问题:(暂时的主观认识)我过去认为,固定渲染管线是无法编写shader的,但是既然固定管线能够编写shader并使用,为何要开发可编程渲染管线?所以很显然,可编程管线与固定渲染管线的不同并不是能不能编写shader。固定管线应当也是能够进行顶点和片元着色器的,但是那为什么又叫固定管线呢?难道是不能进行几何着色器?这应当需要了解学习固定管线的原理。希望以后的学习中能够完善我的认知。

你好,我是有问必答小助手,非常抱歉,本次您提出的有问必答问题,技术专家团超时未为您做出解答


本次提问扣除的有问必答次数,已经为您补发到账户,我们后续会持续优化,扩大我们的服务范围,为您带来更好地服务。