You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

385 lines
12 KiB

5 years ago
  1. using UnityEngine;
  2. using FogVolumeUtilities;
  3. [ExecuteInEditMode]
  4. public class FogVolumeScreen : MonoBehaviour
  5. {
  6. [Header("Scene blur")]
  7. [Range(1, 8)]
  8. public int Downsample = 8;
  9. [SerializeField]
  10. [Range(.001f, 15)]
  11. float _Falloff = 1;
  12. public int screenX
  13. {
  14. get
  15. {
  16. return SceneCamera.pixelWidth;
  17. }
  18. }
  19. float FOV_compensation = 0;
  20. public int screenY
  21. {
  22. get
  23. {
  24. return SceneCamera.pixelHeight;
  25. }
  26. }
  27. Shader _BlurShader = null;
  28. Camera UniformFogCamera;
  29. GameObject UniformFogCameraGO;
  30. [HideInInspector]
  31. public Camera SceneCamera;
  32. //[SerializeField]
  33. RenderTexture RT_FogVolumeConvolution;
  34. // [SerializeField]
  35. RenderTextureFormat RT_Format;
  36. [HideInInspector]
  37. public int FogVolumeLayer = -1;
  38. [SerializeField]
  39. [HideInInspector]
  40. string _FogVolumeLayerName = "FogVolumeUniform";
  41. public string FogVolumeLayerName
  42. {
  43. get { return _FogVolumeLayerName; }
  44. set
  45. {
  46. if (_FogVolumeLayerName != value)
  47. SetFogVolumeLayer(value);
  48. }
  49. }
  50. void SetFogVolumeLayer(string NewFogVolumeLayerName)
  51. {
  52. _FogVolumeLayerName = NewFogVolumeLayerName;
  53. FogVolumeLayer = LayerMask.NameToLayer(_FogVolumeLayerName);
  54. }
  55. void OnValidate()
  56. {
  57. SetFogVolumeLayer(_FogVolumeLayerName);
  58. }
  59. Material _BlurMaterial = null;
  60. Material BlurMaterial
  61. {
  62. get
  63. {
  64. if (_BlurMaterial == null)
  65. {
  66. _BlurMaterial = new Material(_BlurShader);
  67. _BlurMaterial.hideFlags = HideFlags.HideAndDontSave;
  68. }
  69. return _BlurMaterial;
  70. }
  71. }
  72. [Range(0, 10)]
  73. public int iterations = 3;
  74. // [Range(0, 1)]
  75. // public float _Dither = .8f;
  76. [Range(0.0f, 1.0f)]
  77. public float blurSpread = 0.6f;
  78. // [Range(0, 1)]
  79. // public float ImageDistortion = 0;
  80. //BLOOM stuff
  81. public enum BlurType
  82. {
  83. Standard = 0,
  84. Sgx = 1,
  85. }
  86. [Header("Bloom")]
  87. [Range(1, 5)]
  88. public int _BloomDowsample = 8;
  89. [Range(0.0f, 1.5f)]
  90. public float threshold = 0.35f;
  91. [Range(0.0f, 10)]
  92. public float intensity = 2.5f;
  93. [Range(0, 1)]
  94. public float _Saturation = 1;
  95. [Range(0, 5f)]
  96. public float blurSize = 1;
  97. [Range(1, 10)]
  98. public int blurIterations = 4;
  99. BlurType blurType = BlurType.Standard;
  100. Shader fastBloomShader = null;
  101. Material _fastBloomMaterial = null;
  102. Material fastBloomMaterial
  103. {
  104. get
  105. {
  106. if (_fastBloomMaterial == null)
  107. {
  108. _fastBloomMaterial = new Material(fastBloomShader);
  109. _fastBloomMaterial.hideFlags = HideFlags.HideAndDontSave;
  110. }
  111. return _fastBloomMaterial;
  112. }
  113. }
  114. void CreateUniformFogCamera()
  115. {
  116. UniformFogCameraGO = GameObject.Find("Uniform Fog Volume Camera");
  117. if (UniformFogCameraGO == null)
  118. {
  119. UniformFogCameraGO = new GameObject();
  120. UniformFogCameraGO.name = "Uniform Fog Volume Camera";
  121. if (UniformFogCamera == null)
  122. UniformFogCamera = UniformFogCameraGO.AddComponent<Camera>();
  123. UniformFogCamera.backgroundColor = new Color(0, 0, 0, 0);
  124. UniformFogCamera.clearFlags = CameraClearFlags.SolidColor;
  125. UniformFogCamera.renderingPath = RenderingPath.Forward;
  126. UniformFogCamera.enabled = false;
  127. UniformFogCamera.farClipPlane = SceneCamera.farClipPlane;
  128. #if UNITY_5_6_OR_NEWER
  129. UniformFogCamera.GetComponent<Camera>().allowMSAA = false;
  130. #endif
  131. }
  132. else
  133. {
  134. UniformFogCamera = UniformFogCameraGO.GetComponent<Camera>();
  135. }
  136. //UniformFogCameraGO.hideFlags = HideFlags.None;
  137. UniformFogCameraGO.hideFlags = HideFlags.HideInHierarchy;
  138. initFOV = SceneCamera.fieldOfView;
  139. }
  140. float initFOV;
  141. void OnEnable()
  142. {
  143. SceneCamera = gameObject.GetComponent<Camera>();
  144. _BlurShader = Shader.Find("Hidden/FogVolumeDensityFilter");
  145. if (_BlurShader == null) print("Hidden/FogVolumeDensityFilter #SHADER ERROR#");
  146. fastBloomShader = Shader.Find("Hidden/FogVolumeBloom");
  147. if (fastBloomShader == null) print("Hidden/FogVolumeBloom #SHADER ERROR#");
  148. CreateUniformFogCamera();
  149. }
  150. protected void OnDisable()
  151. {
  152. if (_BlurMaterial)
  153. {
  154. DestroyImmediate(_BlurMaterial);
  155. }
  156. if (_fastBloomMaterial)
  157. {
  158. DestroyImmediate(_fastBloomMaterial);
  159. }
  160. //3.2.1 lets destroy it
  161. if (UniformFogCameraGO)
  162. DestroyImmediate(UniformFogCameraGO);
  163. }
  164. public void FourTapCone(RenderTexture source, RenderTexture dest, int iteration)
  165. {
  166. float off = 0.5f + iteration * blurSpread;
  167. Graphics.BlitMultiTap(source, dest, BlurMaterial,
  168. new Vector2(-off, -off),
  169. new Vector2(-off, off),
  170. new Vector2(off, off),
  171. new Vector2(off, -off)
  172. );
  173. }
  174. // Downsamples the texture to a quarter resolution.
  175. private void DownSample4x(RenderTexture source, RenderTexture dest)
  176. {
  177. float off = 1.0f;
  178. Graphics.BlitMultiTap(source, dest, BlurMaterial,
  179. new Vector2(-off, -off),
  180. new Vector2(-off, off),
  181. new Vector2(off, off),
  182. new Vector2(off, -off)
  183. );
  184. }
  185. public RenderTextureFormat GetRTFormat()
  186. {
  187. #if UNITY_5_6_OR_NEWER
  188. RT_Format=(SceneCamera.allowHDR == true) ? RenderTextureFormat.DefaultHDR : RenderTextureFormat.Default;
  189. return RT_Format;
  190. #else
  191. RT_Format = (SceneCamera.hdr == true) ? RenderTextureFormat.DefaultHDR : RenderTextureFormat.ARGBHalf;
  192. return RT_Format;
  193. #endif
  194. //return RT_Format;
  195. }
  196. public void ReleaseRT(RenderTexture rt)
  197. {
  198. if (rt != null)
  199. {
  200. RenderTexture.ReleaseTemporary(rt);
  201. rt = null;
  202. }
  203. }
  204. public RenderTextureReadWrite GetRTReadWrite()
  205. {
  206. //return RenderTextureReadWrite.Default;
  207. #if UNITY_5_6_OR_NEWER
  208. return (SceneCamera.allowHDR) ? RenderTextureReadWrite.Default : RenderTextureReadWrite.Linear;
  209. #else
  210. return (SceneCamera.hdr) ? RenderTextureReadWrite.Default : RenderTextureReadWrite.Linear;
  211. #endif
  212. }
  213. protected void GetRT(ref RenderTexture rt, int2 size, string name)
  214. {
  215. // Release existing one
  216. ReleaseRT(rt);
  217. rt = RenderTexture.GetTemporary(size.x, size.y, 0, GetRTFormat(), GetRTReadWrite());
  218. rt.filterMode = FilterMode.Bilinear;
  219. rt.name = name;
  220. rt.wrapMode = TextureWrapMode.Repeat;
  221. }
  222. public void ConvolveFogVolume()
  223. {
  224. if (UniformFogCameraGO == null) CreateUniformFogCamera();
  225. int2 resolution = new int2(screenX, screenY);
  226. UniformFogCamera.projectionMatrix = SceneCamera.projectionMatrix;
  227. UniformFogCamera.transform.position = SceneCamera.transform.position;
  228. UniformFogCamera.transform.rotation = SceneCamera.transform.rotation;
  229. GetRT(ref RT_FogVolumeConvolution, resolution, "RT_FogVolumeConvolution");
  230. UniformFogCamera.targetTexture = RT_FogVolumeConvolution;
  231. UniformFogCamera.Render();
  232. Shader.SetGlobalTexture("RT_FogVolumeConvolution", RT_FogVolumeConvolution);
  233. }
  234. public bool SceneBloom = false;
  235. #region instance
  236. private static FogVolumeScreen _instance;
  237. public static FogVolumeScreen instance
  238. {
  239. get
  240. {
  241. if (_instance == null)
  242. {
  243. _instance = FindObjectOfType<FogVolumeScreen>();
  244. }
  245. return _instance;
  246. }
  247. }
  248. #endregion
  249. RenderTexture _source;
  250. void OnRenderImage(RenderTexture source, RenderTexture destination)
  251. {
  252. ConvolveFogVolume();
  253. GetRT(ref _source, new int2(Screen.width, Screen.height), "_source");
  254. Graphics.Blit(source, _source);
  255. fastBloomMaterial.SetTexture("_source", _source);
  256. BlurMaterial.SetTexture("_source", _source);
  257. //Graphics.Blit(_source, destination, BlurMaterial);
  258. // RT_Format = source.format;
  259. #region Density convolution
  260. UniformFogCamera.cullingMask = 1 << instance.FogVolumeLayer;
  261. //UniformFogCamera.cullingMask |= 1 << LayerMask.NameToLayer("FogVolumeUniform");//add Fog volume uniforms
  262. FOV_compensation = initFOV / SceneCamera.fieldOfView;
  263. Shader.SetGlobalFloat("FOV_compensation", FOV_compensation);
  264. fastBloomMaterial.SetFloat("_Falloff", _Falloff);
  265. // BlurMaterial.SetFloat("_Dither", _Dither);
  266. // BlurMaterial.SetFloat("_Distortion", ImageDistortion * -.08f);
  267. RenderTexture RT_DensityBlur = RenderTexture.GetTemporary(screenX / Downsample, screenY / Downsample, 0, RT_Format);
  268. DownSample4x(source, RT_DensityBlur);
  269. for (int i = 0; i < iterations; i++)
  270. {
  271. RenderTexture RT_DensityBlur2 = RenderTexture.GetTemporary(screenX / Downsample, screenY / Downsample, 0, RT_Format);
  272. FourTapCone(RT_DensityBlur, RT_DensityBlur2, i);
  273. RenderTexture.ReleaseTemporary(RT_DensityBlur);
  274. RT_DensityBlur = RT_DensityBlur2;
  275. }
  276. // Graphics.Blit(RT_DensityBlur, destination);
  277. #endregion
  278. #region Bloom
  279. if (intensity > 0)
  280. {
  281. Rendering.EnsureKeyword(fastBloomMaterial, "BLOOM", true);
  282. float widthMod = 2.0f / (float)_BloomDowsample;
  283. fastBloomMaterial.SetFloat("_Saturation", _Saturation);
  284. fastBloomMaterial.SetVector("_Parameter", new Vector4(blurSize * widthMod, 0.0f, threshold, intensity));
  285. var rtW = source.width / _BloomDowsample;
  286. var rtH = source.height / _BloomDowsample;
  287. // downsample
  288. RenderTexture rt = RenderTexture.GetTemporary(rtW, rtH, 0, RT_Format);
  289. rt.filterMode = FilterMode.Bilinear;
  290. if (SceneBloom)
  291. Graphics.Blit(source, rt, fastBloomMaterial, 1);
  292. else
  293. Graphics.Blit(RT_DensityBlur, rt, fastBloomMaterial, 1);
  294. var passOffs = blurType == BlurType.Standard ? 0 : 2;
  295. for (int i = 1; i < blurIterations; i++)
  296. {
  297. fastBloomMaterial.SetVector("_Parameter", new Vector4(blurSize * widthMod + (i * 1.0f), 0.0f, threshold, intensity));
  298. // vertical blur
  299. RenderTexture rt2 = RenderTexture.GetTemporary(rtW, rtH, 0, RT_Format);
  300. rt2.filterMode = FilterMode.Bilinear;
  301. Graphics.Blit(rt, rt2, fastBloomMaterial, 2 + passOffs);
  302. RenderTexture.ReleaseTemporary(rt);
  303. rt = rt2;
  304. // horizontal blur
  305. rt2 = RenderTexture.GetTemporary(rtW, rtH, 0, RT_Format);
  306. rt2.filterMode = FilterMode.Bilinear;
  307. Graphics.Blit(rt, rt2, fastBloomMaterial, 3 + passOffs);
  308. RenderTexture.ReleaseTemporary(rt);
  309. rt = rt2;
  310. }
  311. fastBloomMaterial.SetTexture("_Bloom", rt);
  312. RenderTexture.ReleaseTemporary(rt);
  313. }
  314. else
  315. Rendering.EnsureKeyword(fastBloomMaterial, "BLOOM", false);
  316. #endregion
  317. Graphics.Blit(RT_DensityBlur, destination, fastBloomMaterial, 0);
  318. RenderTexture.ReleaseTemporary(RT_DensityBlur);
  319. }
  320. }