Fading AlphaTest Stuff

Here is my shader I use for leaves:

Shader "Nice Alpha" {
	Properties {
		_LitColor ("Lit Color", Color) = (.5, .5, .5, .5)
		_DarkColor ("Dark Color", Color) = (.5, .5, .5, .5)
		_MainTex ("Base (RGB) Alpha (A)", 2D) = "white" {}
		_Cutoff ("Base Alpha cutoff", Range (0,.9)) = .5
	}

	SubShader {
		Pass {
			Material {
				Diffuse [_LitColor]
				Ambient [_LitColor]
			}       

			Lighting On
			Cull Back

			AlphaTest Greater [_Cutoff]
			
			SetTexture [_MainTex] {
				ConstantColor [_DarkColor]
				combine constant + primary, texture
			}

			SetTexture [_MainTex] {

				combine previous * texture, texture
			}
		}
	}
}

I am making a lod and I want to fade objects when they change geometry for it to look nice. I want to fade this shader out by a color alpha, without using the texture alpha or affecting the alphatest at all. I don’t just use a regular alpha blended shader because the official Alpha shader looks horrible, like it is additive or something and anything I make looks worse. After a very long struggle I have come to the conclusion that I can’t use blending for leaves without having each leaf be a different object.

Transparent stuff is hard. Ever wondered why most games don’t fade out trees/grass but just “cut them out”? :slight_smile:

Some sort of alpha test is the way to go. Alpha blending in Unity actually works, but for 100% correct results you need to use either convex objects (trees aren’t that usually) or break objects into parts so that Unity can sort them by distance correctly.

That said, for fading out alpha-tested things there is one clever approach: use “alpha dissolve”. For the whole object’s texture, don’t use just two alpha levels (full opaque or fully transparent); instead use alpha=0 for transparent things, and alpha>0 for the actual object, alpha following the object’s contours or just being noise. For fading out stuff, just modify alpha cutoff value in the material from scripts.

Here are some my attempts at illustrating the thing (excuse programmer’s art). Here I tested two leaf textures, alpha of each shown below. In both cases the shader and script are exactly the same; just have alpha cutoff in the shader and change the cutoff from script based on distance.

For this small test, the shader is:

Shader "Alpha Leaves" {
Properties {
	_MainTex ("Base", 2D) = "white" {}
	_Cutoff ("Alpha cutoff", Range(0.07,0.99)) = 0.1
}
SubShader {
	Pass {
		AlphaTest Greater [_Cutoff]
		SetTexture [_MainTex] { combine texture }
	}
} 
}

and the script attached to each leaf is:

var distanceStart = 10.0;
var distanceEnd = 15.0;
var minAlpha = 0.07;

function Update()
{
	var distance = (Camera.main.transform.position - transform.position).magnitude;
	var alpha = Mathf.InverseLerp( distanceStart, distanceEnd, distance );
	if( alpha < minAlpha )
		alpha = minAlpha;
	renderer.material.SetFloat("_Cutoff", alpha);
}


19564--635--$leaf_alphas_380.png

Ah, thats what I needed. I overlayed the RGB values over the alpha and I can fade it out by adjusting the cutoff. Great!

Here it is in action:

http://forum.unity3d.com/viewtopic.php?p=19881#19881