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.

261 lines
8.2 KiB

5 years ago
  1. using UnityEngine;
  2. using UnityEngine.Profiling;
  3. [ExecuteInEditMode]
  4. public class ShadowCamera : MonoBehaviour
  5. {
  6. Camera ThisCamera = null;
  7. GameObject Dad = null;
  8. FogVolume Fog = null;
  9. public RenderTexture RT_Opacity, RT_OpacityBlur, RT_PostProcess;
  10. public RenderTexture GetOpacityRT()
  11. {
  12. return RT_Opacity;
  13. }
  14. public RenderTexture GetOpacityBlurRT()
  15. {
  16. return RT_OpacityBlur;
  17. }
  18. [System.Serializable]
  19. public enum TextureSize
  20. {
  21. _64 = 64,
  22. _128 = 128,
  23. _256 = 256,
  24. _512 = 512,
  25. _1024 = 1024
  26. };
  27. public TextureSize SetTextureSize
  28. {
  29. set
  30. {
  31. if (value != textureSize)
  32. SetQuality(value);
  33. }
  34. get
  35. {
  36. return textureSize;
  37. }
  38. }
  39. public TextureSize textureSize = TextureSize._128;
  40. /// Blur iterations - larger number means more blur.
  41. [Range(0, 10)]
  42. public int iterations = 3;
  43. /// Blur spread for each iteration. Lower values
  44. /// give better looking blur, but require more iterations to
  45. /// get large blurs. Value is usually between 0.5 and 1.0.
  46. [Range(0.0f, 1)]
  47. public float blurSpread = 0.6f;
  48. public int Downsampling = 2;
  49. void SetQuality(TextureSize value)
  50. {
  51. textureSize = value;
  52. // print((int)textureSize);
  53. }
  54. Shader blurShader = null;
  55. Shader PostProcessShader = null;
  56. Material blurMaterial = null;
  57. Material postProcessMaterial = null;
  58. protected Material BlurMaterial
  59. {
  60. get
  61. {
  62. if (blurMaterial == null)
  63. {
  64. blurMaterial = new Material(blurShader);
  65. blurMaterial.hideFlags = HideFlags.DontSave;
  66. }
  67. return blurMaterial;
  68. }
  69. }
  70. protected Material PostProcessMaterial
  71. {
  72. get
  73. {
  74. if (postProcessMaterial == null)
  75. {
  76. postProcessMaterial = new Material(PostProcessShader);
  77. postProcessMaterial.hideFlags = HideFlags.DontSave;
  78. }
  79. return postProcessMaterial;
  80. }
  81. }
  82. protected void GetRT(ref RenderTexture rt, int size, string name)
  83. {
  84. // Release existing one
  85. ReleaseRT(rt);
  86. rt = RenderTexture.GetTemporary(size, size, 0, RenderTextureFormat.R8, RenderTextureReadWrite.Linear);
  87. rt.filterMode = FilterMode.Bilinear;
  88. rt.name = name;
  89. rt.wrapMode = TextureWrapMode.Repeat;
  90. }
  91. public void ReleaseRT(RenderTexture rt)
  92. {
  93. if (rt != null)
  94. {
  95. RenderTexture.ReleaseTemporary(rt);
  96. rt = null;
  97. }
  98. }
  99. // Performs one blur iteration.
  100. public void FourTapCone(RenderTexture source, RenderTexture dest, int iteration)
  101. {
  102. float off = 0.5f + iteration * blurSpread;
  103. Graphics.BlitMultiTap(source, dest, BlurMaterial,
  104. new Vector2(-off, -off),
  105. new Vector2(-off, off),
  106. new Vector2(off, off),
  107. new Vector2(off, -off)
  108. );
  109. }
  110. // Downsamples the texture to a quarter resolution.
  111. private void DownSample(RenderTexture source, RenderTexture dest)
  112. {
  113. float off = 1.0f;
  114. Graphics.BlitMultiTap(source, dest, BlurMaterial,
  115. new Vector2(-off, -off),
  116. new Vector2(-off, off),
  117. new Vector2(off, off),
  118. new Vector2(off, -off)
  119. );
  120. }
  121. void Blur(RenderTexture Input, int BlurRTSize)
  122. {
  123. RenderTexture RT_OpacityBlur2 = null;
  124. GetRT(ref RT_OpacityBlur, BlurRTSize, "Shadow blurred");
  125. GetRT(ref RT_OpacityBlur2, BlurRTSize, "Shadow blurred");
  126. // Copy source to the smaller texture.
  127. DownSample(Input, RT_OpacityBlur);
  128. //Graphics.Blit(Input, RT_OpacityBlur);
  129. // Blur the small texture
  130. for (int i = 0; i < iterations; i++)
  131. {
  132. FourTapCone(RT_OpacityBlur, RT_OpacityBlur2, i);
  133. FogVolumeUtilities.ExtensionMethods.Swap(ref RT_OpacityBlur, ref RT_OpacityBlur2);
  134. }
  135. Shader.SetGlobalTexture("RT_OpacityBlur", RT_OpacityBlur);
  136. Fog.RT_OpacityBlur = RT_OpacityBlur;
  137. }
  138. void RenderShadowMap()
  139. {
  140. //ideally, a cheaper version should be rendered here.
  141. //So lets render a version with no lighting stuff
  142. Profiler.BeginSample(Fog.name + " shadows");
  143. Fog.FogVolumeShader.maximumLOD = 100;
  144. SetQuality(textureSize);
  145. GetRT(ref RT_Opacity, (int)textureSize, "Opacity");
  146. ThisCamera.targetTexture = RT_Opacity;
  147. // print(Fog.ShadowCameraSkippedFrames);
  148. ThisCamera.Render();
  149. Fog.RT_Opacity = RT_Opacity;
  150. // Shader.SetGlobalTexture("RT_Opacity", RT_Opacity);
  151. if (RT_Opacity != null)
  152. {
  153. GetRT(ref RT_PostProcess, (int)textureSize, "Shadow PostProcess");
  154. PostProcessMaterial.SetFloat("ShadowColor", Fog.ShadowColor.a);
  155. // PostProcessMaterial.SetFloat("_jitter", Fog._jitter);
  156. Graphics.Blit(RT_Opacity, RT_PostProcess, PostProcessMaterial);
  157. // ThisCamera.targetTexture = null;
  158. Graphics.Blit(RT_PostProcess, RT_Opacity);
  159. //RenderTexture.ReleaseTemporary(RT_Opacity);
  160. if (iterations > 0)
  161. {
  162. Blur(RT_Opacity, (int)textureSize >> Downsampling);
  163. }
  164. else
  165. {
  166. Shader.SetGlobalTexture("RT_OpacityBlur", RT_Opacity);
  167. Fog.RT_OpacityBlur = RT_Opacity;
  168. }
  169. Fog.RT_Opacity = RT_Opacity;
  170. }
  171. //Shader.SetGlobalTexture("RT_Opacity", RT_Opacity);
  172. BlurMaterial.SetFloat("ShadowColor", Fog.ShadowColor.a);
  173. // back to normal
  174. Fog.FogVolumeShader.maximumLOD = 600;
  175. Profiler.EndSample();
  176. }
  177. void ShaderLoad()
  178. {
  179. blurShader = Shader.Find("Hidden/Fog Volume/BlurEffectConeTap");
  180. if (blurShader == null) print("Hidden / Fog Volume / BlurEffectConeTap #SHADER ERROR#");
  181. PostProcessShader = Shader.Find("Hidden/Fog Volume/Shadow Postprocess");
  182. if (PostProcessShader == null) print("Hidden/Fog Volume/Shadow Postprocess #SHADER ERROR#");
  183. }
  184. void OnEnable()
  185. {
  186. ShaderLoad();
  187. Dad = transform.parent.gameObject;
  188. Fog = Dad.GetComponent<FogVolume>();
  189. ThisCamera = gameObject.GetComponent<Camera>();
  190. ThisCamera.depthTextureMode = DepthTextureMode.Depth;
  191. CameraTransform();
  192. }
  193. public void CameraTransform()
  194. {
  195. if (ThisCamera != null)
  196. {
  197. ThisCamera.orthographicSize = Dad.GetComponent<FogVolume>().fogVolumeScale.x / 2;
  198. ThisCamera.transform.position = Dad.transform.position;
  199. ThisCamera.farClipPlane = Fog.fogVolumeScale.y + Fog.shadowCameraPosition;
  200. // print(ThisCamera.farClipPlane);
  201. Vector3 VerticalTranslate = new Vector3(0, 0, Fog.fogVolumeScale.y / 2 - Fog.shadowCameraPosition);
  202. // print(Fog.ShadowCameraPosition);
  203. ThisCamera.transform.Translate(VerticalTranslate, Space.Self);
  204. Quaternion target = Quaternion.Euler(90, 0, 0);
  205. ThisCamera.transform.rotation = Dad.transform.rotation * target;
  206. ThisCamera.enabled = false;
  207. if (Fog.SunAttached)
  208. {
  209. Fog.Sun.transform.rotation = Dad.transform.rotation * target;
  210. }
  211. }
  212. }
  213. // Update is called once per frame
  214. void Update()
  215. {
  216. // print(Fog.name + " visibility: " + Fog.IsVisible);
  217. if (Fog.IsVisible && Fog.CastShadows)//3.1.7
  218. {
  219. if (FogVolumeUtilities.ExtensionMethods.TimeSnap(Fog.ShadowCameraSkippedFrames))
  220. RenderShadowMap();
  221. #if UNITY_EDITOR
  222. CameraTransform();
  223. #endif
  224. }
  225. }
  226. void OnDisable()
  227. {
  228. RenderTexture.active = null;
  229. ThisCamera.targetTexture = null;
  230. if (RT_Opacity) DestroyImmediate(RT_Opacity);
  231. if (RT_OpacityBlur) DestroyImmediate(RT_OpacityBlur);
  232. if (RT_PostProcess) DestroyImmediate(RT_PostProcess);
  233. if (blurMaterial) DestroyImmediate(blurMaterial);
  234. if (postProcessMaterial) DestroyImmediate(postProcessMaterial);
  235. }
  236. }