Search Unity

Question Shader with alpha is causing zbuffer anomalies

Discussion in 'Shaders' started by guy123, Dec 9, 2020.

  1. guy123

    guy123

    Joined:
    May 18, 2011
    Posts:
    16
    Hello everyone,

    I'm a Unity Surface shader noob so apologies in advance, hopefully this is a simple fix. I'm trying to have a shader that bends any object using it over the horizon a-la animal crossing. I've achieved this now thanks to the great help I received on here, and through the informative links provided.

    I now however have an issue regarding alpha transparency. In our game we use a few textures with alpha maps (and emissive maps), however when I apply the tags
    Code (CSharp):
    1. Tags { "Queue" = "Transparent" "RenderType" = "Transparent" }
    the faces of the model become un-sorted and are drawn in the incorrect order (please see attached image).

    My current shader code is as follows:


    Code (CSharp):
    1. Shader "Custom/CurvedHorizonShader"
    2. {
    3.     Properties
    4.     {
    5.         _Color ("Color", Color) = (1,1,1,1)
    6.         _MainTex ("Albedo (RGB)", 2D) = "white" {}
    7.         _Glossiness ("Smoothness", Range(0,1)) = 0.5
    8.         _Metallic ("Metallic", Range(0,1)) = 0.0
    9.         _Emission ("Emission", Color) = (0,0,0,0)
    10.         _Curvature ("Curvature", Float) = 0.001
    11.     }
    12.     SubShader
    13.     {
    14.         Tags { "Queue" = "Transparent" "RenderType" = "Transparent" }
    15.         LOD 200
    16.  
    17.         CGPROGRAM
    18.         // Physically based Standard lighting model, and enable shadows on all light types
    19.         #pragma surface surf Standard vertex:vert alpha:fade fullforwardshadows
    20.  
    21.         // Use shader model 3.0 target, to get nicer looking lighting
    22.         #pragma target 3.0
    23.  
    24.         sampler2D _MainTex;
    25.  
    26.         struct Input
    27.         {
    28.             float2 uv_MainTex;
    29.         };
    30.  
    31.         half _Glossiness;
    32.         half _Metallic;
    33.         fixed4 _Color;
    34.         fixed4 _Emission;
    35.         float _Curvature;
    36.  
    37.         void vert(inout appdata_full v)
    38.         {
    39.             // Transform the vertex coordinates from model space into world space
    40.             float4 vv = mul(unity_ObjectToWorld, v.vertex);
    41.  
    42.             // Now adjust the coordinates to be relative to the camera position
    43.             vv.xyz -= _WorldSpaceCameraPos.xyz;
    44.  
    45.             // Reduce the y coordinate (i.e. lower the "height") of each vertex based
    46.             // on the square of the distance from the camera in the z axis, multiplied
    47.             // by the chosen curvature factor
    48.             vv = float4(0.0f, (vv.z * vv.z) * -_Curvature, 0.0f, 0.0f);
    49.  
    50.             // Now apply the offset back to the vertices in model space
    51.             v.vertex += mul(unity_WorldToObject, vv);
    52.         }
    53.  
    54.         // Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
    55.         // See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
    56.         // #pragma instancing_options assumeuniformscaling
    57.         UNITY_INSTANCING_BUFFER_START(Props)
    58.             // put more per-instance properties here
    59.         UNITY_INSTANCING_BUFFER_END(Props)
    60.  
    61.         void surf (Input IN, inout SurfaceOutputStandard o)
    62.         {
    63.             // Albedo comes from a texture tinted by color
    64.             fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
    65.             o.Albedo = c.rgb;
    66.             // Metallic and smoothness come from slider variables
    67.             o.Metallic = _Metallic;
    68.             o.Smoothness = _Glossiness;
    69.             o.Alpha = c.a;
    70.             o.Emission = _Emission;
    71.         }
    72.         ENDCG
    73.     }
    74.     FallBack "Diffuse"
    75. }
    76.  
     

    Attached Files:

  2. whitexroft

    whitexroft

    Joined:
    Oct 22, 2012
    Posts:
    48
    Transparent object do not sort by distance to pixel, rather distance to pivot of the entire object.
    With default Culling option this is what you get - front faced polygons blended onto each other.
    Order independent transparency is not a trivial task, but before you try to tackle, consider that having a lot of transparent object is very costly, especially for mobile platforms. Try using cutout where you can, or separate transparent surfaces into objects on their own.
    Another option is pixel dithering, where opaque pixels are being skipped
     
    Last edited: Dec 11, 2020
  3. guy123

    guy123

    Joined:
    May 18, 2011
    Posts:
    16
    Thanks whitexroft.

    This makes sense, essentially all I was trying to do was mimic the standard shader, if there was a way I could not define a fragment shader at all that would be great!

    The large majority of models in the game will not be using alpha, so I'm more than happy to split the shaders. How would I go about using cutout?

    Is there a way I can keep the autogenerated surface fragment shader?