How to make the hidden edges to be rendered as dashed lines and remove unnecessary diagonals in Wireframe shaders?

by Mira   Last Updated December 06, 2018 10:13 AM

I am currently working on the wireframe shaders which is working. I managed to have some sort of dashed wire whenever the the edges is hidden from the view but I am having problem with certain views of the camera where some supposed to be visible edges would be rendered as dashed lines and the dashed lines itself is not in constant sizes and spacing between the lines.

enter image description here

I am also troubled at removing the unnecessary diagonals since the script supposed to remove it but, probably the shader does not recognize it as a diagonal lines.

enter image description here

Above image is the opposite view from the first image btw.

Here is the shader:

Shader "Custom/Geometry/WireframeSample"
{
    Properties
    {
        [PowerSlider(3.0)]
        _WireframeVal ("Wireframe width", Range(0., 0.5)) = 0.05
        _RepeatCount("Repeat Count", float) = 5
		_Spacing("Spacing", float) = 0.5
		_Offset("Offset", float) = 0
        _FrontColor ("Front color", color) = (1., 1., 1., 1.)
        _BackColor ("Back color", color) = (1., 1., 1., 1.)
        [Toggle] _RemoveDiag("Remove diagonals?", Float) = 0.
    }
    SubShader
    {
        Tags { "Queue"="Geometry" "RenderType"="Opaque" }
       
        Pass
        {
            Cull Front
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma geometry geom
 
            // Change "shader_feature" with "pragma_compile" if you want set this keyword from c# code
            #pragma shader_feature __ _REMOVEDIAG_ON
 
            #include "UnityCG.cginc"

            float _RepeatCount;
	        float _Spacing;
	        float _Offset;
 
            struct v2g {
                float4 worldPos : SV_POSITION;
            };
 
            struct g2f {
                float4 pos : SV_POSITION;
                float3 bary : TEXCOORD0;
            };
 
            v2g vert(appdata_base v) {
                v2g o;
                o.worldPos = mul(unity_ObjectToWorld, v.vertex);
                return o;
            }
 
            [maxvertexcount(3)]
            void geom(triangle v2g IN[3], inout TriangleStream<g2f> triStream) {
                float3 param = float3(0., 0., 0.);
 
                #if _REMOVEDIAG_ON
                float EdgeA = length(IN[0].worldPos - IN[1].worldPos);
                float EdgeB = length(IN[1].worldPos - IN[2].worldPos);
                float EdgeC = length(IN[2].worldPos - IN[0].worldPos);
               
                if(EdgeA > EdgeB && EdgeA > EdgeC)
                    param.y = 1.;
                else if (EdgeB > EdgeC && EdgeB > EdgeA)
                    param.x = 1.;
                else
                    param.z = 1.;
                #endif
 
                g2f o;

                o.pos = mul(UNITY_MATRIX_VP, IN[0].worldPos);
                o.bary = float3(1.+ _Offset, 0., 0.)* _RepeatCount * (1.0f + _Spacing) + param;
                triStream.Append(o);
                o.pos = mul(UNITY_MATRIX_VP, IN[1].worldPos);
                o.bary = float3(0., 0., 1.+ _Offset)* _RepeatCount * (1.0f + _Spacing) + param;
                triStream.Append(o);
                o.pos = mul(UNITY_MATRIX_VP, IN[2].worldPos);
                o.bary = float3(0., 1.+ _Offset, 0.)* _RepeatCount * (1.0f + _Spacing) + param;
                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
        }
 
        Pass
        {
            Cull Back
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma geometry geom
 
            // Change "shader_feature" with "pragma_compile" if you want set this keyword from c# code
            #pragma shader_feature __ _REMOVEDIAG_ON
 
            #include "UnityCG.cginc"
 
            struct v2g {
                float4 worldPos : SV_POSITION;
            };
 
            struct g2f {
                float4 pos : SV_POSITION;
                float3 bary : TEXCOORD0;
            };
 
            v2g vert(appdata_base v) {
                v2g o;
                o.worldPos = mul(unity_ObjectToWorld, v.vertex);
                return o;
            }
 
            [maxvertexcount(3)]
            void geom(triangle v2g IN[3], inout TriangleStream<g2f> triStream) {
                float3 param = float3(0., 0., 0.);
 
                #if _REMOVEDIAG_ON
                float EdgeA = length(IN[0].worldPos - IN[1].worldPos);
                float EdgeB = length(IN[1].worldPos - IN[2].worldPos);
                float EdgeC = length(IN[2].worldPos - IN[0].worldPos);
               
                if(EdgeA > EdgeB && EdgeA > EdgeC)
                    param.y = 1.;
                else if (EdgeB > EdgeC && EdgeB > EdgeA)
                    param.x = 1.;
                else
                    param.z = 1.;
                #endif
 
                g2f o;
                o.pos = mul(UNITY_MATRIX_VP, IN[0].worldPos);
                o.bary = float3(1., 0., 0.) + param;
                triStream.Append(o);
                o.pos = mul(UNITY_MATRIX_VP, IN[1].worldPos);
                o.bary = float3(0., 0., 1.) + param;
                triStream.Append(o);
                o.pos = mul(UNITY_MATRIX_VP, IN[2].worldPos);
                o.bary = float3(0., 1., 0.) + param;
                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
        }
    }
}

Sorry for the long post. Any ideas? Thanks a bunch.



Related Questions


Unity: Simple “pass through” geometry shader

Updated March 31, 2017 09:13 AM

Outline of plane slice of arbitrary object

Updated May 22, 2015 21:05 PM

Toon/cel shading with variable line width?

Updated November 15, 2018 15:13 PM

Transform vertices in a line differently?

Updated October 16, 2017 23:13 PM

Geometry shader and triangle adjacency

Updated June 01, 2015 00:05 AM