UnderWaterFog.cs 4.2 KB

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