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!

4
  • 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? Commented Nov 6, 2018 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! Commented Nov 6, 2018 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. Commented Nov 6, 2018 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. Commented Nov 10, 2018 at 13:04

1 Answer 1

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
                }
            }
    }
Sign up to request clarification or add additional context in comments.

6 Comments

this is a nice simple wireframe shader by the way. good work.
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
works great for me bro. i put the whole shader in here for ya, and some pics to show you it looks nice
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
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. 😉
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.