Yesterday I released a new update to my playerbase, test went well, until I released to a 100% of players
This is the bug in question: Imgur: The magic of the Internet
The bug appears to happen to around 2-3% of players, which adds up to around 30k players.
The issue seems to be device specific, and seems to mostly happen to older phones.
Shaders with issues:
Part shader:
Shader "Sprites/Part"
{
Properties
{
_TextureAtlas("Texture Atlas", 2D) = "white" {}
_Intensity("Shade Intensity", float) = 0
}
SubShader
{
Tags
{
"Queue" = "Transparent"
"IgnoreProjector" = "True"
"RenderType" = "Transparent"
"PreviewType" = "Plane"
}
Cull Off
Lighting Off
Blend One OneMinusSrcAlpha
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
#pragma multi_compile _ ETC1_EXTERNAL_ALPHA
#include "UnityCG.cginc"
struct appdata_t
{
float4 vertex : POSITION;
fixed4 color : COLOR;
float3 UVQ_0 : TEXCOORD0;
float3 UVQ_1 : TEXCOORD1;
float3 UVQ_2 : TEXCOORD2;
float3 UVQ_3 : TEXCOORD3;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f
{
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
float3 UVQ_0 : TEXCOORD0;
float3 UVQ_1 : TEXCOORD1;
float3 UVQ_2 : TEXCOORD2;
float3 UVQ_3 : TEXCOORD3;
UNITY_VERTEX_OUTPUT_STEREO
};
v2f vert(appdata_t IN)
{
v2f OUT;
UNITY_SETUP_INSTANCE_ID(IN);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
OUT.vertex = UnityObjectToClipPos(IN.vertex);
OUT.UVQ_0 = IN.UVQ_0;
OUT.UVQ_1 = IN.UVQ_1;
OUT.UVQ_2 = IN.UVQ_2;
OUT.UVQ_3 = IN.UVQ_3;
OUT.color = IN.color;
return OUT;
}
sampler2D _TextureAtlas;
float _Intensity;
fixed4 frag(v2f IN, out float depth : SV_Depth) : SV_Target
{
// Color texture // Vertice color
fixed4 c = tex2D(_TextureAtlas, IN.UVQ_0.xy / IN.UVQ_0.z) * IN.color;
// Shape texture // Shadow texture
float albedo = tex2D(_TextureAtlas, IN.UVQ_1.xy / IN.UVQ_1.z).r * 1.85 * (1 - (1 - tex2D(_TextureAtlas, IN.UVQ_2.xy / IN.UVQ_2.z).r) * _Intensity);
// Alpha / Albedo
c.rgb *= albedo * c.a;
// Depth
#if defined(UNITY_REVERSED_Z)
depth = IN.UVQ_3.x;
#else
depth = 1.0f - IN.UVQ_3.x;
#endif
return c;
}
ENDCG
}
}
}
Terrain shader:
Shader "SFS/Terrain"
{
Properties
{
_PlanetTexture ("Planet Texture", 2D) = "white" {}
_PlanetTextureCutout ("Planet Texture Cutout", Float) = 1
_TextureA ("Texture A", 2D) = "white" {}
_TextureB ("Texture B", 2D) = "white" {}
_TextureTerrain ("Texture Terrain", 2D) = "white" {}
_RepeatA ("Repeat A", Vector) = (1,1,1,1)
_RepeatB ("Repeat B", Vector) = (1,1,1,1)
_RepeatTerrain ("Repeat Terrain", Vector) = (1,1,1,1)
_SurfaceSize ("Texture Transition", Float) = 1
_Min ("Min fade", Float) = 0
_Max ("Max fade", Float) = 1
_ShadowSize ("Transition shade", Float) = 1
_ShadowIntensity ("Shade intensity", Float) = 1
_Fog ("Atmosphere Color", Color) = (1,1,1,1)
_Depth("Depth", float) = 0
}
SubShader {
Tags {
"Queue" = "Transparent"
"IgnoreProjector" = "True"
"RenderType" = "Opaque"
"PreviewType" = "Plane"
}
Cull Off
Lighting Off
ZWrite Off
Blend Off
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
#pragma multi_compile _ ETC1_EXTERNAL_ALPHA
#include "UnityCG.cginc"
// Data passed into the vert function
struct appdata_t
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float2 uv2 : TEXCOORD1;
float2 uv3 : TEXCOORD2;
};
// Data passed into the frag function
struct v2f
{
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
float2 uv2 : TEXCOORD1;
float2 uv3 : TEXCOORD2;
};
float _ShadowIntensity;
v2f vert(appdata_t IN){
v2f OUT;
OUT.vertex = UnityObjectToClipPos( IN.vertex);
OUT.uv = IN.uv;
OUT.uv2 = IN.uv2;
OUT.uv3 = float2( IN.uv3.x * _ShadowIntensity, IN.uv3.y);
return OUT;
}
sampler2D _PlanetTexture;
float _PlanetTextureCutout;
sampler2D _TextureA;
float4 _RepeatA;
sampler2D _TextureB;
float4 _RepeatB;
sampler2D _TextureTerrain;
float4 _RepeatTerrain;
float _SurfaceSize;
float _Max;
float _Min;
float _ShadowSize;
float4 _Fog;
float _Depth;
fixed4 frag(v2f IN, out float depth : SV_Depth) : SV_TARGET
{
depth = _Depth;
IN.uv = float2(IN.uv.x / (1 - IN.uv.y), IN.uv.y);
float lerpAmount = clamp( IN.uv.y * _SurfaceSize, _Min, _Max);
float grayscale =
(
(tex2D( _TextureA, IN.uv * _RepeatA.xy).r * (1 - IN.uv3.y) + tex2D( _TextureB, IN.uv * _RepeatB.xy).r * (IN.uv3.y) ) * (1 - lerpAmount) // Surface texture
+
tex2D( _TextureTerrain, IN.uv * _RepeatTerrain.xy ).r * (0.95 * lerpAmount) // Terrain texture
)
*
2
*
(1 + IN.uv3.x * (1 - min( 1, IN.uv.y * _ShadowSize)) ); // Shade
float4 f4 = (tex2D( _PlanetTexture, IN.uv2 * _PlanetTextureCutout + 0.5) * grayscale) * (1 - _Fog.a) + (_Fog * _Fog.a);
f4.a = 1;
return f4;
}
ENDCG
}
}
}
Sprite shader:
Shader "SFS/Sprite"
{
Properties
{
[PerRendererData] _MainTex("Sprite Texture", 2D) = "white" {}
_Color("Tint", Color) = (1,1,1,1)
_Depth("Depth", float) = 0
[MaterialToggle] PixelSnap("Pixel snap", Float) = 0
[HideInInspector] _RendererColor("RendererColor", Color) = (1,1,1,1)
[HideInInspector] _Flip("Flip", Vector) = (1,1,1,1)
[PerRendererData] _AlphaTex("External Alpha", 2D) = "white" {}
[PerRendererData] _EnableExternalAlpha("Enable External Alpha", Float) = 0
}
SubShader
{
Tags
{
"Queue" = "Transparent"
"IgnoreProjector" = "True"
"RenderType" = "Transparent"
"PreviewType" = "Plane"
"CanUseSpriteAtlas" = "True"
}
Cull Off
Lighting Off
ZWrite Off
Blend One OneMinusSrcAlpha
Pass
{
CGPROGRAM
#pragma vertex SpriteVert
#pragma fragment SpriteFrag
#pragma target 2.0
#pragma multi_compile_instancing
#pragma multi_compile PIXELSNAP_ON
#pragma multi_compile ETC1_EXTERNAL_ALPHA
#include "Depth.cginc"
ENDCG
}
}
}
With a lot of messing around, we managed to get the terrain shader working by removing āout depthā, however that did not seem to work for the part shader.
Any help would be really appreciated, iām getting absolutely spammed with reports of this bug.