Unity自定义着色器第二遍未执行

时间:2018-11-06 19:31:07

标签: unity3d shader hlsl vertex-shader wireframe

我有一个着色器,应该进行两次遍历,一次渲染一次背面。请参见下面的着色器代码:

Shader "Custom/Geometry/Wireframe"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        [PowerSlider(3.0)]
        _WireframeVal ("Wireframe width", Range(0., 0.34)) = 0.05
        _FrontColor ("Front color", color) = (1., 1., 1., 1.)
        _BackColor ("Back color", color) = (1., 1., 1., 1.)
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }

        Pass
        {
            Cull Back
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma geometry geom
            #include "UnityCG.cginc"

            struct v2g {
                float4 pos : SV_POSITION;
            };

            struct g2f {
                float4 pos : SV_POSITION;
                float3 bary : TEXCOORD0;
            };

            v2g vert(appdata_base v) {
                v2g o;
                o.pos = UnityObjectToClipPos(v.vertex);
                return o;
            }

            [maxvertexcount(3)]
            void geom(triangle v2g IN[3], inout TriangleStream<g2f> triStream) {
                g2f o;
                o.pos = IN[0].pos;
                o.bary = float3(1., 0., 0.);
                triStream.Append(o);
                o.pos = IN[1].pos;
                o.bary = float3(0., 0., 1.);
                triStream.Append(o);
                o.pos = IN[2].pos;
                o.bary = float3(0., 1., 0.);
                triStream.Append(o);
            }

            float _WireframeVal;
            fixed4 _FrontColor;

            fixed4 frag(g2f i) : SV_Target {
            if(!any(bool3(i.bary.x < _WireframeVal, i.bary.y < _WireframeVal, i.bary.z < _WireframeVal)))
                 discard;

                return _FrontColor;
            }

            ENDCG
        }

        Pass
        {
            Cull Front
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma geometry geom
            #include "UnityCG.cginc"

            struct v2g {
                float4 pos : SV_POSITION;
            };

            struct g2f {
                float4 pos : SV_POSITION;
                float3 bary : TEXCOORD0;
            };

            v2g vert(appdata_base v) {
                v2g o;
                o.pos = UnityObjectToClipPos(v.vertex);
                return o;
            }

            [maxvertexcount(3)]
            void geom(triangle v2g IN[3], inout TriangleStream<g2f> triStream) {
                g2f o;
                o.pos = IN[0].pos;
                o.bary = float3(1., 0., 0.);
                triStream.Append(o);
                o.pos = IN[1].pos;
                o.bary = float3(0., 0., 1.);
                triStream.Append(o);
                o.pos = IN[2].pos;
                o.bary = float3(0., 1., 0.);
                triStream.Append(o);
            }

            float _WireframeVal;
            fixed4 _BackColor;

            fixed4 frag(g2f i) : SV_Target {
            if(!any(bool3(i.bary.x < _WireframeVal, i.bary.y < _WireframeVal, i.bary.z < _WireframeVal)))
                 discard;

                return _BackColor;
            }

            ENDCG
        }
    }
}

但是我遇到的问题是代码中的第二遍从未执行过。因为当我为反向传递设置颜色时,该颜色永远不会在网格物体上可见,因此将着色器(材质)应用于该颜色。

此外,如果我交换通行证,以便后通证在前通证之前到来,则会出现相反的问题。

编辑
在此处看到应用了材质的网格物体正面的图片,以及在使用材质的同一网格物体背面的图片:
正面:
FRONT
返回:
BACK

这是我第一次尝试制作这样的着色器,因此非常感谢所有帮助!

1 个答案:

答案 0 :(得分:0)

enter image description here enter image description here删除该括号

Shader "Custom/Geometry/Wireframe"

{<<<<<<<<<<<<
    Properties
    {

这使它对我有用

不幸的是,着色器没有自动完成功能,因此很容易错过这样的错误,但是您的代码在编辑器中给了我以下错误:

Parse error: syntax error unexpected '{' 3(第三行的括号)

shader is not supported on this gpu(由语法错误引起)

去掉支架可以解决问题!

Shader "Custom/NewSurfaceShader" 
{


        Properties
        {
            _MainTex("Texture", 2D) = "white" {}
            [PowerSlider(3.0)]
            _WireframeVal("Wireframe width", Range(0., 0.34)) = 0.05
            _FrontColor("Front color", color) = (1., 1., 1., 1.)
            _BackColor("Back color", color) = (1., 1., 1., 1.)
        }
            SubShader
            {
                Tags { "RenderType" = "Opaque" }

                Pass
                {
                    Cull Back
                    CGPROGRAM
                    #pragma vertex vert
                    #pragma fragment frag
                    #pragma geometry geom
                    #include "UnityCG.cginc"

                    struct v2g {
                        float4 pos : SV_POSITION;
                    };

                    struct g2f {
                        float4 pos : SV_POSITION;
                        float3 bary : TEXCOORD0;
                    };

                    v2g vert(appdata_base v) {
                        v2g o;
                        o.pos = UnityObjectToClipPos(v.vertex);
                        return o;
                    }

                    [maxvertexcount(3)]
                    void geom(triangle v2g IN[3], inout TriangleStream<g2f> triStream) {
                        g2f o;
                        o.pos = IN[0].pos;
                        o.bary = float3(1., 0., 0.);
                        triStream.Append(o);
                        o.pos = IN[1].pos;
                        o.bary = float3(0., 0., 1.);
                        triStream.Append(o);
                        o.pos = IN[2].pos;
                        o.bary = float3(0., 1., 0.);
                        triStream.Append(o);
                    }

                    float _WireframeVal;
                    fixed4 _FrontColor;

                    fixed4 frag(g2f i) : SV_Target {
                    if (!any(bool3(i.bary.x < _WireframeVal, i.bary.y < _WireframeVal, i.bary.z < _WireframeVal)))
                         discard;

                        return _FrontColor;
                    }

                    ENDCG
                }

                Pass
                {
                    Cull Front
                    CGPROGRAM
                    #pragma vertex vert
                    #pragma fragment frag
                    #pragma geometry geom
                    #include "UnityCG.cginc"

                    struct v2g {
                        float4 pos : SV_POSITION;
                    };

                    struct g2f {
                        float4 pos : SV_POSITION;
                        float3 bary : TEXCOORD0;
                    };

                    v2g vert(appdata_base v) {
                        v2g o;
                        o.pos = UnityObjectToClipPos(v.vertex);
                        return o;
                    }

                    [maxvertexcount(3)]
                    void geom(triangle v2g IN[3], inout TriangleStream<g2f> triStream) {
                        g2f o;
                        o.pos = IN[0].pos;
                        o.bary = float3(1., 0., 0.);
                        triStream.Append(o);
                        o.pos = IN[1].pos;
                        o.bary = float3(0., 0., 1.);
                        triStream.Append(o);
                        o.pos = IN[2].pos;
                        o.bary = float3(0., 1., 0.);
                        triStream.Append(o);
                    }

                    float _WireframeVal;
                    fixed4 _BackColor;

                    fixed4 frag(g2f i) : SV_Target {
                    if (!any(bool3(i.bary.x < _WireframeVal, i.bary.y < _WireframeVal, i.bary.z < _WireframeVal)))
                         discard;

                        return _BackColor;
                    }

                    ENDCG
                }
            }
    }