Search Unity

Alpha transparency self sorting issue, help really appreciated

Discussion in 'Shaders' started by monkeybrother, Nov 26, 2010.

  1. monkeybrother

    monkeybrother

    Joined:
    Oct 14, 2010
    Posts:
    83
    Hi. I used "Strumpy's Shader Editor 3" to make a shader with diffuse, lightmap and alpha maps and settings for specular/gloss. It works beautifully, except for one thing that ruins it all. I can't get the object "sort itself" correctly. It randomly puts elements in front of other incorrectly and when it folds on itself, it blends with itself. Sorry if I don't make any sense, I'll post the shader and a picture instead.

    I'm coming up on a deadline and would appreciate any tips. I know basically nothing about shader writing, which is why I used the shader editor.

    Code (csharp):
    1.  
    2. Shader "WhiteLightmapmAlpha"
    3. {
    4.     Properties
    5.     {
    6. _Diffuse("_Diffuse", 2D) = "white" {}
    7. _Lightmap("_Lightmap", 2D) = "white" {}
    8. _GlossOchSpecferg("_GlossOchSpecferg", Color) = (1,1,1,1)
    9. _Specular("_Specular", Range(0,1) ) = 0.5
    10. _Clip("_Clip", 2D) = "white" {}
    11.  
    12.     }
    13.    
    14.     SubShader
    15.     {
    16.         Tags
    17.         {
    18. "Queue"="Transparent+100"
    19. "IgnoreProjector"="False"
    20. "RenderType"="Transparent"
    21.  
    22.         }
    23.  
    24.        
    25. Cull Back
    26. ZWrite Off
    27. ZTest LEqual
    28.  
    29.  
    30.         CGPROGRAM
    31. #pragma surface surf BlinnPhongEditor alpha vertex:vert
    32. #pragma target 2.0
    33.  
    34.  
    35. sampler2D _Diffuse;
    36. sampler2D _Lightmap;
    37. float4 _GlossOchSpecferg;
    38. float _Specular;
    39. sampler2D _Clip;
    40.  
    41.             struct EditorSurfaceOutput {
    42.                 half3 Albedo;
    43.                 half3 Normal;
    44.                 half3 Emission;
    45.                 half3 Gloss;
    46.                 half Specular;
    47.                 half Alpha;
    48.             };
    49.            
    50.             inline half4 LightingBlinnPhongEditor_PrePass (EditorSurfaceOutput s, half4 light)
    51.             {
    52. half3 spec = light.a * s.Gloss;
    53. half4 c;
    54. c.rgb = (s.Albedo * light.rgb + light.rgb * spec);
    55. c.a = s.Alpha + Luminance(spec);
    56. return c;
    57.  
    58.             }
    59.  
    60.             inline half4 LightingBlinnPhongEditor (EditorSurfaceOutput s, half3 lightDir, half3 viewDir, half atten)
    61.             {
    62.                 viewDir = normalize(viewDir);
    63.                 half3 h = normalize (lightDir + viewDir);
    64.                
    65.                 half diff = max (0, dot (s.Normal, lightDir));
    66.                
    67.                 float nh = max (0, dot (s.Normal, h));
    68.                 float3 spec = pow (nh, s.Specular*128.0) * s.Gloss;
    69.                
    70.                 half4 res;
    71.                 res.rgb = _LightColor0.rgb * (diff * atten * 2.0);
    72.                 res.w = spec * Luminance (_LightColor0.rgb);
    73.  
    74.                 return LightingBlinnPhongEditor_PrePass( s, res );
    75.             }
    76.            
    77.             struct Input {
    78.                 float4 meshUV;
    79.  
    80.             };
    81.  
    82.  
    83.             void vert (inout appdata_full v, out Input o) {
    84. float4 Vertex_VertexOutputMaster0_0_NoInput = float4(0,0,0,0);
    85. float4 Vertex_VertexOutputMaster0_1_NoInput = float4(0,0,0,0);
    86. float4 Vertex_VertexOutputMaster0_2_NoInput = float4(0,0,0,0);
    87. float4 Vertex_VertexOutputMaster0_3_NoInput = float4(0,0,0,0);
    88.  
    89. o.meshUV.xy = v.texcoord.xy;
    90. o.meshUV.zw = v.texcoord1.xy;
    91.  
    92.             }
    93.            
    94.  
    95.             void surf (Input IN, inout EditorSurfaceOutput o) {
    96.                 o.Albedo = 0.0;
    97.                 o.Normal = float3(0.0,0.0,1.0);
    98.                 o.Emission = 0.0;
    99.                 o.Gloss = 0.0;
    100.                 o.Specular = 0.0;
    101.                 o.Alpha = 1.0;
    102. float4 Pixel_Tex2D1=tex2D(_Diffuse,(IN.meshUV.xyxy).xy);
    103. float4 Pixel_Tex2D3=tex2D(_Lightmap,(IN.meshUV.xyxy).xy);
    104. float4 Pixel_Multiply0=Pixel_Tex2D1 * Pixel_Tex2D3;
    105. float4 Pixel_Tex2D2=tex2D(_Clip,(IN.meshUV.zwzw).xy);
    106. float4 Pixel_Master0_0_NoInput = float4(0,0,0,0);
    107. float4 Pixel_Master0_1_NoInput = float4(0,0,1,1);
    108. float4 Pixel_Master0_6_NoInput = float4(1,1,1,1);
    109. o.Emission = Pixel_Multiply0;
    110. o.Specular = _GlossOchSpecferg;
    111. o.Gloss = _Specular.xxxx;
    112. o.Alpha = float4( Pixel_Tex2D2.a);
    113.  
    114.             }
    115.         ENDCG
    116.     }
    117.     Fallback "Diffuse"
    118. }
    119.  

    $fasad.jpg
     
    hamokshaelzaki likes this.
  2. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    It doesn't look like you're using any semitransparency. If that's the case, then switch from alpha blending to alpha testing, and your sorting should be fine.
     
  3. monkeybrother

    monkeybrother

    Joined:
    Oct 14, 2010
    Posts:
    83
    Thanks. No, in this case, I don't use any semitransparency. How would I switch from alpha blending to alpha testing?

    Does that also mean that if I want semitransparency in the future, do I have to live with these sorting errors?
     
  4. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    To enable alpha testing, use
    Code (csharp):
    1. #pragma surface surf BlinnPhongEditor alphatest:_Cutoff vertex:vert
    ...and define _Cutoff as a float or range property. Check out the manual for details:
    Surface Shaders
    Properties

    Sorting semitransparent things is a long-standing problem in real-time 3D. Depending on how close your surfaces are to one another, different tricks are necessary to get it to work. Unfortunately the only general purpose solution is an expensive D3D 11 thing. When it comes up, bring more screenshots here.
     
    hamokshaelzaki likes this.
  5. monkeybrother

    monkeybrother

    Joined:
    Oct 14, 2010
    Posts:
    83
    Thank you very much! That was exactly what I was looking for.
     
  6. the_gnoblin

    the_gnoblin

    Joined:
    Jan 10, 2009
    Posts:
    722
    This helps in my case of complex objects with transparency:

     
  7. monkeybrother

    monkeybrother

    Joined:
    Oct 14, 2010
    Posts:
    83
    Thanks, Gnoblin. I'll try it when I get to work on monday. Where in the shader do I put that snippet?
     
  8. the_gnoblin

    the_gnoblin

    Joined:
    Jan 10, 2009
    Posts:
    722
    As far as I remember, you need to put "Pass { ColorMask 0 }" just before the first word "SubShader". Or maybe right after Tags
     
  9. monkeybrother

    monkeybrother

    Joined:
    Oct 14, 2010
    Posts:
    83
    Thank you both! I learned some useful things. I tried both, but in the end I used gnoblins suggestion. I'm sure I'll need Daniel's tip in the future.

    The reason I need a lightmap shader is that we couldn't get beast to work like we wanted and found that we had more control baking everything in VRay and doing it the old school way.

    The finished shader has slots for lightmap, diffuse (tint) and alpha, and controls for specular and glossiness. Here's how it turned out:

    $fasad_fixed.jpg

    And here's the shader, should anyone need it:

    Code (csharp):
    1.  
    2. Shader "WhiteLightmapmAlpha"
    3. {
    4.     Properties
    5.     {
    6. _Diffuse("_Diffuse", 2D) = "white" {}
    7. _Lightmap("_Lightmap", 2D) = "white" {}
    8. _GlossOchSpecferg("_GlossOchSpecferg", Color) = (0.1716418,0.1716418,0.1716418,1)
    9. _Specular("_Specular", Range(0,1) ) = 0.75
    10. // _Cutoff("_Cutoff", Range(0,1) ) = 0.5
    11. _Clip("_Clip", 2D) = "white" {}
    12.  
    13.     }
    14.  
    15.     SubShader
    16.     {
    17.         Tags
    18.         {
    19. "Queue"="Transparent+100"
    20. "IgnoreProjector"="False"
    21. "RenderType"="Transparent"
    22.  
    23.         }
    24.  
    25.             Pass {ColorMask 0}
    26. Cull Back
    27. ZWrite On
    28. ZTest LEqual
    29.  
    30.  
    31.         CGPROGRAM
    32. #pragma surface surf BlinnPhongEditor alpha vertex:vert
    33. #pragma target 2.0
    34.  
    35.  
    36. sampler2D _Diffuse;
    37. sampler2D _Lightmap;
    38. float4 _GlossOchSpecferg;
    39. float _Specular;
    40. sampler2D _Clip;
    41.  
    42.             struct EditorSurfaceOutput {
    43.                 half3 Albedo;
    44.                 half3 Normal;
    45.                 half3 Emission;
    46.                 half3 Gloss;
    47.                 half Specular;
    48.                 half Alpha;
    49.             };
    50.            
    51.             inline half4 LightingBlinnPhongEditor_PrePass (EditorSurfaceOutput s, half4 light)
    52.             {
    53. half3 spec = light.a * s.Gloss;
    54. half4 c;
    55. c.rgb = (s.Albedo * light.rgb + light.rgb * spec);
    56. c.a = s.Alpha + Luminance(spec);
    57. return c;
    58.  
    59.             }
    60.  
    61.             inline half4 LightingBlinnPhongEditor (EditorSurfaceOutput s, half3 lightDir, half3 viewDir, half atten)
    62.             {
    63.                 viewDir = normalize(viewDir);
    64.                 half3 h = normalize (lightDir + viewDir);
    65.                
    66.                 half diff = max (0, dot (s.Normal, lightDir));
    67.                
    68.                 float nh = max (0, dot (s.Normal, h));
    69.                 float3 spec = pow (nh, s.Specular*128.0) * s.Gloss;
    70.                
    71.                 half4 res;
    72.                 res.rgb = _LightColor0.rgb * (diff * atten * 2.0);
    73.                 res.w = spec * Luminance (_LightColor0.rgb);
    74.  
    75.                 return LightingBlinnPhongEditor_PrePass( s, res );
    76.             }
    77.            
    78.             struct Input {
    79.                 float4 meshUV;
    80.  
    81.             };
    82.  
    83.  
    84.             void vert (inout appdata_full v, out Input o) {
    85. float4 Vertex_VertexOutputMaster0_0_NoInput = float4(0,0,0,0);
    86. float4 Vertex_VertexOutputMaster0_1_NoInput = float4(0,0,0,0);
    87. float4 Vertex_VertexOutputMaster0_2_NoInput = float4(0,0,0,0);
    88. float4 Vertex_VertexOutputMaster0_3_NoInput = float4(0,0,0,0);
    89.  
    90. o.meshUV.xy = v.texcoord.xy;
    91. o.meshUV.zw = v.texcoord1.xy;
    92.  
    93.             }
    94.            
    95.  
    96.             void surf (Input IN, inout EditorSurfaceOutput o) {
    97.                 o.Albedo = 0.0;
    98.                 o.Normal = float3(0.0,0.0,1.0);
    99.                 o.Emission = 0.0;
    100.                 o.Gloss = 0.0;
    101.                 o.Specular = 0.0;
    102.                 o.Alpha = 1.0;
    103. float4 Pixel_Tex2D1=tex2D(_Diffuse,(IN.meshUV.xyxy).xy);
    104. float4 Pixel_Tex2D3=tex2D(_Lightmap,(IN.meshUV.xyxy).xy);
    105. float4 Pixel_Multiply0=Pixel_Tex2D1 * Pixel_Tex2D3;
    106. float4 Pixel_Tex2D2=tex2D(_Clip,(IN.meshUV.zwzw).xy);
    107. float4 Pixel_Master0_0_NoInput = float4(0,0,0,0);
    108. float4 Pixel_Master0_1_NoInput = float4(0,0,1,1);
    109. float4 Pixel_Master0_6_NoInput = float4(1,1,1,1);
    110. o.Emission = Pixel_Multiply0;
    111. o.Specular = _GlossOchSpecferg;
    112. o.Gloss = _Specular.xxxx;
    113. o.Alpha = float4( Pixel_Tex2D2.a);
    114.  
    115.             }
    116.         ENDCG
    117.     }
    118.     Fallback "Diffuse"
    119. }
    120.  
    Thanks again!