Alpha transparency self sorting issue, help really appreciated

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.

Shader "WhiteLightmapmAlpha"
{
	Properties 
	{
_Diffuse("_Diffuse", 2D) = "white" {}
_Lightmap("_Lightmap", 2D) = "white" {}
_GlossOchSpecferg("_GlossOchSpecferg", Color) = (1,1,1,1)
_Specular("_Specular", Range(0,1) ) = 0.5
_Clip("_Clip", 2D) = "white" {}

	}
	
	SubShader 
	{
		Tags
		{
"Queue"="Transparent+100"
"IgnoreProjector"="False"
"RenderType"="Transparent"

		}

		
Cull Back
ZWrite Off
ZTest LEqual


		CGPROGRAM
#pragma surface surf BlinnPhongEditor alpha vertex:vert
#pragma target 2.0


sampler2D _Diffuse;
sampler2D _Lightmap;
float4 _GlossOchSpecferg;
float _Specular;
sampler2D _Clip;

			struct EditorSurfaceOutput {
				half3 Albedo;
				half3 Normal;
				half3 Emission;
				half3 Gloss;
				half Specular;
				half Alpha;
			};
			
			inline half4 LightingBlinnPhongEditor_PrePass (EditorSurfaceOutput s, half4 light)
			{
half3 spec = light.a * s.Gloss;
half4 c;
c.rgb = (s.Albedo * light.rgb + light.rgb * spec);
c.a = s.Alpha + Luminance(spec);
return c;

			}

			inline half4 LightingBlinnPhongEditor (EditorSurfaceOutput s, half3 lightDir, half3 viewDir, half atten)
			{
				viewDir = normalize(viewDir);
				half3 h = normalize (lightDir + viewDir);
				
				half diff = max (0, dot (s.Normal, lightDir));
				
				float nh = max (0, dot (s.Normal, h));
				float3 spec = pow (nh, s.Specular*128.0) * s.Gloss;
				
				half4 res;
				res.rgb = _LightColor0.rgb * (diff * atten * 2.0);
				res.w = spec * Luminance (_LightColor0.rgb);

				return LightingBlinnPhongEditor_PrePass( s, res );
			}
			
			struct Input {
				float4 meshUV;

			};


			void vert (inout appdata_full v, out Input o) {
float4 Vertex_VertexOutputMaster0_0_NoInput = float4(0,0,0,0);
float4 Vertex_VertexOutputMaster0_1_NoInput = float4(0,0,0,0);
float4 Vertex_VertexOutputMaster0_2_NoInput = float4(0,0,0,0);
float4 Vertex_VertexOutputMaster0_3_NoInput = float4(0,0,0,0);

o.meshUV.xy = v.texcoord.xy;
o.meshUV.zw = v.texcoord1.xy;

			}
			

			void surf (Input IN, inout EditorSurfaceOutput o) {
				o.Albedo = 0.0;
				o.Normal = float3(0.0,0.0,1.0);
				o.Emission = 0.0;
				o.Gloss = 0.0;
				o.Specular = 0.0;
				o.Alpha = 1.0;
float4 Pixel_Tex2D1=tex2D(_Diffuse,(IN.meshUV.xyxy).xy);
float4 Pixel_Tex2D3=tex2D(_Lightmap,(IN.meshUV.xyxy).xy);
float4 Pixel_Multiply0=Pixel_Tex2D1 * Pixel_Tex2D3;
float4 Pixel_Tex2D2=tex2D(_Clip,(IN.meshUV.zwzw).xy);
float4 Pixel_Master0_0_NoInput = float4(0,0,0,0);
float4 Pixel_Master0_1_NoInput = float4(0,0,1,1);
float4 Pixel_Master0_6_NoInput = float4(1,1,1,1);
o.Emission = Pixel_Multiply0;
o.Specular = _GlossOchSpecferg;
o.Gloss = _Specular.xxxx;
o.Alpha = float4( Pixel_Tex2D2.a);

			}
		ENDCG
	}
	Fallback "Diffuse"
}

1 Like

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.

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?

To enable alpha testing, use

#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.

1 Like

Thank you very much! That was exactly what I was looking for.

This helps in my case of complex objects with transparency:

Thanks, Gnoblin. I’ll try it when I get to work on monday. Where in the shader do I put that snippet?

