GlobalFog.cs 5.4 KB

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