Search Unity

Bug? Rendering Order changes when closer to transparent object..

Discussion in 'Shaders' started by ciprianb, Jul 28, 2014.

  1. ciprianb

    ciprianb

    Joined:
    Oct 11, 2013
    Posts:
    32
    Hi,

    I am having a weird issue with the following shader:
    Code (CSharp):
    1. Shader "Custom/light" {
    2. Properties
    3. {
    4.     _Color ("Main Color", Color) = (1,1,1,1)
    5.     _SolidAlpha ("Solid Alpha", Float) = 1
    6.     _TransparentAlpha ("Transparent Alpha", Float) = 0.5
    7.     _Cutoff ("Alpha cutoff", Float) = 0.3
    8.     _OffsetFactor ("Offset Factor", Float) = 0.3
    9.     _OffsetUnits ("Offset Units", Float) = 0.3
    10.     _Tx1 ("Texture 1", 2D) = "white" {}
    11.     _Tx2 ("Texture 2", 2D) = "white" {}
    12.     _Tx53 ("Texture 53", 2D) = "white" {}
    13.     _Tx54 ("Texture 54", 2D) = "white" {}
    14.     _Tx63 ("Texture 63", 2D) = "white" {}
    15.     _Tx64 ("Texture 64", 2D) = "white" {}
    16. }
    17.  
    18.  
    19. SubShader {
    20.     Tags {"Queue"="Background" "IgnoreProjector"="True" "RenderType"="Transparent"}  //TransparentCutout
    21.  
    22.  
    23. CGPROGRAM
    24. #pragma surface surf Lambert alphatest:_Cutoff
    25. #pragma target 3.0
    26.  
    27. sampler2D _Tx1;
    28. sampler2D _Tx2;
    29.  
    30. fixed4 _Color;
    31. float _SolidAlpha;
    32. float _TransparentAlpha;
    33.  
    34.  
    35. struct Input {
    36.     float2 uv_Tx1;
    37.     float2 uv2_Tx2;
    38. };
    39.  
    40. void surf (Input IN, inout SurfaceOutput o) {
    41.     int blockID = round(IN.uv2_Tx2.x);
    42.     fixed4 c;
    43.     if (blockID==1)
    44.     {
    45.     c = tex2D(_Tx1, IN.uv_Tx1) * _Color;
    46.     o.Albedo = c.rgb;
    47.     o.Alpha=_SolidAlpha;
    48.     return;
    49.     }
    50. }
    51.  
    52. ENDCG
    53.  
    54. CGPROGRAM
    55. #pragma surface surf Lambert alpha
    56. #pragma target 3.0
    57.  
    58. sampler2D _Tx53;
    59. sampler2D _Tx54;
    60. sampler2D _Tx63;
    61. sampler2D _Tx64;
    62.  
    63. fixed4 _Color;
    64. float _SolidAlpha;
    65. float _TransparentAlpha;
    66.  
    67. struct Input {
    68.     float2 uv_Tx53;
    69.     float2 uv2_Tx54;
    70. };
    71.  
    72. void surf (Input IN, inout SurfaceOutput o) {
    73.     int blockID = round(IN.uv2_Tx54.x);
    74.     if (blockID>64.5) return;
    75.     if (blockID<52.5) return;
    76.     fixed4 c;
    77.  
    78.     if (blockID==63)
    79.     {
    80.     c = tex2D(_Tx63, IN.uv_Tx53) * _Color;
    81.     o.Albedo = c.rgb;
    82.     o.Alpha=_TransparentAlpha;
    83.     return;
    84.     }
    85.     if (blockID==64)
    86.     {
    87.     c = tex2D(_Tx64, IN.uv_Tx53) * _Color;
    88.     o.Albedo = c.rgb;
    89.     o.Alpha=_TransparentAlpha;
    90.     return;
    91.     }
    92. }
    93. ENDCG
    94.  
    95.  
    96.  
    97.  
    98. }
    99. }
    100.  
    With Queue=Background
    - When far from overlapping transparent object - they render correctly - the closest object in front of the one which is far away
    - When getting closer, the closest object is behind the object which is far away

    With Queue=Transparent
    - When close to overlapping transparent object - they render correctly - the closest object in front of the one which is far away
    - When getting far, the closest object is behind the object which is far away

    I need to use alphatest:_Cutoff in the first part of the CGPROGRAM in order to have transparency in the second. Any other combination will render the second part as solid.
    I tried all combinations with Blending, ZTesting, ZWrite, Offset..

    Why does this happen?

    What I really want:
    - A first part CGPROGRAM which renders the solids
    - A second part CGPROGRAM which renders the transparency but on correct ordering - closest object should be on top of the object which is further. This should happen no matter how close of far we are from the first object..