EnviroRenderer.cs 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. namespace Enviro
  5. {
  6. [ExecuteInEditMode]
  7. [ImageEffectAllowedInSceneView]
  8. public class EnviroRenderer : MonoBehaviour
  9. {
  10. [Tooltip("Assign a quality here if you want to use different settings for this camera. Otherwise it takes settings from Enviro Manager.")]
  11. public EnviroQuality myQuality;
  12. private Camera myCam;
  13. private EnviroVolumetricCloudRenderer volumetricCloudsRender;
  14. void OnEnable()
  15. {
  16. myCam = GetComponent<Camera>();
  17. }
  18. void OnDisable ()
  19. {
  20. CleanupVolumetricRenderer();
  21. }
  22. private void CleanupVolumetricRenderer()
  23. {
  24. if(volumetricCloudsRender != null)
  25. {
  26. if(volumetricCloudsRender.raymarchMat != null)
  27. DestroyImmediate(volumetricCloudsRender.raymarchMat);
  28. if(volumetricCloudsRender.blendAndLightingMat != null)
  29. DestroyImmediate(volumetricCloudsRender.blendAndLightingMat);
  30. if(volumetricCloudsRender.reprojectMat != null)
  31. DestroyImmediate(volumetricCloudsRender.reprojectMat);
  32. if(volumetricCloudsRender.undersampleBuffer != null)
  33. DestroyImmediate(volumetricCloudsRender.undersampleBuffer);
  34. if(volumetricCloudsRender.fullBuffer != null && volumetricCloudsRender.fullBuffer.Length > 0)
  35. {
  36. for (int i = 0; i < volumetricCloudsRender.fullBuffer.Length; i++)
  37. {
  38. if(volumetricCloudsRender.fullBuffer[i] != null)
  39. DestroyImmediate(volumetricCloudsRender.fullBuffer[i]);
  40. }
  41. }
  42. }
  43. }
  44. private void SetMatrix()
  45. {
  46. if (myCam.stereoEnabled)
  47. {
  48. // Both stereo eye inverse view matrices
  49. Matrix4x4 left_world_from_view = myCam.GetStereoViewMatrix(Camera.StereoscopicEye.Left).inverse;
  50. Matrix4x4 right_world_from_view = myCam.GetStereoViewMatrix(Camera.StereoscopicEye.Right).inverse;
  51. // Both stereo eye inverse projection matrices, plumbed through GetGPUProjectionMatrix to compensate for render texture
  52. Matrix4x4 left_screen_from_view = myCam.GetStereoProjectionMatrix(Camera.StereoscopicEye.Left);
  53. Matrix4x4 right_screen_from_view = myCam.GetStereoProjectionMatrix(Camera.StereoscopicEye.Right);
  54. Matrix4x4 left_view_from_screen = GL.GetGPUProjectionMatrix(left_screen_from_view, true).inverse;
  55. Matrix4x4 right_view_from_screen = GL.GetGPUProjectionMatrix(right_screen_from_view, true).inverse;
  56. // Negate [1,1] to reflect Unity's CBuffer state
  57. if (SystemInfo.graphicsDeviceType != UnityEngine.Rendering.GraphicsDeviceType.OpenGLCore && SystemInfo.graphicsDeviceType != UnityEngine.Rendering.GraphicsDeviceType.OpenGLES3)
  58. {
  59. left_view_from_screen[1, 1] *= -1;
  60. right_view_from_screen[1, 1] *= -1;
  61. }
  62. Shader.SetGlobalMatrix("_LeftWorldFromView", left_world_from_view);
  63. Shader.SetGlobalMatrix("_RightWorldFromView", right_world_from_view);
  64. Shader.SetGlobalMatrix("_LeftViewFromScreen", left_view_from_screen);
  65. Shader.SetGlobalMatrix("_RightViewFromScreen", right_view_from_screen);
  66. }
  67. else
  68. {
  69. // Main eye inverse view matrix
  70. Matrix4x4 left_world_from_view = myCam.cameraToWorldMatrix;
  71. // Inverse projection matrices, plumbed through GetGPUProjectionMatrix to compensate for render texture
  72. Matrix4x4 screen_from_view = myCam.projectionMatrix;
  73. Matrix4x4 left_view_from_screen = GL.GetGPUProjectionMatrix(screen_from_view, true).inverse;
  74. // Negate [1,1] to reflect Unity's CBuffer state
  75. if (SystemInfo.graphicsDeviceType != UnityEngine.Rendering.GraphicsDeviceType.OpenGLCore && SystemInfo.graphicsDeviceType != UnityEngine.Rendering.GraphicsDeviceType.OpenGLES3)
  76. left_view_from_screen[1, 1] *= -1;
  77. // Store matrices
  78. Shader.SetGlobalMatrix("_LeftWorldFromView", left_world_from_view);
  79. Shader.SetGlobalMatrix("_LeftViewFromScreen", left_view_from_screen);
  80. }
  81. }
  82. private Material shadowMat;
  83. [ImageEffectOpaque]
  84. private void OnRenderImage(RenderTexture src, RenderTexture dest)
  85. {
  86. if(EnviroManager.instance == null)
  87. {
  88. Graphics.Blit(src,dest);
  89. return;
  90. }
  91. if(myCam == null)
  92. myCam = GetComponent<Camera>();
  93. if (myCam.actualRenderingPath == RenderingPath.Forward)
  94. myCam.depthTextureMode |= DepthTextureMode.Depth;
  95. //Set what to render on this camera.
  96. bool renderVolumetricClouds = false;
  97. bool renderFog = false;
  98. if(EnviroManager.instance.VolumetricClouds != null)
  99. renderVolumetricClouds = EnviroManager.instance.VolumetricClouds.settingsQuality.volumetricClouds;
  100. if(EnviroManager.instance.Fog != null)
  101. renderFog = EnviroManager.instance.Fog.Settings.fog;
  102. ////////Rendering//////////
  103. SetMatrix();
  104. if(volumetricCloudsRender == null)
  105. volumetricCloudsRender = new EnviroVolumetricCloudRenderer();
  106. //Render volumetrics mask first
  107. if(EnviroManager.instance.Fog != null && renderFog)
  108. EnviroManager.instance.Fog.RenderVolumetrics(myCam, src);
  109. if(EnviroManager.instance.Fog != null && EnviroManager.instance.VolumetricClouds != null && renderVolumetricClouds && renderFog)
  110. {
  111. //Change the order of clouds and fog
  112. RenderTexture temp = RenderTexture.GetTemporary(src.descriptor);
  113. RenderTexture temp2 = RenderTexture.GetTemporary(src.descriptor);
  114. if(myCam.transform.position.y < EnviroManager.instance.VolumetricClouds.settingsLayer1.bottomCloudsHeight)
  115. {
  116. EnviroManager.instance.VolumetricClouds.RenderVolumetricClouds(myCam, src, temp, volumetricCloudsRender, myQuality);
  117. if(EnviroManager.instance.VolumetricClouds.settingsGlobal.cloudShadows && myCam.cameraType != CameraType.Reflection)
  118. {
  119. EnviroManager.instance.VolumetricClouds.RenderCloudsShadows(temp,temp2,volumetricCloudsRender);
  120. EnviroManager.instance.Fog.RenderHeightFog(myCam,temp2,dest);
  121. }
  122. else
  123. {
  124. EnviroManager.instance.Fog.RenderHeightFog(myCam,temp,dest);
  125. }
  126. }
  127. else
  128. {
  129. EnviroManager.instance.Fog.RenderHeightFog(myCam,src,temp);
  130. EnviroManager.instance.VolumetricClouds.RenderVolumetricClouds(myCam,temp,dest,volumetricCloudsRender,myQuality);
  131. }
  132. RenderTexture.ReleaseTemporary(temp);
  133. RenderTexture.ReleaseTemporary(temp2);
  134. }
  135. else if(EnviroManager.instance.VolumetricClouds != null && renderVolumetricClouds && !renderFog)
  136. {
  137. if(EnviroManager.instance.VolumetricClouds.settingsGlobal.cloudShadows && myCam.cameraType != CameraType.Reflection)
  138. {
  139. RenderTexture temp = RenderTexture.GetTemporary(src.descriptor);
  140. EnviroManager.instance.VolumetricClouds.RenderVolumetricClouds(myCam,src,temp,volumetricCloudsRender, myQuality);
  141. EnviroManager.instance.VolumetricClouds.RenderCloudsShadows(temp,dest,volumetricCloudsRender);
  142. RenderTexture.ReleaseTemporary(temp);
  143. }
  144. else
  145. {
  146. EnviroManager.instance.VolumetricClouds.RenderVolumetricClouds(myCam,src,dest,volumetricCloudsRender, myQuality);
  147. }
  148. }
  149. else if (Enviro.EnviroManager.instance.Fog != null && renderFog)
  150. {
  151. EnviroManager.instance.Fog.RenderHeightFog(myCam,src,dest);
  152. }
  153. else
  154. {
  155. Graphics.Blit(src,dest);
  156. }
  157. }
  158. }
  159. }