1

I have a shader that should do two passes that will render the back one front once. See the shader code below:

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

But the problem i am having is the fact that the second pass in the code is never executing. Because when i set the color for the back -pass That color never becomes visible in the on the mesh the shader (material) is applied to.

Also if i swap the passes so that the back-pass comes before the front-pass the opposite problem occurs.

EDIT
See here a picture of the front of the mesh with the material applied and a picture from the back of the same mesh with material:
Front:
FRONT
Back:
BACK

This is my very first time trying to make such a shader so all help is very much appreaciated!

FutureCake
  • 2,614
  • 3
  • 27
  • 70
  • So one side of the mesh is correctly colored front side, and the other side is invisible? And if you swap the order of the passes, one side of the mesh is still colored front side, and the other side is still invisible? – Ruzihm Nov 06 '18 at 20:01
  • yes if i understand you correctly swaping the order makes sure the the first pass is colored and the second pass isnt. So if the _backColor pas is done first this one is colored (visible) and the _FrontColor isnt. The same happens when you swap the order. In that case _FrontColor would be visible and _BackColor would not. Hope this clarifies it! – FutureCake Nov 06 '18 at 20:05
  • 1
    Please edit your question and include an image of the rendered mesh viewed from the front and from the back when the shader is coded like in the question. – Ruzihm Nov 06 '18 at 20:30
  • @Ruzihm I added two pictures one from the front and one from the back. Sorry for the late response but something came in between. – FutureCake Nov 10 '18 at 13:04

1 Answers1

0

enter image description hereenter image description hereremove this bracket

Shader "Custom/Geometry/Wireframe"

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

this made it work for me

unfortunately there is no auto complete for shaders, so its easy to miss errors like this, but your code gave me the following errors in the editor:

Parse error: syntax error unexpected '{' 3 (extra bracket on line three)

shader is not supported on this gpu ( caused by syntax error)

removing that bracket clears up the problem!

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
                }
            }
    }
Technivorous
  • 1,682
  • 2
  • 16
  • 22
  • 1
    this is a nice simple wireframe shader by the way. good work. – Technivorous Nov 10 '18 at 16:57
  • I updated the code, because maybe i made a mistake when copying. But the bracket isnt the problem for me. If i remove it the shader breaks. Still not seeing the back color sadly. Thanks but i must say i modified the shader from an example on the internet :P – FutureCake Nov 10 '18 at 21:33
  • works great for me bro. i put the whole shader in here for ya, and some pics to show you it looks nice – Technivorous Nov 11 '18 at 04:30
  • good to see it work! maybe it has to do with the renderpipline, what are u using basic 3D template or the LWRP or HDRP? i am currently working in the LWRP – FutureCake Nov 11 '18 at 12:18
  • 1
    Oh uhoh. Lwrp only allows for a single pass. That's why your having the problem you are. It will only do the first pass and it won't throw any errors. Looks like you just answered your own question. – Technivorous Nov 11 '18 at 12:34
  • Just a heads up that HDRP seems to also only run a single pass – Axle Nov 12 '18 at 04:07