Search Unity

Vertex displacement shader not working with screen space depth-based edge detection

Discussion in 'Shaders' started by wedgiebee, Jun 12, 2020.

  1. wedgiebee

    wedgiebee

    Joined:
    Aug 9, 2016
    Posts:
    40
    I'm using Unity's Vector Graphics package and this free Outline asset from the asset store to put outlines around my vector images. I set the shader's "Queue" to "Geometry" and "RenderType" to "Opaque", and I then tweaked the vector shader to do some vertex displacement that makes the vectors look like they're wiggling! Unfortunately, the outline acts as if the vertex displacement isn't happening and draws an outline around what the object would look like if no vertices were being displaced.



    From what I understand, the depth buffer isn't getting properly updated with the displaced vertex positions. I tried writing a custom ShadowCaster pass from stuff I found online, but had no luck getting the outline to change in any way.

    Here is my shader code:


    Code (CSharp):
    1. Shader "Unlit/OpaqueJitterVector"
    2. {
    3.     Properties
    4.     {
    5.         [PerRendererData] _MainTex("Sprite Texture", 2D) = "white" {}
    6.         _Color("Tint", Color) = (1,1,1,1)
    7.         _NoiseTex("Noise Texture", 2D) = "white" {}
    8.         _Intensity("Intensity", Float) = 0.05
    9.         [MaterialToggle] PixelSnap("Pixel snap", Float) = 0
    10.         [HideInInspector] _RendererColor("RendererColor", Color) = (1,1,1,1)
    11.         [HideInInspector] _Flip("Flip", Vector) = (1,1,1,1)
    12.         [PerRendererData] _AlphaTex("External Alpha", 2D) = "white" {}
    13.         [PerRendererData] _EnableExternalAlpha("Enable External Alpha", Float) = 0
    14.     }
    15.  
    16.         SubShader
    17.         {
    18.             Tags
    19.             {
    20.                 "Queue" = "Geometry"
    21.                 "IgnoreProjector" = "True"
    22.                 "RenderType" = "Opaque"
    23.                 "PreviewType" = "Plane"
    24.                 "CanUseSpriteAtlas" = "True"
    25.             }
    26.  
    27.             Cull Off
    28.             Lighting Off
    29.             ZWrite Off
    30.             Blend One OneMinusSrcAlpha
    31.  
    32.             Pass
    33.             {
    34.  
    35.             Tags {"LightMode" = "ForwardBase"}
    36.  
    37.             CGPROGRAM
    38.                 #pragma vertex VectorVert
    39.                 #pragma fragment SpriteFrag
    40.                 #pragma target 2.0
    41.                 #pragma multi_compile_instancing
    42.                 #pragma multi_compile _ PIXELSNAP_ON
    43.                 #pragma multi_compile _ ETC1_EXTERNAL_ALPHA
    44.                 #include "UnitySprites.cginc"
    45.  
    46.                 sampler2D _NoiseTex;
    47.                 float _Intensity;
    48.  
    49.                 v2f VectorVert(appdata_t IN)
    50.                 {
    51.                     v2f OUT;
    52.  
    53.                     UNITY_SETUP_INSTANCE_ID(IN);
    54.                     UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
    55.  
    56.                     OUT.vertex = UnityFlipSprite(IN.vertex, _Flip);
    57.  
    58.                     float interval = 0.15f; // seconds between change
    59.                     float t = floor(_Time.y/interval);
    60.                     t = t % 3; // this is the number of variants
    61.                     t *= 0.1f; // this is necessary because the t's can't all be multiples of 1
    62.                     float4 hi = float4(IN.vertex.x + t, IN.vertex.y + t, 0, 0);
    63.                     half noiseVal = tex2Dlod(_NoiseTex, hi).r;
    64.                     OUT.vertex.x += noiseVal * _Intensity;
    65.  
    66.                     OUT.vertex = UnityObjectToClipPos(OUT.vertex);
    67.                     OUT.texcoord = IN.texcoord;
    68.  
    69.                     #ifdef UNITY_COLORSPACE_GAMMA
    70.                     fixed4 color = IN.color;
    71.                     #else
    72.                     fixed4 color = fixed4(GammaToLinearSpace(IN.color.rgb), IN.color.a);
    73.                     #endif
    74.  
    75.                     OUT.color = color * _Color * _RendererColor;
    76.  
    77.                     #ifdef PIXELSNAP_ON
    78.                     OUT.vertex = UnityPixelSnap(OUT.vertex);
    79.                     #endif
    80.  
    81.                     return OUT;
    82.                 }
    83.             ENDCG
    84.             }
    85.         }
    86. }
    87.  
    And I can't post the outline code since it's from someone else's asset but here's a link to it. (It's free!)
     

    Attached Files:

  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    I mean, personally, I think that looks cool like that.

    But, the problem comes down to the fact the outline you're using is making use of the camera depth normal texture, or something similar. That works by rendering your view with a replacement shader. That takes everything in the scene and replaces the shader they use with a different shader, using the
    RenderType
    tag to match them with a pass in the replacement shader. You're using
    Opaque
    as the
    RenderType
    , which means it'll render your objects with this shader like it will any other opaque object, which is to say with no vertex wiggle at all. If you want it to have the vertex wiggle, you need to change your shader's
    RenderType
    , and add a new pass with that type and the wiggle, to the camera depth normals replacement shader being used.