- Home /
Transparent Objects within Transparent Objects
I'll admit, I'm a complete novice when it comes to shaders and I may be in way over my head with this one.
I'm currently trying to write a shader that allows transparent objects to be placed within or intersecting other transparent objects and have each object, and its back-faces, visible, and to fade between opaque + coloured and transparent + Greyscale
So far I've created a shader that appears to fit the bill, except that it's not rendering consistently and I'm getting alot of flickering (potentially z-fighting) when rotating around the object.
In my example I have a Cube within a Cube within a Cube, it looks perfectly fine at some angles:
At other angles (even <1 degree change) it looks like this:
Here's the shader code incase it helps:
Shader "GreyscaleTransition" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
_BumpMap ("Bump (RGB)", 2D) = "black" {}
_Brightness ("Brightness (Desaturated)", Range(-1,1)) = 0
_Fade ("Fade ",Range(0,1)) = 0
_Alpha ("Alpha (Desaturated)", Range(0,1)) = 1
}
SubShader {
Tags {
"RenderType"="Transparent"
"IgnoreProjector"="False"
"Queue" = "Transparent"
}
LOD 200
Cull Off
ZWrite on
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma surface surf Lambert
sampler2D _MainTex;
sampler2D _BumpMap;
fixed _Brightness;
fixed _Fade;
fixed _Alpha;
struct Input {
float2 uv_MainTex;
float2 uv_BumpMap;
};
void surf (Input IN, inout SurfaceOutput o) {
half4 c = tex2D (_MainTex, IN.uv_MainTex);
fixed3 desat = dot(c.rgb, float3(0.3, 0.59, 0.11)) + _Brightness;
fixed3 colour = c.rgb;
o.Albedo = lerp(colour,desat,_Fade);
o.Alpha = lerp(c.a,_Alpha,_Fade);
o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
}
ENDCG
}
FallBack "Diffuse"
}
Transparent shaders can't have Z-fighting, because they don't write to the Z-buffer :)
Sorry, I meant they can't have Z-fighting because they aren't ordered by the Z-buffer ;)
Answer by whydoidoit · Aug 20, 2013 at 08:09 AM
You need a 2 pass shader to make that work for a single cube, the first pass writes the back faces and the second pass writes the front faces.
The problem otherwise is that Unity does not Z order the triangles being drawn and so back and front faces can overlap and be drawn in the wrong order.
There's another problem too - given the ordering you will always end up with one of the cubes not drawing in front of another one, because the whole object is rendered at once either it will write the furthest back faces and the front faces (stopping the inner cube from working) or the inner cube will overwrite the outer cube. To fix that you need to ensure that all of the cubes back faces are written first (late in the pipeline so that all other geometry is rendered) and then all of the front faces, not just for each object, but indeed for the whole collection.
You can do that last bit by having the two subshaders use "Queue"="Transparent+1000" and "Queue"="Transparent+1001" for example
Your answer
Follow this Question
Related Questions
Shader for overlaying textures 1 Answer
Transparent & reflective shader 1 Answer
Transparency shader that also writes to Camera Depth Texture 0 Answers
Unity Tree transparency 1 Answer
weird shader problem (correct in editor, weird ingame) 2 Answers