Transparent shader odd behavior based on viewpoint

I trying my hand at creating a simple semi transparent “holograph” shader in Unity. I have the basic effect I am looking for working, but the transparency is causing me some grief. Depending on the viewpoint sometimes the render shows objects behind the transparent objects, sometimes no objects and its just the skybox you see through it, and sometimes its just a few objects and not others.

You can see a video of the problem here:

I am new to shaders, can you point me in the right direction?

Here is my shader code:

Shader “Custom/MyShader” {
Properties {
_RimColor (“Rim Color”, Color) = (1,1,1,1)
_MainColor (“Main Color”, Color) = (1,0,0,0)
}
SubShader {
Pass {
Tags { “Queue”=“Fade” “RenderType”=“Fade” }
Blend SrcAlpha OneMinusSrcAlpha

CGPROGRAM
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
#pragma vertex vert
#pragma fragment frag

#include “UnityCG.cginc”

uniform float4 _MainColor;
uniform float4 _RimColor;

struct vertexInput{
float4 vertex : POSITION;
float3 normal: NORMAL;
};

struct vertexOutput{
float4 pos : SV_POSITION;
float4 col: COLOR;
};

vertexOutput vert(vertexInput v){
vertexOutput o;

float3 normalDirection = normalize(mul(float4(v.normal, 0.0), _World2Object).xyz);
float3 viewDir = WorldSpaceViewDir(v.vertex);
half rim = 1.0 - dot(normalize(viewDir), v.normal) * 0.5;
o.col = rim * _RimColor + _MainColor;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);

return o;
}

float4 frag(vertexOutput i) : COLOR
{
return i.col;
}

ENDCG
}
}
FallBack “Diffuse”
}

Not 100% sure but it maybe the tag thats the issue.

Tags { “Queue”=“Fade” “RenderType”=“Fade” }

Fade is not a queue Unity will recognize and will give a error. Also the tag is in the wrong spot so it will default to the geometry queue.

Transparent objects require they be sorted before being drawn. This will not happen in the geometry queue which is why you can see objects behind the capsule sometimes. They are not there because they have not been rendered yet so will not be alpha blended when the capsule is drawn.

You need to use this queue and it needs to be in the subshader, not the pass.

SubShader
{
Tags { “Queue”=“Transparent” “RenderType”=“Transparent” }

Pass
{
}
}

The render type should also be Transparent. This will not cause a issue as you can have custom render types but unless you have a reason to use a custom render type (like for replacement shaders) then use one of Unitys render types (ie transparent, opaque etc).

Thanks for the advice. I moved the Tags line as you suggested. Unfortunately it does seems to have any effect.

Below is the updated code

Shader “Custom/MyShader” {
Properties {
_RimColor (“Rim Color”, Color) = (1,1,1,1)
_MainColor (“Main Color”, Color) = (1,0,0,0)
}
SubShader {
Tags{ “Queue”=“Transparent” “RenderType”=“Transparent” }
Pass {
Blend SrcAlpha OneMinusSrcAlpha

CGPROGRAM
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
#pragma vertex vert
#pragma fragment frag

#include “UnityCG.cginc”

uniform float4 _MainColor;
uniform float4 _RimColor;

struct vertexInput{
float4 vertex : POSITION;
float3 normal: NORMAL;
};

struct vertexOutput{
float4 pos : SV_POSITION;
float4 col: COLOR;
};

vertexOutput vert(vertexInput v){
vertexOutput o;

float3 normalDirection = normalize(mul(float4(v.normal, 0.0), _World2Object).xyz);
float3 viewDir = WorldSpaceViewDir(v.vertex);
half rim = 1.0 - dot(normalize(viewDir), v.normal) * 0.5;
o.col = rim * _RimColor + _MainColor;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);

return o;
}

float4 frag(vertexOutput i) : COLOR
{
return i.col;
}

ENDCG
}
}
FallBack “Diffuse”
}

Hmm, thats odd.

Click on the shader and see what the queue is. It should be 3000.

Changing the Queue in a shader has no effect on existing materials, due to this bug:
[Material] Render Queue value is not updated until shader is changed and reverted

I workaround this issue by switching the Inspector to Debug Mode, select the material and set the Queue property to -1.

1 Like

Keep in mind, semi-transparency in Unity (especially in custom shaders) is quite primitive. I believe the standard shader has fixed most of the problems with unity’s semi-transparency, but as far as I’m aware there’s no way to implement the new systems into custom shaders.

There is no difference between custom shaders and the standard shader when it comes to transparency handling. The only difference is the standard shader custom editor overrides the material’s render queue with the drop down (2000 for opaque, 2450 for alpha test, 3000 for fade and transparent). Other shaders don’t do this and the expectation is a material should use the shader’s queue, but it doesn’t if the shader’s queue changes after it’s been set on a material because of the afore linked issue.

1 Like