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.

521 lines
16 KiB

  1. using UnityEngine;
  2. using UnityEngine.UI;
  3. /*not working on android*/
  4. [ExecuteInEditMode]
  5. public class FogVolumeDirectionalLight : MonoBehaviour
  6. {
  7. public FogVolume[] _TargetFogVolumes;
  8. public Vector2 MiniaturePosition = new Vector2(110, 320);
  9. public FogVolume _ProminentFogVolume = null;
  10. // [HideInInspector]
  11. public Material FogVolumeMaterial;
  12. public float _CameraVerticalPosition = 500;
  13. RenderTexture depthRT;
  14. public enum Resolution
  15. {
  16. _256 = 256,
  17. _512 = 512,
  18. _1024 = 1024,
  19. _2048 = 2048,
  20. _4096 = 4096
  21. };
  22. public enum Antialiasing
  23. {
  24. _1 = 1,
  25. _2 = 2,
  26. _4 = 4,
  27. _8 = 8
  28. };
  29. public Antialiasing _Antialiasing = Antialiasing._1;
  30. public Resolution Size = Resolution._512;
  31. // [Range(10, 300)]
  32. // float CameraSize = 100;
  33. //public bool ToggleKeyword = true;
  34. // [HideInInspector]
  35. public Camera ShadowCamera;
  36. public enum ScaleMode
  37. {
  38. VolumeMaxAxis,
  39. Manual
  40. };
  41. public float _FogVolumeShadowMapEdgeSoftness = 0.001f;
  42. public ScaleMode _ScaleMode = ScaleMode.VolumeMaxAxis;
  43. public LayerMask LayersToRender;
  44. [HideInInspector]
  45. public Shader outputDepth;
  46. [HideInInspector]
  47. public GameObject GOShadowCamera;
  48. public bool CameraVisible;
  49. public enum UpdateMode
  50. {
  51. OnStart,
  52. Interleaved
  53. };
  54. Image _CanvasImage;
  55. public UpdateMode _UpdateMode = UpdateMode.Interleaved;
  56. public float Scale = 50;
  57. [Range(0, 100)]
  58. public int SkipFrames = 2;
  59. // CanvasRenderer DebugCanvas;
  60. public bool ShowMiniature = false;
  61. GameObject _GO_Canvas, _GO_Image;
  62. Canvas _Canvas;
  63. public Material DebugViewMaterial;
  64. GameObject Quad;
  65. Vector3 FocusPosition;
  66. FogVolumeData _FogVolumeData;
  67. Camera _GameCamera;
  68. public enum FocusMode
  69. {
  70. VolumeCenter,
  71. GameCameraPosition,
  72. GameObject
  73. };
  74. public Transform _GameObjectFocus;
  75. public FocusMode _FocusMode = FocusMode.VolumeCenter;
  76. Material quadMaterial = null;
  77. public Material QuadMaterial
  78. {
  79. get
  80. {
  81. if (quadMaterial == null) { CreateMaterial(); }
  82. return quadMaterial;
  83. }
  84. }
  85. public Shader quadShader;
  86. void OnEnable()
  87. {
  88. _GO_Canvas = GameObject.Find("FogVolume Debug Canvas");
  89. if (!_GO_Canvas) _GO_Canvas = new GameObject("FogVolume Debug Canvas");
  90. _GO_Image = GameObject.Find("FogVolume Image");
  91. if (!_GO_Image)
  92. {
  93. _GO_Image = new GameObject("FogVolume Image");
  94. _CanvasImage = _GO_Image.AddComponent<Image>();
  95. _CanvasImage.material = DebugViewMaterial;
  96. _CanvasImage.rectTransform.position = new Vector3(MiniaturePosition.x, MiniaturePosition.y, 0);
  97. _CanvasImage.rectTransform.pivot = new Vector2(.5f, .5f);
  98. _CanvasImage.rectTransform.anchorMax = new Vector2(0, 0);
  99. _CanvasImage.rectTransform.anchorMin = new Vector2(0, 0);
  100. _CanvasImage.rectTransform.localScale = new Vector3(2, 2, 2);
  101. }
  102. if (!_CanvasImage) _CanvasImage = _GO_Image.GetComponent<Image>();
  103. _CanvasImage.material = DebugViewMaterial;
  104. _GO_Image.transform.SetParent(_GO_Canvas.transform);
  105. _GO_Canvas.AddComponent<CanvasScaler>();
  106. _GO_Canvas.GetComponent<CanvasScaler>().scaleFactor = 1;
  107. _GO_Canvas.GetComponent<CanvasScaler>().referencePixelsPerUnit = 100;
  108. _Canvas = _GO_Canvas.GetComponent<Canvas>(); // ("Debug view canvas");
  109. _GO_Canvas.hideFlags = HideFlags.HideInHierarchy;
  110. // DebugCanvas = _GO_Canvas.AddComponent<CanvasRenderer>();
  111. _GO_Canvas.layer = LayerMask.NameToLayer("UI");
  112. _GO_Image.layer = LayerMask.NameToLayer("UI");
  113. _Canvas.renderMode = RenderMode.ScreenSpaceOverlay;
  114. Initialize();
  115. if (_UpdateMode == UpdateMode.OnStart) { Render(); }
  116. }
  117. void CreateMaterial()
  118. {
  119. DestroyImmediate(quadMaterial);
  120. quadShader = Shader.Find("Hidden/DepthMapQuad");
  121. //
  122. quadMaterial = new Material(quadShader);
  123. quadMaterial.name = "Depth camera quad material";
  124. quadMaterial.hideFlags = HideFlags.HideAndDontSave;
  125. }
  126. RenderTextureFormat rt_DepthFormat;
  127. void Initialize()
  128. {
  129. CreateMaterial();
  130. if (SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.RGFloat))
  131. rt_DepthFormat = RenderTextureFormat.RGFloat;
  132. else
  133. rt_DepthFormat = RenderTextureFormat.DefaultHDR;
  134. GameObject FogVolumeDataGO = GameObject.Find("Fog Volume Data");
  135. if (FogVolumeDataGO) _FogVolumeData = FogVolumeDataGO.GetComponent<FogVolumeData>();
  136. else return;
  137. _GameCamera = _FogVolumeData.GameCamera;
  138. GOShadowCamera = GameObject.Find("FogVolumeShadowCamera");
  139. if (!GOShadowCamera)
  140. {
  141. GOShadowCamera = new GameObject();
  142. GOShadowCamera.name = "FogVolumeShadowCamera";
  143. }
  144. if (!GOShadowCamera) print("Shadow camera is lost");
  145. else ShadowCamera = GOShadowCamera.GetComponent<Camera>();
  146. if (!depthRT)
  147. {
  148. depthRT = new RenderTexture((int) Size, (int) Size, 16, rt_DepthFormat);
  149. depthRT.antiAliasing = (int) _Antialiasing;
  150. depthRT.filterMode = FilterMode.Bilinear;
  151. depthRT.name = "FogVolumeShadowMap";
  152. depthRT.wrapMode = TextureWrapMode.Clamp;
  153. }
  154. if (!ShadowCamera) ShadowCamera = GOShadowCamera.AddComponent<Camera>();
  155. else ShadowCamera = GOShadowCamera.GetComponent<Camera>();
  156. ShadowCamera.clearFlags = CameraClearFlags.Color;
  157. ShadowCamera.backgroundColor = Color.black;
  158. ShadowCamera.orthographic = true;
  159. ShadowCamera.farClipPlane = 10000.0f;
  160. ShadowCamera.enabled = false;
  161. ShadowCamera.stereoTargetEye = StereoTargetEyeMask.None;
  162. ShadowCamera.targetTexture = depthRT;
  163. ShadowCamera.cullingMask &= ~(1 << LayerMask.NameToLayer("FogVolume"));
  164. ShadowCamera.cullingMask &= ~(1 << LayerMask.NameToLayer("FogVolumeUniform"));
  165. ShadowCamera.cullingMask &= ~(1 << LayerMask.NameToLayer("FogVolumeSurrogate"));
  166. ShadowCamera.cullingMask &= ~(1 << LayerMask.NameToLayer("FogVolumeShadowCaster"));
  167. //make it child
  168. ShadowCamera.transform.parent = gameObject.transform;
  169. Quad = GameObject.Find("Depth map background");
  170. if (!Quad) Quad = GameObject.CreatePrimitive(PrimitiveType.Quad);
  171. Quad.name = "Depth map background";
  172. Quad.GetComponent<MeshRenderer>().sharedMaterial = QuadMaterial;
  173. Quad.transform.parent = ShadowCamera.transform;
  174. //remnove the collider
  175. DestroyImmediate(Quad.GetComponent<MeshCollider>());
  176. Quad.hideFlags = HideFlags.HideInHierarchy;
  177. }
  178. void EnableVolumetricShadow(bool b)
  179. {
  180. if (_TargetFogVolumes == null) { return; }
  181. if (_TargetFogVolumes.Length > 0)
  182. {
  183. float largestAxis = 0.0f;
  184. int largestIndex = 0;
  185. for (int FVindex = 0; FVindex < _TargetFogVolumes.Length; FVindex++)
  186. {
  187. var fogVolume = _TargetFogVolumes[FVindex];
  188. if ((fogVolume != null) && (fogVolume._FogType == FogVolume.FogType.Textured))
  189. {
  190. if (fogVolume.enabled)
  191. {
  192. FogVolumeMaterial = fogVolume.FogMaterial;
  193. FogVolumeMaterial.SetInt("_VolumetricShadowsEnabled", b ? 1 : 0);
  194. }
  195. float largest = _MaxOf(fogVolume.fogVolumeScale.x,
  196. fogVolume.fogVolumeScale.y,
  197. fogVolume.fogVolumeScale.z);
  198. if (largest > largestAxis)
  199. {
  200. largestAxis = largest;
  201. largestIndex = FVindex;
  202. }
  203. }
  204. }
  205. _ProminentFogVolume = _TargetFogVolumes[largestIndex];
  206. }
  207. }
  208. void Update()
  209. {
  210. if (_CanvasImage.material != null) _CanvasImage.material = DebugViewMaterial;
  211. if (!ShadowCamera) Initialize();
  212. if (_TargetFogVolumes != null && _AtLeastOneFogVolumeInArray())
  213. {
  214. EnableVolumetricShadow(depthRT);
  215. LayersToRender &= ~(1 << LayerMask.NameToLayer("FogVolume"));
  216. LayersToRender &= ~(1 << LayerMask.NameToLayer("FogVolumeUniform"));
  217. LayersToRender &= ~(1 << LayerMask.NameToLayer("FogVolumeSurrogate"));
  218. LayersToRender &= ~(1 << LayerMask.NameToLayer("FogVolumeShadowCaster"));
  219. ShadowCamera.cullingMask = LayersToRender;
  220. Refresh();
  221. //
  222. //now, adjust camera size to make it see the whole volume
  223. if (_ScaleMode == ScaleMode.VolumeMaxAxis)
  224. {
  225. if (_ProminentFogVolume != null)
  226. {
  227. ShadowCamera.orthographicSize =
  228. _MaxOf(_ProminentFogVolume.fogVolumeScale.x,
  229. _ProminentFogVolume.fogVolumeScale.y,
  230. _ProminentFogVolume.fogVolumeScale.z) * .5f;
  231. }
  232. }
  233. else ShadowCamera.orthographicSize = Scale;
  234. // ShadowCamera.orthographicSize = CameraSize;
  235. if (ShadowCamera.cullingMask != 0 &&
  236. _ProminentFogVolume != null &&
  237. _UpdateMode == UpdateMode.Interleaved)
  238. {
  239. if (FogVolumeUtilities.ExtensionMethods.TimeSnap(SkipFrames))
  240. {
  241. Render();
  242. }
  243. }
  244. }
  245. else
  246. {
  247. if (depthRT)
  248. {
  249. DestroyImmediate(depthRT);
  250. DestroyImmediate(GOShadowCamera);
  251. }
  252. }
  253. if (!ShowMiniature &&
  254. _GO_Canvas.activeInHierarchy) _GO_Canvas.SetActive(ShowMiniature);
  255. if (ShowMiniature && !_GO_Canvas.activeInHierarchy) _GO_Canvas.SetActive(ShowMiniature);
  256. #if UNITY_EDITOR
  257. if(ShowMiniature)
  258. _CanvasImage.rectTransform.position = new Vector3(MiniaturePosition.x, MiniaturePosition.y, 0);
  259. #endif
  260. }
  261. public void Refresh()
  262. {
  263. if (_TargetFogVolumes == null)
  264. {
  265. _ProminentFogVolume = null;
  266. return;
  267. }
  268. for (int i = 0; i < _TargetFogVolumes.Length; i++)
  269. {
  270. var fogVolume = _TargetFogVolumes[i];
  271. if ((fogVolume != null) &&
  272. (fogVolume._FogType == FogVolume.FogType.Textured))
  273. {
  274. if (fogVolume.HasUpdatedBoxMesh)
  275. {
  276. float largestOfProminent = (_ProminentFogVolume != null)
  277. ? _MaxOf(_ProminentFogVolume.fogVolumeScale.x,
  278. _ProminentFogVolume.fogVolumeScale.y,
  279. _ProminentFogVolume.fogVolumeScale.z)
  280. : 0.0f;
  281. float largest = _MaxOf(fogVolume.fogVolumeScale.x,
  282. fogVolume.fogVolumeScale.y,
  283. fogVolume.fogVolumeScale.z);
  284. if (largest > largestOfProminent) { _ProminentFogVolume = fogVolume; }
  285. }
  286. }
  287. }
  288. }
  289. public void Render()
  290. {
  291. if (!depthRT)
  292. {
  293. Initialize();
  294. }
  295. if (depthRT.height != (int) Size)
  296. {
  297. DestroyImmediate(depthRT);
  298. Initialize();
  299. // Debug.Log("A tomar por culo la textura");
  300. }
  301. if ((int) _Antialiasing != depthRT.antiAliasing)
  302. {
  303. DestroyImmediate(depthRT);
  304. Initialize();
  305. }
  306. if (!ShadowCamera)
  307. {
  308. Initialize();
  309. }
  310. switch (_FocusMode)
  311. {
  312. case FocusMode.GameCameraPosition:
  313. FocusPosition = _GameCamera.transform.position;
  314. break;
  315. case FocusMode.VolumeCenter:
  316. if (_ProminentFogVolume != null)
  317. {
  318. FocusPosition = _ProminentFogVolume.transform.position;
  319. }
  320. else
  321. {
  322. FocusPosition = Vector3.zero;
  323. }
  324. break;
  325. case FocusMode.GameObject:
  326. if (_GameObjectFocus) FocusPosition = _GameObjectFocus.transform.position;
  327. break;
  328. }
  329. //move the camera to the target center
  330. Vector3 VerticalTranslate = new Vector3(0,
  331. 0, /* _TargetFogVolume.fogVolumeScale.y / 2*/
  332. FocusPosition.y - _CameraVerticalPosition);
  333. ShadowCamera.transform.position = FocusPosition;
  334. ShadowCamera.transform.Translate(VerticalTranslate, Space.Self);
  335. Vector3 QuadScale = new Vector3(ShadowCamera.orthographicSize * 2,
  336. ShadowCamera.orthographicSize * 2,
  337. ShadowCamera.orthographicSize * 2);
  338. Quad.transform.localScale = QuadScale;
  339. //move it to the farclip
  340. Quad.transform.position = ShadowCamera.transform.position;
  341. Vector3 QuadTranslate = new Vector3(0, 0, ShadowCamera.farClipPlane - 50);
  342. Quad.transform.Translate(QuadTranslate, Space.Self);
  343. ShadowCamera.transform.rotation = Quaternion.LookRotation(transform.forward);
  344. ;
  345. Shader.SetGlobalVector("_ShadowCameraPosition", ShadowCamera.transform.position);
  346. Shader.SetGlobalMatrix("_ShadowCameraProjection", ShadowCamera.worldToCameraMatrix);
  347. Shader.SetGlobalFloat("_ShadowCameraSize", ShadowCamera.orthographicSize);
  348. Shader.SetGlobalVector("_ShadowLightDir", ShadowCamera.transform.forward);
  349. //depthRT.DiscardContents();
  350. quadShader.maximumLOD = 1;
  351. Shader.SetGlobalFloat("_FogVolumeShadowMapEdgeSoftness",
  352. 20.0f / _FogVolumeShadowMapEdgeSoftness);
  353. ShadowCamera.RenderWithShader(outputDepth, "RenderType");
  354. quadShader.maximumLOD = 100;
  355. Shader.SetGlobalTexture("_ShadowTexture", depthRT);
  356. }
  357. void OnDisable()
  358. {
  359. DestroyImmediate(depthRT);
  360. if (_GO_Canvas) _GO_Canvas.SetActive(false);
  361. // DestroyImmediate(_Canvas);
  362. // DestroyImmediate(GOShadowCamera);
  363. // if (FogVolumeMaterial)
  364. // FogVolumeUtilities.Rendering.EnsureKeyword(FogVolumeMaterial, "VOLUMETRIC_SHADOWS", false);
  365. // FogVolumeMaterial.SetInt("_VolumetricShadowsEnabled", 0);
  366. EnableVolumetricShadow(false);
  367. }
  368. private void OnDestroy()
  369. {
  370. DestroyImmediate(GOShadowCamera);
  371. // print("A la mierda!");
  372. DestroyImmediate(_GO_Canvas);
  373. DestroyImmediate(Quad);
  374. }
  375. private bool _AtLeastOneFogVolumeInArray()
  376. {
  377. if (_TargetFogVolumes != null)
  378. {
  379. for (int i = 0; i < _TargetFogVolumes.Length; i++)
  380. {
  381. if (_TargetFogVolumes[i] != null) { return true; }
  382. }
  383. }
  384. return false;
  385. }
  386. public void AddAllFogVolumesToThisLight()
  387. {
  388. _ProminentFogVolume = null;
  389. var fogVolumes = FindObjectsOfType<FogVolume>();
  390. int validFogVolumeCount = 0;
  391. for (int i = 0; i < fogVolumes.Length; i++)
  392. {
  393. if ((fogVolumes[i] != null) &&
  394. (fogVolumes[i]._FogType == FogVolume.FogType.Textured)) { validFogVolumeCount++; }
  395. }
  396. _TargetFogVolumes = new FogVolume[validFogVolumeCount];
  397. int k = 0;
  398. for (var i = 0; i < fogVolumes.Length; i++)
  399. {
  400. var fogVolume = fogVolumes[i];
  401. if ((fogVolume != null) && (fogVolume._FogType == FogVolume.FogType.Textured))
  402. {
  403. _TargetFogVolumes[k++] = fogVolumes[i];
  404. }
  405. }
  406. }
  407. public void RemoveAllFogVolumesFromThisLight()
  408. {
  409. _ProminentFogVolume = null;
  410. _TargetFogVolumes = null;
  411. }
  412. private float _MaxOf(float _a, float _b) { return _a >= _b ? _a : _b; }
  413. private float _MaxOf(float _a, float _b, float _c) { return _MaxOf(_MaxOf(_a, _b), _c); }
  414. }