Search Unity

Dithered Solids

Discussion in 'Shaders' started by writerofworlds, Dec 18, 2019.

  1. writerofworlds

    writerofworlds

    Joined:
    Jun 16, 2015
    Posts:
    3
    I have a fog image effect that uses the depth map, so it draws over transparent materials. I had an idea for a solid material that could become 'transparent' by cutting out pixels instead. It still has to write to the depth map, otherwise near objects would remove all the fog from behind them. I'm going to use the effect as little as I can, just for fading out enemies and items, maybe for a few small windows, etc. It's almost complete, the only problem is that flat areas now have striped shadowing when they should be fully lit. Also, I'm not sure if I've set up the passes the correct way. Does anyone have any ideas? Thank you!

    Code (CSharp):
    1. Shader "Dithered Solid"
    2. {
    3.     Properties
    4.     {
    5.         _Color("Color", Color) = (1,1,1,1)
    6.         _Cutoff ("Alpha cutoff", Range(0,1)) = 0.5
    7.         _Transparency ("Transparency", Range(0,1)) = 0.5
    8.                
    9.         _Metallic("Metallic", Range(0.0, 1.0)) = 0
    10.         _Glossiness("Smoothness", Range(0.0, 1.0)) = 0.5
    11.        
    12.         [Enum(UnityEngine.Rendering.CullMode)] _Culling ("Cull Mode", Int) = 2
    13.     }
    14.  
    15.     CGINCLUDE
    16.    
    17.     half4 _Color;
    18.     half _Glossiness;
    19.     half _Metallic;
    20.  
    21.     float _Transparency;
    22.  
    23.     struct Input
    24.     {
    25.         float4 color : COLOR;
    26.         float4 screenPos;
    27.     };
    28.  
    29.     void surf(Input IN, inout SurfaceOutputStandard o)
    30.     {
    31.         const float4x4 thresholdMatrix =
    32.         {
    33.         1,9,3,11,
    34.         13,5,15,7,
    35.         4,12,2,10,
    36.         16,8,14,6
    37.         };
    38.         float2 pixelPos = IN.screenPos.xy / IN.screenPos.w * _ScreenParams.xy;
    39.         float threshold = thresholdMatrix[pixelPos.x % 4][pixelPos.y % 4] / 17;
    40.        
    41.         float ditheredAlpha = 1;
    42.         if (threshold > _Transparency) ditheredAlpha = 0;
    43.  
    44.         o.Albedo = _Color.rgb;
    45.         o.Alpha = _Color.a * ditheredAlpha;
    46.         o.Metallic = _Metallic;
    47.         o.Smoothness = _Glossiness;
    48.     }
    49.     ENDCG
    50.  
    51.     SubShader
    52.     {
    53.         Tags { "LightMode" = "ShadowCaster" }
    54.         Cull [_Culling]
    55.         CGPROGRAM
    56.         #pragma surface surf Standard alphatest:_Cutoff fullforwardshadows addshadow keepalpha
    57.         #pragma target 3.0
    58.         ENDCG
    59.     }
    60.  
    61.     SubShader
    62.     {  
    63.         Tags { "RenderType" = "TransparentCutout" "Queue" = "AlphaTest" }
    64.         Cull [_Culling]
    65.         CGPROGRAM
    66.         #pragma surface surf Standard alphatest:_Cutoff fullforwardshadows addshadow
    67.         #pragma target 3.0
    68.         ENDCG
    69.     }
    70.     FallBack "Diffuse"
    71. }
     

    Attached Files:

  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,348
    You don’t have any passes in your shader, and shouldn’t, since the surface shader will generate them for you. You also shouldn’t have a light mode defined for a sub shader, those should only be used on a Pass, which again the Surface Shader should be generating for you and setting proper light mode tags on. You also shouldn’t have two sub shaders at all unless they’re being used to define different shaders for different platforms.

    Try deleting the entire first SubShader.