Search Unity

Culling front does not working in my shader

Discussion in 'Shaders' started by galuodo, Aug 18, 2018.

  1. galuodo

    galuodo

    Joined:
    Jan 28, 2013
    Posts:
    3
    Hi all,

    I am trying to make a outline shade which show the outline when blocked, however I found that the front face culling seems not working after I set ztest to always.

    Is there something I forget to set or mistake i made?

    Thank you.

    Code (CSharp):
    1. Pass{
    2.  
    3.  
    4.                
    5.                 ZTest always
    6.                 ZWrite Off
    7.                 Cull Front
    8.                 Tags{ "Queue" = "Geometry" }
    9.                 CGPROGRAM
    10. #pragma vertex vert
    11. #pragma fragment frag
    12. #include "UnityCG.cginc"
    13.                
    14.             struct v2f {
    15.                 float4 pos : SV_POSITION;
    16.                 fixed4 color : COLOR;
    17.             };
    18.  
    19.             v2f vert(appdata_base v)
    20.             {
    21.                 v2f o;
    22.                 //    o.pos = UnityObjectToClipPos(v.vertex + v.normal *0.01);
    23.                 float4x4 view = (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
    24.                 float thickness = 1.04f;
    25.                 view._m00 = thickness;
    26.                 view._m11 = thickness;
    27.                 view._m22 = thickness;
    28.                 view._m33 = 1;
    29.                 o.pos = UnityObjectToClipPos(mul(view ,v.vertex));
    30.                 o.color = (1,0,0,1);
    31.  
    32.  
    33.                 return o;
    34.             }
    35.  
    36.             fixed4 frag(v2f i) : SV_Target{
    37.                 i.color.r = 0.4 + 0.5 * sin(_Time.w * 2) + 7;
    38.                 i.color.g = 0.7 + 0.5 * sin(_Time.w * 2) +1;
    39.                 i.color.b = 0.4 + 0.5 * sin(_Time.w * 2 + 2);
    40.             return i.color; }
    41.  
    42.                 ENDCG
    43.             }
    1.png 2.png
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    Culling is likely working correctly. I'm guessing you have two passes in your shader, and the outline is the second one. Because you've set ZTest Always, if the base cube pass renders first, it'll be hidden by the outline pass because you've told the shader to ignore the depth buffer and render over everything. That includes the cube.

    Move the outline pass before the main pass so that it renders over everything, but the cube draws afterward.

    Also, you don't need a matrix here. Just;
    v.vertex.xyz *= 1.04;
     
  3. galuodo

    galuodo

    Joined:
    Jan 28, 2013
    Posts:
    3
    Yes, it works, thank you.
     
  4. galuodo

    galuodo

    Joined:
    Jan 28, 2013
    Posts:
    3
    Hi, bgolus,
    your method solve the problem, however, bring a new issue, the outline is missing when overlap with another cube? can you give me a hint how to solve this? Thank you. 3.png
     
  5. brownboot67

    brownboot67

    Joined:
    Jan 5, 2013
    Posts:
    375
    Disable batching. But be aware of the fallout of doing so...
     
  6. vx4

    vx4

    Joined:
    Dec 11, 2012
    Posts:
    181
    Is don't think there is solution to this problem except by doing outline effect in post processing which take depth buffer and normal buffer as input and based on input there will be outline.
    Here some shader to do outline
    Code (CSharp):
    1. Shader "Glow/Glow_Depth_2Pass"
    2. {
    3.     Properties
    4.     {
    5.         _MainTex ("Texture", 2D) = "white" {}
    6.         _sf("Scale factor",Float) = 1
    7.         _nf("Normals Facor",Float) = 0
    8.         _c("glow color",Color) = (0,1,1,0)
    9.     }
    10.     SubShader
    11.     {
    12.         Tags { "RenderType"="Opaque" }
    13.         LOD 100
    14.  
    15.         Pass
    16.         {
    17.             CGPROGRAM
    18.             #pragma vertex vert
    19.             #pragma fragment frag
    20.  
    21.          
    22.             #include "UnityCG.cginc"
    23.  
    24.             struct appdata
    25.             {
    26.                 float4 vertex : POSITION;
    27.                 float2 uv : TEXCOORD0;
    28.             };
    29.  
    30.             struct v2f
    31.             {
    32.                 float2 uv : TEXCOORD0;
    33.                 float4 vertex : SV_POSITION;
    34.             };
    35.  
    36.             sampler2D _MainTex;
    37.             float4 _MainTex_ST;
    38.          
    39.             v2f vert (appdata v)
    40.             {
    41.                 v2f o;
    42.                 o.vertex = UnityObjectToClipPos(v.vertex);
    43.                 o.uv = TRANSFORM_TEX(v.uv, _MainTex);
    44.                 return o;
    45.             }
    46.          
    47.             fixed4 frag (v2f i) : SV_Target
    48.             {
    49.                 // sample the texture
    50.                 fixed4 col = tex2D(_MainTex, i.uv);
    51.                 return col;
    52.             }
    53.             ENDCG
    54.         }
    55.             Pass
    56.             {
    57.                 Cull  Front
    58.                 CGPROGRAM
    59.                 #pragma vertex vert
    60.                 #pragma fragment frag
    61.  
    62.  
    63.                 #include "UnityCG.cginc"
    64.  
    65.                 struct appdata
    66.             {
    67.                 float4 vertex : POSITION;
    68.                 float2 uv : TEXCOORD0;
    69.                 float3 normal : NORMAL;
    70.             };
    71.  
    72.             struct v2f
    73.             {
    74.                 float2 uv : TEXCOORD0;
    75.                 float4 vertex : SV_POSITION;
    76.             };
    77.  
    78.             sampler2D _MainTex;
    79.             float4 _MainTex_ST;
    80.             float4 _c;
    81.             float _sf, _nf;
    82.             v2f vert(appdata v)
    83.             {
    84.                 v2f o;
    85.                 v.vertex.xyz = v.vertex.xyz*_sf + v.normal*_nf;
    86.                 o.vertex = UnityObjectToClipPos(v.vertex);
    87.                 o.uv = TRANSFORM_TEX(v.uv, _MainTex);
    88.                 return o;
    89.             }
    90.  
    91.             fixed4 frag(v2f i) : SV_Target
    92.             {
    93.                 // sample the texture
    94.                 //fixed4 col = tex2D(_MainTex, i.uv);
    95.             return _c;
    96.             }
    97.                 ENDCG
    98.             }
    99.     }
    100. }
    And this another using Stencil
    Code (CSharp):
    1. Shader "Glow/Stencil"
    2. {
    3.     Properties
    4.     {
    5.         _MainTex("Texture", 2D) = "white" {}
    6.     _sf("Scale factor",Float) = 1
    7.         _nf("Normals Facor",Float) = 0
    8.         _c("glow color",Color) = (0,1,1,0)
    9.     }
    10.         SubShader
    11.     {
    12.         Tags{ "RenderType" = "Opaque" }
    13.         LOD 100
    14.  
    15.         Pass
    16.     {
    17.         Stencil{
    18.             Comp Always
    19.             Ref 1
    20.             Pass Replace
    21.         ReadMask 1
    22.         WriteMask 1
    23.         }
    24.         CGPROGRAM
    25. #pragma vertex vert
    26. #pragma fragment frag
    27.  
    28.  
    29. #include "UnityCG.cginc"
    30.  
    31.         struct appdata
    32.     {
    33.         float4 vertex : POSITION;
    34.         float2 uv : TEXCOORD0;
    35.     };
    36.  
    37.     struct v2f
    38.     {
    39.         float2 uv : TEXCOORD0;
    40.         float4 vertex : SV_POSITION;
    41.     };
    42.  
    43.     sampler2D _MainTex;
    44.     float4 _MainTex_ST;
    45.  
    46.     v2f vert(appdata v)
    47.     {
    48.         v2f o;
    49.         o.vertex = UnityObjectToClipPos(v.vertex);
    50.         o.uv = TRANSFORM_TEX(v.uv, _MainTex);
    51.         return o;
    52.     }
    53.  
    54.     fixed4 frag(v2f i) : SV_Target
    55.     {
    56.         // sample the texture
    57.         fixed4 col = tex2D(_MainTex, i.uv);
    58.     return col;
    59.     }
    60.         ENDCG
    61.     }
    62.         Pass
    63.     {
    64.         Stencil{
    65.         Comp NotEqual
    66.         Ref 1
    67.         Pass Keep
    68.         ReadMask 1
    69.         WriteMask 1
    70.         }
    71.         CGPROGRAM
    72. #pragma vertex vert
    73. #pragma fragment frag
    74.  
    75.  
    76. #include "UnityCG.cginc"
    77.  
    78.         struct appdata
    79.     {
    80.         float4 vertex : POSITION;
    81.         float2 uv : TEXCOORD0;
    82.         float3 normal : NORMAL;
    83.     };
    84.  
    85.     struct v2f
    86.     {
    87.         float2 uv : TEXCOORD0;
    88.         float4 vertex : SV_POSITION;
    89.     };
    90.  
    91.     sampler2D _MainTex;
    92.     float4 _MainTex_ST;
    93.     float4 _c;
    94.     float _sf, _nf;
    95.     v2f vert(appdata v)
    96.     {
    97.         v2f o;
    98.         v.vertex.xyz = v.vertex.xyz*_sf + v.normal*_nf;
    99.         o.vertex = UnityObjectToClipPos(v.vertex);
    100.         o.uv = TRANSFORM_TEX(v.uv, _MainTex);
    101.         return o;
    102.     }
    103.  
    104.     fixed4 frag(v2f i) : SV_Target
    105.     {
    106.         // sample the texture
    107.         //fixed4 col = tex2D(_MainTex, i.uv);
    108.         return _c;
    109.     }
    110.         ENDCG
    111.     }
    112.     }
    113. }