Unity fog of war video tutorial with webplayer demo

In this video tutorial I want to tell you about fog of war implementation in Unity engine. This technique does not require rendering to texture so it can be used in Unity free version. It also works well in mobile devices.

Author: Sergey Taraban

:ad:
Part 2. Mobile version Part 3. Static and dynamic fog of war using render to texture

Unity web player demo.

fog of war play demo

Use WASD or Arrow buttons for moving

Download pack file: fog_of_war_tutorial.unitypackage

Fog of war tutorial.

Fog of war aperture shader.

Here is the shader I used in this tutorial for creating aperture on the fog of war plane.
// FogOfWar shader
// Copyright (C) 2013 Sergey Taraban 
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//

Shader “Custom/FogOfWar” { Properties {     _Color (“Main Color”, Color) = (1,1,1,1)     _MainTex (“Base (RGB) Trans (A)”, 2D) = “white” {}     _FogRadius (“FogRadius”, Float) = 1.0     _FogMaxRadius(“FogMaxRadius”, Float) = 0.5     _Player1_Pos ("_Player1_Pos", Vector) = (0,0,0,1)     _Player2_Pos ("_Player2_Pos", Vector) = (0,0,0,1)     _Player3_Pos ("_Player3_Pos", Vector) = (0,0,0,1) }

SubShader {     Tags {“Queue”=“Transparent” “IgnoreProjector”=“True” “RenderType”=“Transparent”}     LOD 200     Blend SrcAlpha OneMinusSrcAlpha     Cull Off

    CGPROGRAM     #pragma surface surf Lambert vertex:vert

    sampler2D _MainTex;     fixed4     _Color;     float     _FogRadius;     float     _FogMaxRadius;     float4     _Player1_Pos;     float4     _Player2_Pos;     float4     _Player3_Pos;

    struct Input {         float2 uv_MainTex;         float2 location;     };

    float powerForPos(float4 pos, float2 nearVertex);

    void vert(inout appdata_full vertexData, out Input outData) {         float4 pos = mul(UNITY_MATRIX_MVP, vertexData.vertex);         float4 posWorld = mul(_Object2World, vertexData.vertex);         outData.uv_MainTex = vertexData.texcoord;         outData.location = posWorld.xz;     }

    void surf (Input IN, inout SurfaceOutput o) {         fixed4 baseColor = tex2D(_MainTex, IN.uv_MainTex) * _Color;

        float alpha = (1.0 - (baseColor.a + powerForPos(_Player1_Pos, IN.location) + powerForPos(_Player2_Pos, IN.location) + powerForPos(_Player3_Pos, IN.location)));

        o.Albedo = baseColor.rgb;         o.Alpha = alpha;     }

    //return 0 if (pos - nearVertex) > _FogRadius     float powerForPos(float4 pos, float2 nearVertex) {         float atten = clamp(_FogRadius - length(pos.xz - nearVertex.xy), 0.0, _FogRadius);

        return (1.0/_FogMaxRadius)*atten/_FogRadius;     }

    ENDCG }

Fallback “Transparent/VertexLit” }

 Fog of war script for players.

using UnityEngine;
using System.Collections;

public class FogOfWarPlayer : MonoBehaviour {

public Transform FogOfWarPlane;
public int Number = 1;

// Use this for initialization
void Start () {

}

// Update is called once per frame
void Update () {
	Vector3 screenPos = Camera.mainCamera.WorldToScreenPoint(transform.position);
	Ray rayToPlayerPos = Camera.mainCamera.ScreenPointToRay(screenPos);
	int layermask = (int)(1<<8);
	RaycastHit hit;
	if(Physics.Raycast(rayToPlayerPos, out hit, 1000, layermask)) {
		FogOfWarPlane.GetComponent<Renderer>().material.SetVector("_Player" + Number.ToString() +"_Pos", hit.point);
	}
}

}

Author: Sergey Taraban

Related links