I'm making a space exploration game in Unity and I'm having two problems with semi-transparency.
Each planet is made up of two spheres: One is the combined surface and cloud layer, the other (with a slightly larger radius) depicts the horizon 'glow' by culling front faces and fading alpha toward the outer edge of the sphere. This is MOSTLY working fine, but with the following two problems:
1) In my custom surface shader, when I use the alpha keyword in the #pragma definition, alpha is factored into the rendered sphere, but the 'glow' sphere disappears at a distance of a few thousand units. If I DON'T include the alpha keyword, the sphere does not fade toward the edge, but it renders at distance.
2) Despite trying all RenderType, Queue, ZWrite and ZDepth options, the surface sphere and 'glow' sphere are z-fighting; the game can't seem to decide which polygons are nearer - despite the fact near faces on the glow sphere should be culled. I have even tried pushing the glow sphere away from the player camera and expanding its radius by the same proportion, but I'm STILL, inexplicably, getting the z-fighting between the spheres!
Is there any setting that I'm missing that will enable the 'glow' sphere to be always drawn BEHIND the surface sphere (given that I have tried ALL combinations of ZWrite, ZDepth as detailed above) and is there a way to have an alpha-enabled object NOT disappear at distance?
I cannot seem to figure this out, so any help will be well appreciated!
EDIT
Here's the shader code for my 'glow sphere'. Front faces are culled. I've even tried the Offset keyword to 'push' any drawn polygons further from camera. And I've tried all of the Tag, ZWrite and ZTest options I've been able to find. The shader gets passed a tint Color, an atmosphere density float and a sun direction vector...
Shader "Custom/planet glow" {
Properties {
_glowTint ("Glow Tint", Color) = (0.5,0.8,1,1)
_atmosphereMix ("Atmosphere Mix", float) = 0
_sunDirection ("Sun Direction", Vector) = (0, 0, 0, 0)
}
SubShader {
Tags { "RenderType" = "Opaque" "Queue" = "Geometry" }
Cull Front // I want only the far faces to render (behind the actual planet surface)
Offset 10000, 10000
ZWrite On // Off also tried
ZTest LEqual // I have tried various other options here, incombination with changing this setting in the planet surface shader
CGPROGRAM
#pragma surface surf Lambert alpha
#pragma target 4.0
struct Input {
float3 viewDir;
};
fixed4 _glowTint;
float _atmosphereMix;
float4 _sunDirection;
void surf (Input IN, inout SurfaceOutput o) {
_sunDirection = normalize(_sunDirection);
o.Albedo = _glowTint;
float cameraNormalDP = saturate(dot( normalize(IN.viewDir), -o.Normal ) * 4.5);
float sunNormalDP = saturate(dot( normalize(-_sunDirection), -o.Normal ) * 2);
o.Alpha = _atmosphereMix * sunNormalDP * (cameraNormalDP * cameraNormalDP * cameraNormalDP); // makes the edge fade 'faster'
o.Emission = _glowTint;
}
ENDCG
}
FallBack "Diffuse"
}