Unity Custom Shader второй проход не выполняется - PullRequest
0 голосов
/ 06 ноября 2018

У меня есть шейдер, который должен сделать два прохода, которые будут рендерить заднюю часть одного фронта один раз. Смотрите код шейдера ниже:

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
        }
    }
}

Но у меня проблема в том, что второй проход в коде никогда не выполняется. Потому что, когда я устанавливаю цвет для обратного прохода, этот цвет никогда не становится видимым в сетке, к которой применяется шейдер (материал).

Также, если я поменяю местами проходы так, чтобы обратный проход пришел раньше переднего прохода, возникнет противоположная проблема.

EDIT
Смотрите здесь изображение передней части сетки с нанесенным материалом и изображение задней части той же сетки с материалом:
Спереди:
FRONT
Назад:
BACK

Я впервые пытаюсь создать такой шейдер, поэтому вся помощь очень важна!

1 Ответ

0 голосов
/ 10 ноября 2018

enter image description hereenter 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
                }
            }
    }
...