Software7

Personal Developer Notebook

Unity Custom Fog Shader on Windows Phone 8

 

Unity doesn’t support Standard fog on  all Windows Phone 8 devices.
So if you switch on fog in render settings fog is shown in the editor but not on the actual device.

Fog Render Settings

Fog Render Settings

Fog in the Editor

Fog in the Editor

You can however create a custom shader with fog.

To do so start right click in the project area and choose ‘Create/Shader’. You can name the shader e.g. ‘Fog’.  You can then apply this ‘Custom/Fog’ shader to your materials.

But still nothing has changed in your scene. Therefore the first change one should make to the shader is to switch off the standard fog, because otherwise you will still see the ‘Unity Fog’.

To do so, double click the newly created shader and add ‘Fog {Mode Off}’. After saving the ‘Unity Fog’ should disappear.

Switch Fog Mode Off

Switch Fog Mode Off

We want to use the parameters of the Render Settings pane, so we add some Unity standard parameters to the shader code.

Unity Fog Parameter

Unity Fog Parameter

Next step is to add a vertex and finalcolor function.

In the vertex function we compute the distance between the vertex and camera and calculate based on the parameters a factor (fogFactor) that describes how much fog color to apply.

Fog Vertex- and Finalcolor Function

Fog Vertex- and Finalcolor Function

At this state we still don’t see any fog in the editor or game view of Unity, because we have to tell the system about our vertex and finalcolor function. So we will extend the #pragma statement accordingly.

Extend #pragma

Extend #pragma

Now when the shader is saved and automatically compiled by Unity we can now see our fog. This kind of fog is also visible on the Windows Phone 8 device.

In case you want to use exponential fog you can replace the linear fog computation by:

float f = cameraVertDist * unity_FogDensity;
data.fogFactor = saturate(1 / pow(2.71828,  f));

or for the exp2 case with

float f = cameraVertDist * unity_FogDensity;
data.fogFactor = saturate(1 / pow(2.71828,  f * f));

Here the whole shader:

Shader "Custom/Fog" {
	Properties {
		_MainTex ("Base (RGB)", 2D) = "white" {}
	}
	SubShader {
		Tags { "RenderType"="Opaque" }
		Fog {Mode  Off}
		LOD 200

		CGPROGRAM
		#pragma surface surf Lambert vertex:fogVertex finalcolor:fogColor

		sampler2D _MainTex;

		uniform half4 unity_FogColor;
		uniform half4 unity_FogStart;
		uniform half4 unity_FogEnd;
		uniform half4 unity_FogDensity;

		struct Input {
			float2 uv_MainTex;
			half fogFactor;
		};

		void fogVertex(inout appdata_full v, out Input data) 
		{
			UNITY_INITIALIZE_OUTPUT(Input, data);
			float cameraVertDist = length(mul(UNITY_MATRIX_MV, v.vertex).xyz);
			data.fogFactor = saturate((unity_FogEnd.x - cameraVertDist) / (unity_FogEnd.x - unity_FogStart.x));			
		}

		void fogColor(Input IN, SurfaceOutput o, inout fixed4 color)
		{
			color.rgb = lerp(unity_FogColor.rgb, color.rgb, IN.fogFactor);
		}

		void surf (Input IN, inout SurfaceOutput o) {
			half4 c = tex2D (_MainTex, IN.uv_MainTex);
			o.Albedo = c.rgb;
			o.Alpha = c.a;
		}
		ENDCG
	} 
	FallBack "Diffuse"
}

[Update 1/20/2014] On user request you can download the project from here.

The test project is only a static scene. Nothing fancy.

Instructions:

  • download and extract the zip file
  • choose <File/Build settings…>
  • choose ‘Windows Phone 8’ from Platform
  • click on ‘Switch Platform’
  • click on ‘Build and Run’
  • enjoy 🙂