I am working on upgrading my project to Unity 2017 and one of my shaders (seen below) has stopped working properly.
I can only get it to render behind all other objects OR infront. Previously, it would render based on which object was closest the the camera. Adding or removing the line “ZTest Always” switches between these behaviours. I have already tried the other settings for ZTest.
The problem is best seen as white circle in these images. I would like the white circle to render behind the box but in front of the terrain.
Shader "Custom/BillboardDX11" {
Properties{
_MainTex("Base (RGB)", 2D) = "white" {}
_Extents("Extents (min distance, max distance)", Vector) = (0.05, 0.05, 0.005, 0.005)
_AngleFadeScale("Angle Fade Scale", Range(0, 1)) = 0.5
_ScaleRange("Scale Range (min, max, fadeoff min, fadeoff max)", Vector) = (0.0, 500.0, 0, 0)
_DepthOffsetThreshold("Depth Offset Theshold", Float) = 500
[MaterialToggle] _IsUnidirectional("Is Unidirectional", Float) = 1
[MaterialToggle] _NearFadeoff("Near Fadeoff", Float) = 0
[MaterialToggle] _AllowDistanceFalloff("Allow Distance Falloff", Float) = 1
_DistanceFalloff("Distance Falloff Factor", Float) = 500
}
SubShader{
Tags{ "IgnoreProjector" = "True" "RenderType" = "Transparent" }
pass {
Cull Off
Fog{ Mode Off }
ZWrite Off
Blend One One
//ZTest Always
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 5.0
#include "UnityCG.cginc"
sampler2D _MainTex;
sampler2D_float _CameraDepthTexture;
float4 _MainTex_ST;
float4 _Extents;
float _AngleFadeScale;
float4 _ScaleRange;
float _IsUnidirectional;
float _NearFadeoff;
float _AllowDistanceFalloff;
float _DepthOffsetThreshold;
float _DistanceFalloff;
struct vertex_data {
float4 vertex : POSITION;
float4 texcoord : TEXCOORD0;
float3 normal : NORMAL;
float4 color : COLOR;
};
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float3 color : COLOR;
};
float4x4 inverse(float4x4 input)
{
#define minor(a,b,c) determinant(float3x3(input.a, input.b, input.c))
//determinant(float3x3(input._22_23_23, input._32_33_34, input._42_43_44))
float4x4 cofactors = float4x4(
minor(_22_23_24, _32_33_34, _42_43_44),
-minor(_21_23_24, _31_33_34, _41_43_44),
minor(_21_22_24, _31_32_34, _41_42_44),
-minor(_21_22_23, _31_32_33, _41_42_43),
-minor(_12_13_14, _32_33_34, _42_43_44),
minor(_11_13_14, _31_33_34, _41_43_44),
-minor(_11_12_14, _31_32_34, _41_42_44),
minor(_11_12_13, _31_32_33, _41_42_43),
minor(_12_13_14, _22_23_24, _42_43_44),
-minor(_11_13_14, _21_23_24, _41_43_44),
minor(_11_12_14, _21_22_24, _41_42_44),
-minor(_11_12_13, _21_22_23, _41_42_43),
-minor(_12_13_14, _22_23_24, _32_33_34),
minor(_11_13_14, _21_23_24, _31_33_34),
-minor(_11_12_14, _21_22_24, _31_32_34),
minor(_11_12_13, _21_22_23, _31_32_33)
);
#undef minor
return transpose(cofactors) / determinant(input);
}
v2f vert(vertex_data v)
{
v2f output;
float3 viewPos = mul(UNITY_MATRIX_MV, v.vertex);
float4 center = mul(UNITY_MATRIX_MVP, v.vertex); // UNITY_SHADER_NO_UPGRADE
float4 pos = center;
// find depth buffer depth
float2 screenTexCoord = (pos.xy / pos.w) * 0.5 + 0.5;
float currentDepth = Linear01Depth(tex2Dlod(_CameraDepthTexture, float4(float2(screenTexCoord.x, 1 - screenTexCoord.y), 0, 0)).r);
// calculate linear 01 depth of center of billboard
float depth = pos.z / pos.w;// / _ProjectionParams.z;
//float depth = Linear01Depth(pos.z / pos.w);
// expand quad vertices
float distance = length(viewPos);
float2 scaleAlpha = saturate((distance - _ScaleRange.xz) / (_ScaleRange.yw - _ScaleRange.xz));
float2 offset = lerp(_Extents.xy, _Extents.zw, scaleAlpha.x) * float2(_ScreenParams.y / _ScreenParams.x, 1) * (v.texcoord * 2 - 1);
if (_NearFadeoff) {
offset *= scaleAlpha.y;
}
// move into homogenous space
offset *= pos.w;
pos.xy += offset;
float depthComparison = pos.z * (pos.z < _DepthOffsetThreshold ? 0.99 : 0.93) / _ProjectionParams.z;
if (depthComparison > currentDepth) {
pos.xy = 0;
}
float4x4 mvp_inv = inverse(UNITY_MATRIX_MVP);
float4 unprojected = mul(mvp_inv, pos);
float size = length(v.vertex.xyz - unprojected.xyz) / _ProjectionParams.z;
float fade = 1;
// unidirectional angle fadeoff
if (_IsUnidirectional) {
if (_AngleFadeScale == 1) {
fade = 0;
}
else {
float3 forward = normalize(mul(UNITY_MATRIX_IT_MV, v.normal.xyzz).xyz);
float angle = dot(forward, -normalize(viewPos)) * 0.5 + 0.5;
fade *= saturate((angle - _AngleFadeScale) / (1 - _AngleFadeScale));
}
}
float alpha = 1;
if (_AllowDistanceFalloff) {
alpha = saturate((_DistanceFalloff - distance) / (_DistanceFalloff));
}
pos.z = 0;
output.pos = pos;
output.color = v.color * fade * alpha;
output.uv = v.texcoord;
return output;
}
float4 frag(v2f input) : SV_Target
{
return tex2D(_MainTex, TRANSFORM_TEX(input.uv, _MainTex)) * float4(input.color, 1);
}
ENDCG
}
}
Fallback "Standard"
}