Fog on a sprite

90106-fog-shader.jpgTrying to get fog to affect a 2D sprite. Another question has modifying ‘ZWrite On’ to the shader as a solution.

That doesn’t work for me. I’m using 5.4.1.

In the Shader I am using though there is a line;

#pragma surface surf Lambert vertex:vert nofog keepalpha

And getting rid of “nofog” does make the the sprite be affected by fog, but there is an outline that follows it that looks strange.

I also add the line ;

#pragma multi_compile_fog

but this doesn’t seem to change anything one way or the other.

For reference I am using the Sprites-Diffuse shader from the standard shaders download.

There are a few other questions addressing this but they are either unanswered or much older and also didn’t work for me.

I copy and pasted this solution and got about as far.

Any help would be appreciated. Thank you.

Although the post is from some time ago, I just had the same small problem and I want to provide the solution I found, thanks to the fact that someone charitable shared a shader just for this in the following link:

https://www.reddit.com/r/Unity3D/comments/6scjlo/a_friend_of_mine_made_a_sprite_shader_which/

The shader what Im talking about is the next:
// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)

Shader "Sprites/Default with Fog"
{
	Properties
	{
		[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
		_Color ("Tint", Color) = (1,1,1,1)
		[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 SpriteVertFog
			#pragma fragment SpriteFragFog
			#pragma target 2.0
			#pragma multi_compile_instancing
			#pragma multi_compile _ PIXELSNAP_ON
			#pragma multi_compile _ ETC1_EXTERNAL_ALPHA
			#pragma multi_compile_fog
			#include "UnitySprites.cginc"

			struct v2f_fog
			{
				float4 vertex   : SV_POSITION;
				fixed4 color    : COLOR;
				float2 texcoord : TEXCOORD0;
				UNITY_FOG_COORDS(1)
				UNITY_VERTEX_OUTPUT_STEREO
			};

			v2f_fog SpriteVertFog(appdata_t IN)
			{
				v2f_fog OUT;

				UNITY_SETUP_INSTANCE_ID (IN);
				UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);

			#ifdef UNITY_INSTANCING_ENABLED
				IN.vertex.xy *= _Flip.xy;
			#endif

				OUT.vertex = UnityObjectToClipPos(IN.vertex);
				OUT.texcoord = IN.texcoord;
				OUT.color = IN.color * _Color * _RendererColor;

			#ifdef PIXELSNAP_ON
				OUT.vertex = UnityPixelSnap (OUT.vertex);
			#endif


				UNITY_TRANSFER_FOG(OUT, OUT.vertex);

				return OUT;
			}


			fixed4 SpriteFragFog(v2f_fog IN) : SV_Target
			{
				fixed4 c = SampleSpriteTexture (IN.texcoord) * IN.color;

				// apply fog
				UNITY_APPLY_FOG(IN.fogCoord, c);
				c.rgb *= c.a;

				return c;
			}

		ENDCG
		}
	}
}

It was enough for me to create a material, assign it to this shader and then assign it to my sprites that material.

I ran into the same issue and resolved it by:

1.) Removing the nofog directive

2.) Adding this line to the end of the surf function

clip(o.Albedo - _CutoutThresh); where _CutoutThresh is a float that I set to 0.05

Note, I didn’t have to turn ZWrite on or add the multi_compile_fog in my case but your results may vary.

EDIT: As @blargenswarg pointed out, the clip line should probably use o.Alpha instead of o.Albedo