#pragma strict @script ExecuteInEditMode @script RequireComponent (Camera) @script AddComponentMenu ("Image Effects/Global Fog") class GlobalFog extends PostEffectsBase { enum FogMode { AbsoluteYAndDistance = 0, AbsoluteY = 1, Distance = 2, RelativeYAndDistance = 3, } public var fogMode : FogMode = FogMode.AbsoluteYAndDistance; private var CAMERA_NEAR : float = 0.5f; private var CAMERA_FAR : float = 50.0f; private var CAMERA_FOV : float = 60.0f; private var CAMERA_ASPECT_RATIO : float = 1.333333f; public var startDistance : float = 200.0f; public var globalDensity : float = 1.0f; public var heightScale : float = 100.0f; public var height : float = 0.0f; public var globalFogColor : Color = Color.grey; public var fogShader : Shader; private var fogMaterial : Material = null; function OnDisable() { if (fogMaterial) DestroyImmediate(fogMaterial); } function CheckResources () : boolean { CheckSupport (true); fogMaterial = CheckShaderAndCreateMaterial (fogShader, fogMaterial); if(!isSupported) ReportAutoDisable (); return isSupported; } function OnRenderImage (source : RenderTexture, destination : RenderTexture) { if(CheckResources()==false) { Graphics.Blit (source, destination); return; } CAMERA_NEAR = camera.nearClipPlane; CAMERA_FAR = camera.farClipPlane; CAMERA_FOV = camera.fieldOfView; CAMERA_ASPECT_RATIO = camera.aspect; var frustumCorners : Matrix4x4 = Matrix4x4.identity; var vec : Vector4; var corner : Vector3; var fovWHalf : float = CAMERA_FOV * 0.5f; var toRight : Vector3 = camera.transform.right * CAMERA_NEAR * Mathf.Tan (fovWHalf * Mathf.Deg2Rad) * CAMERA_ASPECT_RATIO; var toTop : Vector3 = camera.transform.up * CAMERA_NEAR * Mathf.Tan (fovWHalf * Mathf.Deg2Rad); var topLeft : Vector3 = (camera.transform.forward * CAMERA_NEAR - toRight + toTop); var CAMERA_SCALE : float = topLeft.magnitude * CAMERA_FAR/CAMERA_NEAR; topLeft.Normalize(); topLeft *= CAMERA_SCALE; var topRight : Vector3 = (camera.transform.forward * CAMERA_NEAR + toRight + toTop); topRight.Normalize(); topRight *= CAMERA_SCALE; var bottomRight : Vector3 = (camera.transform.forward * CAMERA_NEAR + toRight - toTop); bottomRight.Normalize(); bottomRight *= CAMERA_SCALE; var bottomLeft : Vector3 = (camera.transform.forward * CAMERA_NEAR - toRight - toTop); bottomLeft.Normalize(); bottomLeft *= CAMERA_SCALE; frustumCorners.SetRow (0, topLeft); frustumCorners.SetRow (1, topRight); frustumCorners.SetRow (2, bottomRight); frustumCorners.SetRow (3, bottomLeft); fogMaterial.SetMatrix ("_FrustumCornersWS", frustumCorners); fogMaterial.SetVector ("_CameraWS", camera.transform.position); fogMaterial.SetVector ("_StartDistance", Vector4 (1.0f / startDistance, (CAMERA_SCALE-startDistance))); fogMaterial.SetVector ("_Y", Vector4 (height, 1.0f / heightScale)); fogMaterial.SetFloat ("_GlobalDensity", globalDensity * 0.01f); fogMaterial.SetColor ("_FogColor", globalFogColor); CustomGraphicsBlit (source, destination, fogMaterial, fogMode); } static function CustomGraphicsBlit (source : RenderTexture, dest : RenderTexture, fxMaterial : Material, passNr : int) { RenderTexture.active = dest; fxMaterial.SetTexture ("_MainTex", source); GL.PushMatrix (); GL.LoadOrtho (); fxMaterial.SetPass (passNr); GL.Begin (GL.QUADS); GL.MultiTexCoord2 (0, 0.0f, 0.0f); GL.Vertex3 (0.0f, 0.0f, 3.0f); // BL GL.MultiTexCoord2 (0, 1.0f, 0.0f); GL.Vertex3 (1.0f, 0.0f, 2.0f); // BR GL.MultiTexCoord2 (0, 1.0f, 1.0f); GL.Vertex3 (1.0f, 1.0f, 1.0f); // TR GL.MultiTexCoord2 (0, 0.0f, 1.0f); GL.Vertex3 (0.0f, 1.0f, 0.0); // TL GL.End (); GL.PopMatrix (); } }