LuxURP_Wind.cs 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5. #if UNITY_EDITOR
  6. using UnityEditor;
  7. #endif
  8. namespace LuxURPEssentials
  9. {
  10. [System.Serializable]
  11. public enum RTSize {
  12. _128 = 128,
  13. _256 = 256,
  14. _512 = 512
  15. }
  16. [System.Serializable]
  17. public enum RTFormat {
  18. ARGB32 = 0,
  19. ARGBHalf = 1
  20. }
  21. [System.Serializable]
  22. public enum GustMixLayer {
  23. Layer_0 = 0,
  24. Layer_1 = 1,
  25. Layer_2 = 2
  26. }
  27. [ExecuteInEditMode]
  28. //[ExecuteAlways]
  29. [RequireComponent(typeof(WindZone))]
  30. //[HelpURL("https://docs.google.com/document/d/1ck3hmPzKUdewHfwsvmPYwSPCP8azwtpzN7aOLJHvMqE/edit#heading=h.wnnhm4pxp610")]
  31. public class LuxURP_Wind : MonoBehaviour {
  32. // using order to fix header/button issue
  33. [Space(5)]
  34. [LuxURP_HelpBtn("h.wnnhm4pxp610")]
  35. [Space(-5)]
  36. public bool UpdateInEditMode = false;
  37. [Header("Render Texture Settings")]
  38. public RTSize Resolution = RTSize._256;
  39. public RTFormat Format = RTFormat.ARGB32;
  40. public Texture WindBaseTex;
  41. public Shader WindCompositeShader;
  42. [Header("Wind Multipliers")]
  43. public float Grass = 1.0f;
  44. public float Foliage = 1.0f;
  45. [Header("Wind Speed and Size")]
  46. [Tooltip("Base Wind Speed in km/h at Main = 1 (WindZone)")]
  47. public float BaseWindSpeed = 15;
  48. [Tooltip("Size of the Wind RenderTexture in World Space")]
  49. public float SizeInWorldSpace = 50;
  50. [Space(5)]
  51. public float speedLayer0 = 1.0f;
  52. public float speedLayer1 = 1.137f;
  53. public float speedLayer2 = 1.376f;
  54. [Header("Noise")]
  55. public int GrassGustTiling = 4;
  56. public float GrassGustSpeed = 0.278f;
  57. public GustMixLayer LayerToMixWith = GustMixLayer.Layer_1;
  58. [Header("Jitter")]
  59. public float JitterFrequency = 3.127f;
  60. public float JitterHighFrequency = 21.0f;
  61. private RenderTexture WindRenderTexture;
  62. private Material m_material;
  63. private Vector2 uvs = new Vector2(0,0);
  64. private Vector2 uvs1 = new Vector2(0,0);
  65. private Vector2 uvs2 = new Vector2(0,0);
  66. private Vector2 uvs3 = new Vector2(0,0);
  67. private int WindRTPID;
  68. private Transform trans;
  69. private WindZone windZone;
  70. private float mainWind;
  71. private float turbulence;
  72. private int LuxLWRPWindDirSizePID;
  73. private int LuxLWRPWindStrengthMultipliersPID;
  74. private int LuxLWRPSinTimePID;
  75. private int LuxLWRPGustPID;
  76. private int LuxLWRPGustMixLayerPID;
  77. private int LuxLWRPWindUVsPID;
  78. private int LuxLWRPWindUVs1PID;
  79. private int LuxLWRPWindUVs2PID;
  80. private int LuxLWRPWindUVs3PID;
  81. private int previousRTSize;
  82. private int previousRTFormat;
  83. private Vector4 WindDirectionSize = Vector4.zero;
  84. private static Vector3[] MixLayers = new [] { new Vector3(1f,0f,0f), new Vector3(0f,1f,0f), new Vector3(0f,0f,1f) };
  85. #if UNITY_EDITOR
  86. private double lastTimeStamp = 0.0;
  87. #endif
  88. void OnEnable () {
  89. if(WindCompositeShader == null) {
  90. WindCompositeShader = Shader.Find("Hidden/Lux URP WindComposite");
  91. }
  92. if (WindBaseTex == null ) {
  93. WindBaseTex = Resources.Load("Lux URP default wind base texture") as Texture;
  94. }
  95. SetupRT();
  96. GetPIDs();
  97. trans = this.transform;
  98. windZone = trans.GetComponent<WindZone>();
  99. previousRTSize = (int)Resolution;
  100. previousRTFormat = (int)Format;
  101. #if UNITY_EDITOR
  102. EditorApplication.update += OnEditorUpdate;
  103. #endif
  104. }
  105. void OnDisable () {
  106. if (WindRenderTexture != null) {
  107. WindRenderTexture.Release();
  108. UnityEngine.Object.DestroyImmediate(WindRenderTexture);
  109. }
  110. if (m_material != null) {
  111. UnityEngine.Object.DestroyImmediate(m_material);
  112. m_material = null;
  113. }
  114. if (WindBaseTex != null) {
  115. WindBaseTex = null;
  116. }
  117. #if UNITY_EDITOR
  118. EditorApplication.update -= OnEditorUpdate;
  119. #endif
  120. }
  121. #if UNITY_EDITOR
  122. void OnEditorUpdate() {
  123. if(!Application.isPlaying && UpdateInEditMode) {
  124. Update();
  125. // Unity 2019.1.10 on macOS using Metal also needs this
  126. SceneView.RepaintAll();
  127. }
  128. }
  129. #endif
  130. void SetupRT () {
  131. if (WindRenderTexture == null || m_material == null)
  132. {
  133. var rtf = ((int)Format == 0) ? RenderTextureFormat.ARGB32 : RenderTextureFormat.ARGBHalf;
  134. WindRenderTexture = new RenderTexture((int)Resolution, (int)Resolution, 0, rtf, RenderTextureReadWrite.Linear );
  135. WindRenderTexture.useMipMap = true;
  136. WindRenderTexture.wrapMode = TextureWrapMode.Repeat;
  137. m_material = new Material(WindCompositeShader);
  138. }
  139. }
  140. void GetPIDs () {
  141. WindRTPID = Shader.PropertyToID("_LuxLWRPWindRT");
  142. LuxLWRPWindDirSizePID = Shader.PropertyToID("_LuxLWRPWindDirSize");
  143. LuxLWRPWindStrengthMultipliersPID = Shader.PropertyToID("_LuxLWRPWindStrengthMultipliers");
  144. LuxLWRPSinTimePID = Shader.PropertyToID("_LuxLWRPSinTime");
  145. LuxLWRPGustPID = Shader.PropertyToID("_LuxLWRPGust");
  146. LuxLWRPWindUVsPID = Shader.PropertyToID("_LuxLWRPWindUVs");
  147. LuxLWRPWindUVs1PID = Shader.PropertyToID("_LuxLWRPWindUVs1");
  148. LuxLWRPWindUVs2PID = Shader.PropertyToID("_LuxLWRPWindUVs2");
  149. LuxLWRPWindUVs3PID = Shader.PropertyToID("_LuxLWRPWindUVs3");
  150. LuxLWRPGustMixLayerPID = Shader.PropertyToID("_GustMixLayer");
  151. }
  152. void OnValidate () {
  153. if(WindCompositeShader == null) {
  154. WindCompositeShader = Shader.Find("Hidden/Lux LWRP WindComposite");
  155. }
  156. if (WindBaseTex == null ) {
  157. WindBaseTex = Resources.Load("Default wind base texture") as Texture;
  158. }
  159. if ( (previousRTSize != (int)Resolution ) || ( previousRTFormat != (int)Format ) ) {
  160. var rtf = ((int)Format == 0) ? RenderTextureFormat.ARGB32 : RenderTextureFormat.ARGBHalf;
  161. WindRenderTexture = new RenderTexture((int)Resolution, (int)Resolution, 0, rtf, RenderTextureReadWrite.Linear );
  162. WindRenderTexture.useMipMap = true;
  163. WindRenderTexture.wrapMode = TextureWrapMode.Repeat;
  164. }
  165. }
  166. void Update () {
  167. // Get wind settings from WindZone
  168. mainWind = windZone.windMain;
  169. turbulence = windZone.windTurbulence;
  170. float delta = Time.deltaTime;
  171. #if UNITY_EDITOR
  172. if(!Application.isPlaying) {
  173. delta = (float)(EditorApplication.timeSinceStartup - lastTimeStamp);
  174. lastTimeStamp = EditorApplication.timeSinceStartup;
  175. }
  176. #endif
  177. WindDirectionSize.x = trans.forward.x;
  178. WindDirectionSize.y = trans.forward.y;
  179. WindDirectionSize.z = trans.forward.z;
  180. WindDirectionSize.w = 1.0f / SizeInWorldSpace;
  181. var windVec = new Vector2(WindDirectionSize.x, WindDirectionSize.z ) * delta * (BaseWindSpeed * 0.2777f * WindDirectionSize.w); // * mainWind);
  182. uvs -= windVec * speedLayer0;
  183. uvs.x = uvs.x - (int)uvs.x;
  184. uvs.y = uvs.y - (int)uvs.y;
  185. uvs1 -= windVec * speedLayer1;
  186. uvs1.x = uvs1.x - (int)uvs1.x;
  187. uvs1.y = uvs1.y - (int)uvs1.y;
  188. uvs2 -= windVec * speedLayer2;
  189. uvs2.x = uvs2.x - (int)uvs2.x;
  190. uvs2.y = uvs2.y - (int)uvs2.y;
  191. uvs3 -= windVec * GrassGustSpeed * turbulence;
  192. uvs3.x = uvs3.x - (int)uvs3.x;
  193. uvs3.y = uvs3.y - (int)uvs3.y;
  194. // Set global shader variables for grass and foliage shaders
  195. Shader.SetGlobalVector(LuxLWRPWindDirSizePID, WindDirectionSize);
  196. Vector2 tempWindstrengths;
  197. tempWindstrengths.x = Grass * mainWind;
  198. tempWindstrengths.y = Foliage * mainWind;
  199. Shader.SetGlobalVector(LuxLWRPWindStrengthMultipliersPID, tempWindstrengths );
  200. // Use clamped turbulence as otherwise wind direction might get "reversed"
  201. Shader.SetGlobalVector(LuxLWRPGustPID, new Vector2(GrassGustTiling, Mathf.Clamp( turbulence + 0.5f, 0.0f, 1.5f)) );
  202. // Jitter frequncies and strength
  203. Shader.SetGlobalVector(LuxLWRPSinTimePID, new Vector4(
  204. (float)Math.Sin(Time.time * JitterFrequency),
  205. (float)Math.Sin(Time.time * JitterFrequency * 0.2317f + 2.0f * Mathf.PI),
  206. (float)Math.Sin(Time.time * JitterHighFrequency),
  207. turbulence * 0.1f
  208. ));
  209. // Set UVs
  210. Shader.SetGlobalVector(LuxLWRPWindUVsPID, uvs);
  211. Shader.SetGlobalVector(LuxLWRPWindUVs1PID, uvs1);
  212. Shader.SetGlobalVector(LuxLWRPWindUVs2PID, uvs2);
  213. Shader.SetGlobalVector(LuxLWRPWindUVs3PID, uvs3);
  214. // Set Mix Layer
  215. Shader.SetGlobalVector(LuxLWRPGustMixLayerPID, MixLayers[(int)LayerToMixWith]);
  216. #if UNITY_EDITOR
  217. if (m_material != null && WindRenderTexture != null ) {
  218. #endif
  219. Graphics.Blit(WindBaseTex, WindRenderTexture, m_material);
  220. WindRenderTexture.SetGlobalShaderProperty("_LuxLWRPWindRT"); // only accepts strings...
  221. #if UNITY_EDITOR
  222. }
  223. #endif
  224. }
  225. #if UNITY_EDITOR
  226. void OnRenderObject() {
  227. //Update();
  228. }
  229. #endif
  230. }
  231. }