- GlobalFog.cs
- Scripts /
- ImageEffects /
- Effects /
- Standard Assets /
- Assets /
- project /
1 using System;
2 using UnityEngine;
3
4 namespace UnityStandardAssets.ImageEffects
5 {
6 [ExecuteInEditMode]
7 [RequireComponent (typeof(Camera))]
8 [AddComponentMenu ("Image Effects/Rendering/Global Fog")]
9 class GlobalFog : PostEffectsBase
10 {
11 [Tooltip("Apply distance-based fog?")]
12 public bool distanceFog = true;
13 [Tooltip("Exclude far plane pixels from distance-based fog? (Skybox or clear color)")]
14 public bool excludeFarPixels = true;
15 [Tooltip("Distance fog is based on radial distance from camera when checked")]
16 public bool useRadialDistance = false;
17 [Tooltip("Apply height-based fog?")]
18 public bool heightFog = true;
19 [Tooltip("Fog top Y coordinate")]
20 public float height = 1.0f;
21 [Range(0.001f,10.0f)]
22 public float heightDensity = 2.0f;
23 [Tooltip("Push fog away from the camera by this amount")]
24 public float startDistance = 0.0f;
25
26 public Shader fogShader = null;
27 private Material fogMaterial = null;
28
29
30 public override bool CheckResources ()
31 {
32 CheckSupport (true);
33
34 fogMaterial = CheckShaderAndCreateMaterial (fogShader, fogMaterial);
35
36 if (!isSupported)
37 ReportAutoDisable ();
38 return isSupported;
39 }
40
41 [ImageEffectOpaque]
42 void OnRenderImage (RenderTexture source, RenderTexture destination)
43 {
44 if (CheckResources()==false || (!distanceFog && !heightFog))
45 {
46 Graphics.Blit (source, destination);
47 return;
48 }
49
50 Camera cam = GetComponent<Camera>();
51 Transform camtr = cam.transform;
52 float camNear = cam.nearClipPlane;
53 float camFar = cam.farClipPlane;
54 float camFov = cam.fieldOfView;
55 float camAspect = cam.aspect;
56
57 Matrix4x4 frustumCorners = Matrix4x4.identity;
58
59 float fovWHalf = camFov * 0.5f;
60
61 Vector3 toRight = camtr.right * camNear * Mathf.Tan (fovWHalf * Mathf.Deg2Rad) * camAspect;
62 Vector3 toTop = camtr.up * camNear * Mathf.Tan (fovWHalf * Mathf.Deg2Rad);
63
64 Vector3 topLeft = (camtr.forward * camNear - toRight + toTop);
65 float camScale = topLeft.magnitude * camFar/camNear;
66
67 topLeft.Normalize();
68 topLeft *= camScale;
69
70 Vector3 topRight = (camtr.forward * camNear + toRight + toTop);
71 topRight.Normalize();
72 topRight *= camScale;
73
74 Vector3 bottomRight = (camtr.forward * camNear + toRight - toTop);
75 bottomRight.Normalize();
76 bottomRight *= camScale;
77
78 Vector3 bottomLeft = (camtr.forward * camNear - toRight - toTop);
79 bottomLeft.Normalize();
80 bottomLeft *= camScale;
81
82 frustumCorners.SetRow (0, topLeft);
83 frustumCorners.SetRow (1, topRight);
84 frustumCorners.SetRow (2, bottomRight);
85 frustumCorners.SetRow (3, bottomLeft);
86
87 var camPos= camtr.position;
88 float FdotC = camPos.y-height;
89 float paramK = (FdotC <= 0.0f ? 1.0f : 0.0f);
90 float excludeDepth = (excludeFarPixels ? 1.0f : 2.0f);
91 fogMaterial.SetMatrix ("_FrustumCornersWS", frustumCorners);
92 fogMaterial.SetVector ("_CameraWS", camPos);
93 fogMaterial.SetVector ("_HeightParams", new Vector4 (height, FdotC, paramK, heightDensity*0.5f));
94 fogMaterial.SetVector ("_DistanceParams", new Vector4 (-Mathf.Max(startDistance,0.0f), excludeDepth, 0, 0));
95
96 var sceneMode= RenderSettings.fogMode;
97 var sceneDensity= RenderSettings.fogDensity;
98 var sceneStart= RenderSettings.fogStartDistance;
99 var sceneEnd= RenderSettings.fogEndDistance;
100 Vector4 sceneParams;
101 bool linear = (sceneMode == FogMode.Linear);
102 float diff = linear ? sceneEnd - sceneStart : 0.0f;
103 float invDiff = Mathf.Abs(diff) > 0.0001f ? 1.0f / diff : 0.0f;
104 sceneParams.x = sceneDensity * 1.2011224087f; // density / sqrt(ln(2)), used by Exp2 fog mode
105 sceneParams.y = sceneDensity * 1.4426950408f; // density / ln(2), used by Exp fog mode
106 sceneParams.z = linear ? -invDiff : 0.0f;
107 sceneParams.w = linear ? sceneEnd * invDiff : 0.0f;
108 fogMaterial.SetVector ("_SceneFogParams", sceneParams);
109 fogMaterial.SetVector ("_SceneFogMode", new Vector4((int)sceneMode, useRadialDistance ? 1 : 0, 0, 0));
110
111 int pass = 0;
112 if (distanceFog && heightFog)
113 pass = 0; // distance + height
114 else if (distanceFog)
115 pass = 1; // distance only
116 else
117 pass = 2; // height only
118 CustomGraphicsBlit (source, destination, fogMaterial, pass);
119 }
120
121 static void CustomGraphicsBlit (RenderTexture source, RenderTexture dest, Material fxMaterial, int passNr)
122 {
123 RenderTexture.active = dest;
124
125 fxMaterial.SetTexture ("_MainTex", source);
126
127 GL.PushMatrix ();
128 GL.LoadOrtho ();
129
130 fxMaterial.SetPass (passNr);
131
132 GL.Begin (GL.QUADS);
133
134 GL.MultiTexCoord2 (0, 0.0f, 0.0f);
135 GL.Vertex3 (0.0f, 0.0f, 3.0f); // BL
136
137 GL.MultiTexCoord2 (0, 1.0f, 0.0f);
138 GL.Vertex3 (1.0f, 0.0f, 2.0f); // BR
139
140 GL.MultiTexCoord2 (0, 1.0f, 1.0f);
141 GL.Vertex3 (1.0f, 1.0f, 1.0f); // TR
142
143 GL.MultiTexCoord2 (0, 0.0f, 1.0f);
144 GL.Vertex3 (0.0f, 1.0f, 0.0f); // TL
145
146 GL.End ();
147 GL.PopMatrix ();
148 }
149 }
150 }
2 using UnityEngine;
3
4 namespace UnityStandardAssets.ImageEffects
5 {
6 [ExecuteInEditMode]
7 [RequireComponent (typeof(Camera))]
8 [AddComponentMenu ("Image Effects/Rendering/Global Fog")]
9 class GlobalFog : PostEffectsBase
10 {
11 [Tooltip("Apply distance-based fog?")]
12 public bool distanceFog = true;
13 [Tooltip("Exclude far plane pixels from distance-based fog? (Skybox or clear color)")]
14 public bool excludeFarPixels = true;
15 [Tooltip("Distance fog is based on radial distance from camera when checked")]
16 public bool useRadialDistance = false;
17 [Tooltip("Apply height-based fog?")]
18 public bool heightFog = true;
19 [Tooltip("Fog top Y coordinate")]
20 public float height = 1.0f;
21 [Range(0.001f,10.0f)]
22 public float heightDensity = 2.0f;
23 [Tooltip("Push fog away from the camera by this amount")]
24 public float startDistance = 0.0f;
25
26 public Shader fogShader = null;
27 private Material fogMaterial = null;
28
29
30 public override bool CheckResources ()
31 {
32 CheckSupport (true);
33
34 fogMaterial = CheckShaderAndCreateMaterial (fogShader, fogMaterial);
35
36 if (!isSupported)
37 ReportAutoDisable ();
38 return isSupported;
39 }
40
41 [ImageEffectOpaque]
42 void OnRenderImage (RenderTexture source, RenderTexture destination)
43 {
44 if (CheckResources()==false || (!distanceFog && !heightFog))
45 {
46 Graphics.Blit (source, destination);
47 return;
48 }
49
50 Camera cam = GetComponent<Camera>();
51 Transform camtr = cam.transform;
52 float camNear = cam.nearClipPlane;
53 float camFar = cam.farClipPlane;
54 float camFov = cam.fieldOfView;
55 float camAspect = cam.aspect;
56
57 Matrix4x4 frustumCorners = Matrix4x4.identity;
58
59 float fovWHalf = camFov * 0.5f;
60
61 Vector3 toRight = camtr.right * camNear * Mathf.Tan (fovWHalf * Mathf.Deg2Rad) * camAspect;
62 Vector3 toTop = camtr.up * camNear * Mathf.Tan (fovWHalf * Mathf.Deg2Rad);
63
64 Vector3 topLeft = (camtr.forward * camNear - toRight + toTop);
65 float camScale = topLeft.magnitude * camFar/camNear;
66
67 topLeft.Normalize();
68 topLeft *= camScale;
69
70 Vector3 topRight = (camtr.forward * camNear + toRight + toTop);
71 topRight.Normalize();
72 topRight *= camScale;
73
74 Vector3 bottomRight = (camtr.forward * camNear + toRight - toTop);
75 bottomRight.Normalize();
76 bottomRight *= camScale;
77
78 Vector3 bottomLeft = (camtr.forward * camNear - toRight - toTop);
79 bottomLeft.Normalize();
80 bottomLeft *= camScale;
81
82 frustumCorners.SetRow (0, topLeft);
83 frustumCorners.SetRow (1, topRight);
84 frustumCorners.SetRow (2, bottomRight);
85 frustumCorners.SetRow (3, bottomLeft);
86
87 var camPos= camtr.position;
88 float FdotC = camPos.y-height;
89 float paramK = (FdotC <= 0.0f ? 1.0f : 0.0f);
90 float excludeDepth = (excludeFarPixels ? 1.0f : 2.0f);
91 fogMaterial.SetMatrix ("_FrustumCornersWS", frustumCorners);
92 fogMaterial.SetVector ("_CameraWS", camPos);
93 fogMaterial.SetVector ("_HeightParams", new Vector4 (height, FdotC, paramK, heightDensity*0.5f));
94 fogMaterial.SetVector ("_DistanceParams", new Vector4 (-Mathf.Max(startDistance,0.0f), excludeDepth, 0, 0));
95
96 var sceneMode= RenderSettings.fogMode;
97 var sceneDensity= RenderSettings.fogDensity;
98 var sceneStart= RenderSettings.fogStartDistance;
99 var sceneEnd= RenderSettings.fogEndDistance;
100 Vector4 sceneParams;
101 bool linear = (sceneMode == FogMode.Linear);
102 float diff = linear ? sceneEnd - sceneStart : 0.0f;
103 float invDiff = Mathf.Abs(diff) > 0.0001f ? 1.0f / diff : 0.0f;
104 sceneParams.x = sceneDensity * 1.2011224087f; // density / sqrt(ln(2)), used by Exp2 fog mode
105 sceneParams.y = sceneDensity * 1.4426950408f; // density / ln(2), used by Exp fog mode
106 sceneParams.z = linear ? -invDiff : 0.0f;
107 sceneParams.w = linear ? sceneEnd * invDiff : 0.0f;
108 fogMaterial.SetVector ("_SceneFogParams", sceneParams);
109 fogMaterial.SetVector ("_SceneFogMode", new Vector4((int)sceneMode, useRadialDistance ? 1 : 0, 0, 0));
110
111 int pass = 0;
112 if (distanceFog && heightFog)
113 pass = 0; // distance + height
114 else if (distanceFog)
115 pass = 1; // distance only
116 else
117 pass = 2; // height only
118 CustomGraphicsBlit (source, destination, fogMaterial, pass);
119 }
120
121 static void CustomGraphicsBlit (RenderTexture source, RenderTexture dest, Material fxMaterial, int passNr)
122 {
123 RenderTexture.active = dest;
124
125 fxMaterial.SetTexture ("_MainTex", source);
126
127 GL.PushMatrix ();
128 GL.LoadOrtho ();
129
130 fxMaterial.SetPass (passNr);
131
132 GL.Begin (GL.QUADS);
133
134 GL.MultiTexCoord2 (0, 0.0f, 0.0f);
135 GL.Vertex3 (0.0f, 0.0f, 3.0f); // BL
136
137 GL.MultiTexCoord2 (0, 1.0f, 0.0f);
138 GL.Vertex3 (1.0f, 0.0f, 2.0f); // BR
139
140 GL.MultiTexCoord2 (0, 1.0f, 1.0f);
141 GL.Vertex3 (1.0f, 1.0f, 1.0f); // TR
142
143 GL.MultiTexCoord2 (0, 0.0f, 1.0f);
144 GL.Vertex3 (0.0f, 1.0f, 0.0f); // TL
145
146 GL.End ();
147 GL.PopMatrix ();
148 }
149 }
150 }