As far as I remember, you need to put “Pass { ColorMask 0 }” just before the first word “SubShader”. Or maybe right after Tags

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:

440090--15302--$fasad_fixed.jpg

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

Shader "WhiteLightmapmAlpha"
{
	Properties 
	{
_Diffuse("_Diffuse", 2D) = "white" {}
_Lightmap("_Lightmap", 2D) = "white" {}
_GlossOchSpecferg("_GlossOchSpecferg", Color) = (0.1716418,0.1716418,0.1716418,1)
_Specular("_Specular", Range(0,1) ) = 0.75
// _Cutoff("_Cutoff", Range(0,1) ) = 0.5
_Clip("_Clip", 2D) = "white" {}

	}

	SubShader 
	{
		Tags
		{
"Queue"="Transparent+100"
"IgnoreProjector"="False"
"RenderType"="Transparent"

		}

			Pass {ColorMask 0} 
Cull Back
ZWrite On
ZTest LEqual


		CGPROGRAM
#pragma surface surf BlinnPhongEditor alpha vertex:vert
#pragma target 2.0


sampler2D _Diffuse;
sampler2D _Lightmap;
float4 _GlossOchSpecferg;
float _Specular;
sampler2D _Clip;

			struct EditorSurfaceOutput {
				half3 Albedo;
				half3 Normal;
				half3 Emission;
				half3 Gloss;
				half Specular;
				half Alpha;
			};
			
			inline half4 LightingBlinnPhongEditor_PrePass (EditorSurfaceOutput s, half4 light)
			{
half3 spec = light.a * s.Gloss;
half4 c;
c.rgb = (s.Albedo * light.rgb + light.rgb * spec);
c.a = s.Alpha + Luminance(spec);
return c;

			}

			inline half4 LightingBlinnPhongEditor (EditorSurfaceOutput s, half3 lightDir, half3 viewDir, half atten)
			{
				viewDir = normalize(viewDir);
				half3 h = normalize (lightDir + viewDir);
				
				half diff = max (0, dot (s.Normal, lightDir));
				
				float nh = max (0, dot (s.Normal, h));
				float3 spec = pow (nh, s.Specular*128.0) * s.Gloss;
				
				half4 res;
				res.rgb = _LightColor0.rgb * (diff * atten * 2.0);
				res.w = spec * Luminance (_LightColor0.rgb);

				return LightingBlinnPhongEditor_PrePass( s, res );
			}
			
			struct Input {
				float4 meshUV;

			};


			void vert (inout appdata_full v, out Input o) {
float4 Vertex_VertexOutputMaster0_0_NoInput = float4(0,0,0,0);
float4 Vertex_VertexOutputMaster0_1_NoInput = float4(0,0,0,0);
float4 Vertex_VertexOutputMaster0_2_NoInput = float4(0,0,0,0);
float4 Vertex_VertexOutputMaster0_3_NoInput = float4(0,0,0,0);

o.meshUV.xy = v.texcoord.xy;
o.meshUV.zw = v.texcoord1.xy;

			}
			

			void surf (Input IN, inout EditorSurfaceOutput o) {
				o.Albedo = 0.0;
				o.Normal = float3(0.0,0.0,1.0);
				o.Emission = 0.0;
				o.Gloss = 0.0;
				o.Specular = 0.0;
				o.Alpha = 1.0;
float4 Pixel_Tex2D1=tex2D(_Diffuse,(IN.meshUV.xyxy).xy);
float4 Pixel_Tex2D3=tex2D(_Lightmap,(IN.meshUV.xyxy).xy);
float4 Pixel_Multiply0=Pixel_Tex2D1 * Pixel_Tex2D3;
float4 Pixel_Tex2D2=tex2D(_Clip,(IN.meshUV.zwzw).xy);
float4 Pixel_Master0_0_NoInput = float4(0,0,0,0);
float4 Pixel_Master0_1_NoInput = float4(0,0,1,1);
float4 Pixel_Master0_6_NoInput = float4(1,1,1,1);
o.Emission = Pixel_Multiply0;
o.Specular = _GlossOchSpecferg;
o.Gloss = _Specular.xxxx;
o.Alpha = float4( Pixel_Tex2D2.a);

			}
		ENDCG
	}
	Fallback "Diffuse"
}

Thanks again!