UnityMol  0.9.6-875
UnityMol viewer / In developement
GlobalFog.cs
Go to the documentation of this file.
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")]
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 }
static void CustomGraphicsBlit(RenderTexture source, RenderTexture dest, Material fxMaterial, int passNr)
Definition: GlobalFog.cs:121
void OnRenderImage(RenderTexture source, RenderTexture destination)
Definition: GlobalFog.cs:42