No Description
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.

SpeedTree8Wind.hlsl 35KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977
  1. // Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
  2. #ifndef SPEEDTREE_WIND_8_INCLUDED
  3. #define SPEEDTREE_WIND_8_INCLUDED
  4. #define SPEEDTREE_VERSION_8 1
  5. #include "SpeedTreeCommon.hlsl"
  6. ///////////////////////////////////////////////////////////////////////
  7. // Wind Info
  8. CBUFFER_START(SpeedTreeWind)
  9. float4 _ST_WindVector;
  10. float4 _ST_WindGlobal;
  11. float4 _ST_WindBranch;
  12. float4 _ST_WindBranchTwitch;
  13. float4 _ST_WindBranchWhip;
  14. float4 _ST_WindBranchAnchor;
  15. float4 _ST_WindBranchAdherences;
  16. float4 _ST_WindTurbulences;
  17. float4 _ST_WindLeaf1Ripple;
  18. float4 _ST_WindLeaf1Tumble;
  19. float4 _ST_WindLeaf1Twitch;
  20. float4 _ST_WindLeaf2Ripple;
  21. float4 _ST_WindLeaf2Tumble;
  22. float4 _ST_WindLeaf2Twitch;
  23. float4 _ST_WindFrondRipple;
  24. float4 _ST_WindAnimation;
  25. CBUFFER_END
  26. CBUFFER_START(SpeedTreeWindHistory)
  27. float4 _ST_WindVectorHistory;
  28. float4 _ST_WindGlobalHistory;
  29. float4 _ST_WindBranchHistory;
  30. float4 _ST_WindBranchTwitchHistory;
  31. float4 _ST_WindBranchWhipHistory;
  32. float4 _ST_WindBranchAnchorHistory;
  33. float4 _ST_WindBranchAdherencesHistory;
  34. float4 _ST_WindTurbulencesHistory;
  35. float4 _ST_WindLeaf1RippleHistory;
  36. float4 _ST_WindLeaf1TumbleHistory;
  37. float4 _ST_WindLeaf1TwitchHistory;
  38. float4 _ST_WindLeaf2RippleHistory;
  39. float4 _ST_WindLeaf2TumbleHistory;
  40. float4 _ST_WindLeaf2TwitchHistory;
  41. float4 _ST_WindFrondRippleHistory;
  42. float4 _ST_WindAnimationHistory;
  43. CBUFFER_END
  44. #ifdef UNITY_DOTS_INSTANCING_ENABLED
  45. #define DOTS_ST_WindVector DOTS_ST_WindParam0
  46. #define DOTS_ST_WindGlobal DOTS_ST_WindParam1
  47. #define DOTS_ST_WindBranch DOTS_ST_WindParam2
  48. #define DOTS_ST_WindBranchTwitch DOTS_ST_WindParam3
  49. #define DOTS_ST_WindBranchWhip DOTS_ST_WindParam4
  50. #define DOTS_ST_WindBranchAnchor DOTS_ST_WindParam5
  51. #define DOTS_ST_WindBranchAdherences DOTS_ST_WindParam6
  52. #define DOTS_ST_WindTurbulences DOTS_ST_WindParam7
  53. #define DOTS_ST_WindLeaf1Ripple DOTS_ST_WindParam8
  54. #define DOTS_ST_WindLeaf1Tumble DOTS_ST_WindParam9
  55. #define DOTS_ST_WindLeaf1Twitch DOTS_ST_WindParam10
  56. #define DOTS_ST_WindLeaf2Ripple DOTS_ST_WindParam11
  57. #define DOTS_ST_WindLeaf2Tumble DOTS_ST_WindParam12
  58. #define DOTS_ST_WindLeaf2Twitch DOTS_ST_WindParam13
  59. #define DOTS_ST_WindFrondRipple DOTS_ST_WindParam14
  60. #define DOTS_ST_WindAnimation DOTS_ST_WindParam15
  61. #define DOTS_ST_WindVectorHistory DOTS_ST_WindHistoryParam0
  62. #define DOTS_ST_WindGlobalHistory DOTS_ST_WindHistoryParam1
  63. #define DOTS_ST_WindBranchHistory DOTS_ST_WindHistoryParam2
  64. #define DOTS_ST_WindBranchTwitchHistory DOTS_ST_WindHistoryParam3
  65. #define DOTS_ST_WindBranchWhipHistory DOTS_ST_WindHistoryParam4
  66. #define DOTS_ST_WindBranchAnchorHistory DOTS_ST_WindHistoryParam5
  67. #define DOTS_ST_WindBranchAdherencesHistory DOTS_ST_WindHistoryParam6
  68. #define DOTS_ST_WindTurbulencesHistory DOTS_ST_WindHistoryParam7
  69. #define DOTS_ST_WindLeaf1RippleHistory DOTS_ST_WindHistoryParam8
  70. #define DOTS_ST_WindLeaf1TumbleHistory DOTS_ST_WindHistoryParam9
  71. #define DOTS_ST_WindLeaf1TwitchHistory DOTS_ST_WindHistoryParam10
  72. #define DOTS_ST_WindLeaf2RippleHistory DOTS_ST_WindHistoryParam11
  73. #define DOTS_ST_WindLeaf2TumbleHistory DOTS_ST_WindHistoryParam12
  74. #define DOTS_ST_WindLeaf2TwitchHistory DOTS_ST_WindHistoryParam13
  75. #define DOTS_ST_WindFrondRippleHistory DOTS_ST_WindHistoryParam14
  76. #define DOTS_ST_WindAnimationHistory DOTS_ST_WindHistoryParam15
  77. UNITY_DOTS_INSTANCING_START(UserPropertyMetadata)
  78. UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindVector)
  79. UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindGlobal)
  80. UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindBranch)
  81. UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindBranchTwitch)
  82. UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindBranchWhip)
  83. UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindBranchAnchor)
  84. UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindBranchAdherences)
  85. UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindTurbulences)
  86. UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindLeaf1Ripple)
  87. UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindLeaf1Tumble)
  88. UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindLeaf1Twitch)
  89. UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindLeaf2Ripple)
  90. UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindLeaf2Tumble)
  91. UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindLeaf2Twitch)
  92. UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindFrondRipple)
  93. UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindAnimation)
  94. UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindVectorHistory)
  95. UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindGlobalHistory)
  96. UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindBranchHistory)
  97. UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindBranchTwitchHistory)
  98. UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindBranchWhipHistory)
  99. UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindBranchAnchorHistory)
  100. UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindBranchAdherencesHistory)
  101. UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindTurbulencesHistory)
  102. UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindLeaf1RippleHistory)
  103. UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindLeaf1TumbleHistory)
  104. UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindLeaf1TwitchHistory)
  105. UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindLeaf2RippleHistory)
  106. UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindLeaf2TumbleHistory)
  107. UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindLeaf2TwitchHistory)
  108. UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindFrondRippleHistory)
  109. UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindAnimationHistory)
  110. UNITY_DOTS_INSTANCING_END(UserPropertyMetadata)
  111. #define _ST_WindVector UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindVector)
  112. #define _ST_WindGlobal UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindGlobal)
  113. #define _ST_WindBranch UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindBranch)
  114. #define _ST_WindBranchTwitch UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindBranchTwitch)
  115. #define _ST_WindBranchWhip UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindBranchWhip)
  116. #define _ST_WindBranchAnchor UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindBranchAnchor)
  117. #define _ST_WindBranchAdherences UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindBranchAdherences)
  118. #define _ST_WindTurbulences UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindTurbulences)
  119. #define _ST_WindLeaf1Ripple UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindLeaf1Ripple)
  120. #define _ST_WindLeaf1Tumble UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindLeaf1Tumble)
  121. #define _ST_WindLeaf1Twitch UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindLeaf1Twitch)
  122. #define _ST_WindLeaf2Ripple UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindLeaf2Ripple)
  123. #define _ST_WindLeaf2Tumble UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindLeaf2Tumble)
  124. #define _ST_WindLeaf2Twitch UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindLeaf2Twitch)
  125. #define _ST_WindFrondRipple UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindFrondRipple)
  126. #define _ST_WindAnimation UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindAnimation)
  127. #define _ST_WindVectorHistory UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindVectorHistory)
  128. #define _ST_WindGlobalHistory UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindGlobalHistory)
  129. #define _ST_WindBranchHistory UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindBranchHistory)
  130. #define _ST_WindBranchTwitchHistory UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindBranchTwitchHistory)
  131. #define _ST_WindBranchWhipHistory UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindBranchWhipHistory)
  132. #define _ST_WindBranchAnchorHistory UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindBranchAnchorHistory)
  133. #define _ST_WindBranchAdherencesHistory UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindBranchAdherencesHistory)
  134. #define _ST_WindTurbulencesHistory UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindTurbulencesHistory)
  135. #define _ST_WindLeaf1RippleHistory UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindLeaf1RippleHistory)
  136. #define _ST_WindLeaf1TumbleHistory UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindLeaf1TumbleHistory)
  137. #define _ST_WindLeaf1TwitchHistory UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindLeaf1TwitchHistory)
  138. #define _ST_WindLeaf2RippleHistory UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindLeaf2RippleHistory)
  139. #define _ST_WindLeaf2TumbleHistory UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindLeaf2TumbleHistory)
  140. #define _ST_WindLeaf2TwitchHistory UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindLeaf2TwitchHistory)
  141. #define _ST_WindFrondRippleHistory UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindFrondRippleHistory)
  142. #define _ST_WindAnimationHistory UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindAnimationHistory)
  143. #endif
  144. #define ST_WIND_QUALITY_NONE 0
  145. #define ST_WIND_QUALITY_FASTEST 1
  146. #define ST_WIND_QUALITY_FAST 2
  147. #define ST_WIND_QUALITY_BETTER 3
  148. #define ST_WIND_QUALITY_BEST 4
  149. #define ST_WIND_QUALITY_PALM 5
  150. ///////////////////////////////////////////////////////////////////////
  151. // Get_Wind*() functions
  152. float4 Get_WindVector(bool bHistory) { return bHistory ? _ST_WindVectorHistory : _ST_WindVector; }
  153. float4 Get_WindGlobal(bool bHistory) { return bHistory ? _ST_WindGlobalHistory : _ST_WindGlobal; }
  154. float4 Get_WindBranch(bool bHistory) { return bHistory ? _ST_WindBranchHistory : _ST_WindBranch; }
  155. float4 Get_WindBranchTwitch(bool bHistory) { return bHistory ? _ST_WindBranchTwitchHistory : _ST_WindBranchTwitch; }
  156. float4 Get_WindBranchWhip(bool bHistory) { return bHistory ? _ST_WindBranchWhipHistory : _ST_WindBranchWhip; }
  157. float4 Get_WindBranchAnchor(bool bHistory) { return bHistory ? _ST_WindBranchAnchorHistory : _ST_WindBranchAnchor; }
  158. float4 Get_WindBranchAdherences(bool bHistory) { return bHistory ? _ST_WindBranchAdherencesHistory : _ST_WindBranchAdherences; }
  159. float4 Get_WindTurbulences(bool bHistory) { return bHistory ? _ST_WindTurbulencesHistory : _ST_WindTurbulences; }
  160. float4 Get_WindLeaf1Ripple(bool bHistory) { return bHistory ? _ST_WindLeaf1RippleHistory : _ST_WindLeaf1Ripple; }
  161. float4 Get_WindLeaf1Tumble(bool bHistory) { return bHistory ? _ST_WindLeaf1TumbleHistory : _ST_WindLeaf1Tumble; }
  162. float4 Get_WindLeaf1Twitch(bool bHistory) { return bHistory ? _ST_WindLeaf1TwitchHistory : _ST_WindLeaf1Twitch; }
  163. float4 Get_WindLeaf2Ripple(bool bHistory) { return bHistory ? _ST_WindLeaf2RippleHistory : _ST_WindLeaf2Ripple; }
  164. float4 Get_WindLeaf2Tumble(bool bHistory) { return bHistory ? _ST_WindLeaf2TumbleHistory : _ST_WindLeaf2Tumble; }
  165. float4 Get_WindLeaf2Twitch(bool bHistory) { return bHistory ? _ST_WindLeaf2TwitchHistory : _ST_WindLeaf2Twitch; }
  166. float4 Get_WindFrondRipple(bool bHistory) { return bHistory ? _ST_WindFrondRippleHistory : _ST_WindFrondRipple; }
  167. float4 Get_WindAnimation(bool bHistory) { return bHistory ? _ST_WindAnimationHistory : _ST_WindAnimation; }
  168. ///////////////////////////////////////////////////////////////////////
  169. // UnpackNormalFromFloat
  170. float3 UnpackNormalFromFloat(float fValue)
  171. {
  172. float3 vDecodeKey = float3(16.0, 1.0, 0.0625);
  173. // decode into [0,1] range
  174. float3 vDecodedValue = frac(fValue / vDecodeKey);
  175. // move back into [-1,1] range & normalize
  176. return (vDecodedValue * 2.0 - 1.0);
  177. }
  178. ///////////////////////////////////////////////////////////////////////
  179. // CubicSmooth
  180. float4 CubicSmooth(float4 vData)
  181. {
  182. return vData * vData * (3.0 - 2.0 * vData);
  183. }
  184. ///////////////////////////////////////////////////////////////////////
  185. // TriangleWave
  186. float4 TriangleWave(float4 vData)
  187. {
  188. return abs((frac(vData + 0.5) * 2.0) - 1.0);
  189. }
  190. ///////////////////////////////////////////////////////////////////////
  191. // TrigApproximate
  192. float4 TrigApproximate(float4 vData)
  193. {
  194. return (CubicSmooth(TriangleWave(vData)) - 0.5) * 2.0;
  195. }
  196. ///////////////////////////////////////////////////////////////////////
  197. // RotationMatrix
  198. //
  199. // Constructs an arbitrary axis rotation matrix
  200. float3x3 RotationMatrix(float3 vAxis, float fAngle)
  201. {
  202. // compute sin/cos of fAngle
  203. float2 vSinCos;
  204. #ifdef OPENGL
  205. vSinCos.x = sin(fAngle);
  206. vSinCos.y = cos(fAngle);
  207. #else
  208. sincos(fAngle, vSinCos.x, vSinCos.y);
  209. #endif
  210. const float c = vSinCos.y;
  211. const float s = vSinCos.x;
  212. const float t = 1.0 - c;
  213. const float x = vAxis.x;
  214. const float y = vAxis.y;
  215. const float z = vAxis.z;
  216. return float3x3(t * x * x + c, t * x * y - s * z, t * x * z + s * y,
  217. t * x * y + s * z, t * y * y + c, t * y * z - s * x,
  218. t * x * z - s * y, t * y * z + s * x, t * z * z + c);
  219. }
  220. ///////////////////////////////////////////////////////////////////////
  221. // mul_float3x3_float3x3
  222. float3x3 mul_float3x3_float3x3(float3x3 mMatrixA, float3x3 mMatrixB)
  223. {
  224. return mul(mMatrixA, mMatrixB);
  225. }
  226. ///////////////////////////////////////////////////////////////////////
  227. // mul_float3x3_float3
  228. float3 mul_float3x3_float3(float3x3 mMatrix, float3 vVector)
  229. {
  230. return mul(mMatrix, vVector);
  231. }
  232. ///////////////////////////////////////////////////////////////////////
  233. // cross()'s parameters are backwards in GLSL
  234. #define wind_cross(a, b) cross((a), (b))
  235. ///////////////////////////////////////////////////////////////////////
  236. // Roll
  237. float Roll(float fCurrent,
  238. float fMaxScale,
  239. float fMinScale,
  240. float fSpeed,
  241. float fRipple,
  242. float3 vPos,
  243. float fTime,
  244. float3 vRotatedWindVector)
  245. {
  246. float fWindAngle = dot(vPos, -vRotatedWindVector) * fRipple;
  247. float fAdjust = TrigApproximate(float4(fWindAngle + fTime * fSpeed, 0.0, 0.0, 0.0)).x;
  248. fAdjust = (fAdjust + 1.0) * 0.5;
  249. return lerp(fCurrent * fMinScale, fCurrent * fMaxScale, fAdjust);
  250. }
  251. ///////////////////////////////////////////////////////////////////////
  252. // Twitch
  253. float Twitch(float3 vPos, float fAmount, float fSharpness, float fTime)
  254. {
  255. const float c_fTwitchFudge = 0.87;
  256. float4 vOscillations = TrigApproximate(float4(fTime + (vPos.x + vPos.z), c_fTwitchFudge * fTime + vPos.y, 0.0, 0.0));
  257. //float fTwitch = sin(fFreq1 * fTime + (vPos.x + vPos.z)) * cos(fFreq2 * fTime + vPos.y);
  258. float fTwitch = vOscillations.x * vOscillations.y * vOscillations.y;
  259. fTwitch = (fTwitch + 1.0) * 0.5;
  260. return fAmount * pow(saturate(fTwitch), fSharpness);
  261. }
  262. ///////////////////////////////////////////////////////////////////////
  263. // Oscillate
  264. //
  265. // This function computes an oscillation value and whip value if necessary.
  266. // Whip and oscillation are combined like this to minimize calls to
  267. // TrigApproximate( ) when possible.
  268. float Oscillate(float3 vPos,
  269. float fTime,
  270. float fOffset,
  271. float fWeight,
  272. float fWhip,
  273. bool bWhip,
  274. bool bRoll,
  275. bool bComplex,
  276. float fTwitch,
  277. float fTwitchFreqScale,
  278. inout float4 vOscillations,
  279. float3 vRotatedWindVector,
  280. bool bHistory)
  281. {
  282. float fOscillation = 1.0;
  283. if (bComplex)
  284. {
  285. if (bWhip)
  286. vOscillations = TrigApproximate(float4(fTime + fOffset, fTime * fTwitchFreqScale + fOffset, fTwitchFreqScale * 0.5 * (fTime + fOffset), fTime + fOffset + (1.0 - fWeight)));
  287. else
  288. vOscillations = TrigApproximate(float4(fTime + fOffset, fTime * fTwitchFreqScale + fOffset, fTwitchFreqScale * 0.5 * (fTime + fOffset), 0.0));
  289. float fFineDetail = vOscillations.x;
  290. float fBroadDetail = vOscillations.y * vOscillations.z;
  291. float fTarget = 1.0;
  292. float fAmount = fBroadDetail;
  293. if (fBroadDetail < 0.0)
  294. {
  295. fTarget = -fTarget;
  296. fAmount = -fAmount;
  297. }
  298. fBroadDetail = lerp(fBroadDetail, fTarget, fAmount);
  299. fBroadDetail = lerp(fBroadDetail, fTarget, fAmount);
  300. fOscillation = fBroadDetail * fTwitch * (1.0 - Get_WindVector(bHistory).w) + fFineDetail * (1.0 - fTwitch);
  301. if (bWhip)
  302. fOscillation *= 1.0 + (vOscillations.w * fWhip);
  303. }
  304. else
  305. {
  306. if (bWhip)
  307. vOscillations = TrigApproximate(float4(fTime + fOffset, fTime * 0.689 + fOffset, 0.0, fTime + fOffset + (1.0 - fWeight)));
  308. else
  309. vOscillations = TrigApproximate(float4(fTime + fOffset, fTime * 0.689 + fOffset, 0.0, 0.0));
  310. fOscillation = vOscillations.x + vOscillations.y * vOscillations.x;
  311. if (bWhip)
  312. fOscillation *= 1.0 + (vOscillations.w * fWhip);
  313. }
  314. //if (bRoll)
  315. //{
  316. // fOscillation = Roll(fOscillation, _ST_WindRollingBranches.x, _ST_WindRollingBranches.y, _ST_WindRollingBranches.z, _ST_WindRollingBranches.w, vPos.xyz, fTime + fOffset, vRotatedWindVector);
  317. //}
  318. return fOscillation;
  319. }
  320. ///////////////////////////////////////////////////////////////////////
  321. // Turbulence
  322. float Turbulence(float fTime, float fOffset, float fGlobalTime, float fTurbulence)
  323. {
  324. const float c_fTurbulenceFactor = 0.1;
  325. float4 vOscillations = TrigApproximate(float4(fTime * c_fTurbulenceFactor + fOffset, fGlobalTime * fTurbulence * c_fTurbulenceFactor + fOffset, 0.0, 0.0));
  326. return 1.0 - (vOscillations.x * vOscillations.y * vOscillations.x * vOscillations.y * fTurbulence);
  327. }
  328. ///////////////////////////////////////////////////////////////////////
  329. // GlobalWind
  330. //
  331. // This function positions any tree geometry based on their untransformed
  332. // position and 4 wind floats.
  333. float3 GlobalWind(float3 vPos, float3 vInstancePos, bool bPreserveShape, float3 vRotatedWindVector, float time, bool bHistory)
  334. {
  335. // WIND_LOD_GLOBAL may be on, but if the global wind effect (WIND_EFFECT_GLOBAL_ST_Wind)
  336. // was disabled for the tree in the Modeler, we should skip it
  337. const float4 windGlobal = Get_WindGlobal(bHistory);
  338. const float4 windBranchAdherences = Get_WindBranchAdherences(bHistory);
  339. float fLength = 1.0;
  340. if (bPreserveShape)
  341. fLength = length(vPos.xyz);
  342. // compute how much the height contributes
  343. #ifdef SPEEDTREE_Z_UP
  344. float fAdjust = max(vPos.z - (1.0 / windGlobal.z) * 0.25, 0.0) * windGlobal.z;
  345. #else
  346. float fAdjust = max(vPos.y - (1.0 / windGlobal.z) * 0.25, 0.0) * windGlobal.z;
  347. #endif
  348. if (fAdjust != 0.0)
  349. fAdjust = pow(abs(fAdjust), windGlobal.w);
  350. // primary oscillation
  351. float4 vOscillations = TrigApproximate(float4(vInstancePos.x + time, vInstancePos.y + time * 0.8, 0.0, 0.0));
  352. float fOsc = vOscillations.x + (vOscillations.y * vOscillations.y);
  353. float fMoveAmount = windGlobal.y * fOsc;
  354. // move a minimum amount based on direction adherence
  355. fMoveAmount += windBranchAdherences.x / windGlobal.z;
  356. // adjust based on how high up the tree this vertex is
  357. fMoveAmount *= fAdjust;
  358. // xy component
  359. #ifdef SPEEDTREE_Z_UP
  360. vPos.xy += vRotatedWindVector.xy * fMoveAmount;
  361. #else
  362. vPos.xz += vRotatedWindVector.xz * fMoveAmount;
  363. #endif
  364. if (bPreserveShape)
  365. vPos.xyz = normalize(vPos.xyz) * fLength;
  366. return vPos;
  367. }
  368. ///////////////////////////////////////////////////////////////////////
  369. // SimpleBranchWind
  370. float3 SimpleBranchWind(float3 vPos,
  371. float3 vInstancePos,
  372. float fWeight,
  373. float fOffset,
  374. float fTime,
  375. float fDistance,
  376. float fTwitch,
  377. float fTwitchScale,
  378. float fWhip,
  379. bool bWhip,
  380. bool bRoll,
  381. bool bComplex,
  382. float3 vRotatedWindVector,
  383. bool bHistory)
  384. {
  385. // turn the offset back into a nearly normalized vector
  386. float3 vWindVector = UnpackNormalFromFloat(fOffset);
  387. vWindVector = vWindVector * fWeight;
  388. // try to fudge time a bit so that instances aren't in sync
  389. fTime += vInstancePos.x + vInstancePos.y;
  390. // oscillate
  391. float4 vOscillations;
  392. float fOsc = Oscillate(vPos, fTime, fOffset, fWeight, fWhip, bWhip, bRoll, bComplex, fTwitch, fTwitchScale, vOscillations, vRotatedWindVector, bHistory);
  393. vPos.xyz += vWindVector * fOsc * fDistance;
  394. return vPos;
  395. }
  396. ///////////////////////////////////////////////////////////////////////
  397. // DirectionalBranchWind
  398. float3 DirectionalBranchWind(float3 vPos,
  399. float3 vInstancePos,
  400. float fWeight,
  401. float fOffset,
  402. float fTime,
  403. float fDistance,
  404. float fTurbulence,
  405. float fAdherence,
  406. float fTwitch,
  407. float fTwitchScale,
  408. float fWhip,
  409. bool bWhip,
  410. bool bRoll,
  411. bool bComplex,
  412. bool bTurbulence,
  413. float3 vRotatedWindVector,
  414. bool bHistory)
  415. {
  416. // turn the offset back into a nearly normalized vector
  417. float3 vWindVector = UnpackNormalFromFloat(fOffset);
  418. vWindVector = vWindVector * fWeight;
  419. // try to fudge time a bit so that instances aren't in sync
  420. fTime += vInstancePos.x + vInstancePos.y;
  421. // oscillate
  422. float4 vOscillations;
  423. float fOsc = Oscillate(vPos, fTime, fOffset, fWeight, fWhip, bWhip, false, bComplex, fTwitch, fTwitchScale, vOscillations, vRotatedWindVector, bHistory);
  424. vPos.xyz += vWindVector * fOsc * fDistance;
  425. // add in the direction, accounting for turbulence
  426. float fAdherenceScale = 1.0;
  427. if (bTurbulence)
  428. fAdherenceScale = Turbulence(fTime, fOffset, Get_WindAnimation(bHistory).x, fTurbulence);
  429. if (bWhip)
  430. fAdherenceScale += vOscillations.w * Get_WindVector(bHistory).w * fWhip;
  431. //if (bRoll)
  432. // fAdherenceScale = Roll(fAdherenceScale, _ST_WindRollingBranches.x, _ST_WindRollingBranches.y, _ST_WindRollingBranches.z, _ST_WindRollingBranches.w, vPos.xyz, fTime + fOffset, vRotatedWindVector);
  433. vPos.xyz += vRotatedWindVector * fAdherence * fAdherenceScale * fWeight;
  434. return vPos;
  435. }
  436. ///////////////////////////////////////////////////////////////////////
  437. // DirectionalBranchWindFrondStyle
  438. float3 DirectionalBranchWindFrondStyle(float3 vPos,
  439. float3 vInstancePos,
  440. float fWeight,
  441. float fOffset,
  442. float fTime,
  443. float fDistance,
  444. float fTurbulence,
  445. float fAdherence,
  446. float fTwitch,
  447. float fTwitchScale,
  448. float fWhip,
  449. bool bWhip,
  450. bool bRoll,
  451. bool bComplex,
  452. bool bTurbulence,
  453. float3 vRotatedWindVector,
  454. float3 vRotatedBranchAnchor,
  455. bool bHistory)
  456. {
  457. // turn the offset back into a nearly normalized vector
  458. float3 vWindVector = UnpackNormalFromFloat(fOffset);
  459. vWindVector = vWindVector * fWeight;
  460. // try to fudge time a bit so that instances aren't in sync
  461. fTime += vInstancePos.x + vInstancePos.y;
  462. // oscillate
  463. float4 vOscillations;
  464. float fOsc = Oscillate(vPos, fTime, fOffset, fWeight, fWhip, bWhip, false, bComplex, fTwitch, fTwitchScale, vOscillations, vRotatedWindVector, bHistory);
  465. vPos.xyz += vWindVector * fOsc * fDistance;
  466. // add in the direction, accounting for turbulence
  467. float fAdherenceScale = 1.0;
  468. if (bTurbulence)
  469. fAdherenceScale = Turbulence(fTime, fOffset, Get_WindAnimation(bHistory).x, fTurbulence);
  470. //if (bRoll)
  471. // fAdherenceScale = Roll(fAdherenceScale, _ST_WindRollingBranches.x, _ST_WindRollingBranches.y, _ST_WindRollingBranches.z, _ST_WindRollingBranches.w, vPos.xyz, fTime + fOffset, vRotatedWindVector);
  472. if (bWhip)
  473. fAdherenceScale += vOscillations.w * Get_WindVector(bHistory).w * fWhip;
  474. float3 vWindAdherenceVector = vRotatedBranchAnchor - vPos.xyz;
  475. vPos.xyz += vWindAdherenceVector * fAdherence * fAdherenceScale * fWeight;
  476. return vPos;
  477. }
  478. ///////////////////////////////////////////////////////////////////////
  479. // BranchWind
  480. // Apply only to better, best, palm winds
  481. float3 BranchWind(bool isPalmWind, float3 vPos, float3 vInstancePos, float4 vWindData, float3 vRotatedWindVector, float3 vRotatedBranchAnchor, bool bHistory)
  482. {
  483. const float4 windBranch = Get_WindBranch(bHistory);
  484. const float4 windBranchTwitch = Get_WindBranchTwitch(bHistory);
  485. const float4 windBranchAdherences = Get_WindBranchAdherences(bHistory);
  486. const float4 windBarnchWhip = Get_WindBranchWhip(bHistory);
  487. const float4 windTurbulences = Get_WindTurbulences(bHistory);
  488. const bool bWhip = isPalmWind;
  489. const bool bRoll = false;
  490. const bool bComplex = true;
  491. if (isPalmWind)
  492. {
  493. const bool bTurbulence = true;
  494. vPos = DirectionalBranchWindFrondStyle(
  495. vPos,
  496. vInstancePos,
  497. vWindData.x, vWindData.y,
  498. windBranch.x, windBranch.y,
  499. windTurbulences.x, windBranchAdherences.y,
  500. windBranchTwitch.x, windBranchTwitch.y,
  501. windBarnchWhip.x,
  502. bWhip,
  503. bRoll,
  504. bComplex,
  505. bTurbulence,
  506. vRotatedWindVector,
  507. vRotatedBranchAnchor,
  508. bHistory
  509. );
  510. }
  511. else
  512. {
  513. vPos = SimpleBranchWind(
  514. vPos,
  515. vInstancePos,
  516. vWindData.x, vWindData.y,
  517. windBranch.x, windBranch.y,
  518. windBranchTwitch.x, windBranchTwitch.y,
  519. windBarnchWhip.x,
  520. bWhip,
  521. bRoll,
  522. bComplex,
  523. vRotatedWindVector,
  524. bHistory
  525. );
  526. }
  527. return vPos;
  528. }
  529. ///////////////////////////////////////////////////////////////////////
  530. // LeafRipple
  531. float3 LeafRipple(float3 vPos,
  532. inout float3 vDirection,
  533. float fScale,
  534. float fPackedRippleDir,
  535. float fTime,
  536. float fAmount,
  537. bool bDirectional,
  538. float fTrigOffset)
  539. {
  540. // compute how much to move
  541. float4 vInput = float4(fTime + fTrigOffset, 0.0, 0.0, 0.0);
  542. float fMoveAmount = fAmount * TrigApproximate(vInput).x;
  543. if (bDirectional)
  544. {
  545. vPos.xyz += vDirection.xyz * fMoveAmount * fScale;
  546. }
  547. else
  548. {
  549. float3 vRippleDir = UnpackNormalFromFloat(fPackedRippleDir);
  550. vPos.xyz += vRippleDir * fMoveAmount * fScale;
  551. }
  552. return vPos;
  553. }
  554. ///////////////////////////////////////////////////////////////////////
  555. // LeafTumble
  556. float3 LeafTumble(float3 vPos,
  557. inout float3 vDirection,
  558. float fScale,
  559. float3 vAnchor,
  560. float3 vGrowthDir,
  561. float fTrigOffset,
  562. float fTime,
  563. float fFlip,
  564. float fTwist,
  565. float fAdherence,
  566. float3 vTwitch,
  567. float4 vRoll,
  568. bool bTwitch,
  569. bool bRoll,
  570. float3 vRotatedWindVector)
  571. {
  572. // compute all oscillations up front
  573. float3 vFracs = frac((vAnchor + fTrigOffset) * 30.3);
  574. float fOffset = vFracs.x + vFracs.y + vFracs.z;
  575. float4 vOscillations = TrigApproximate(float4(fTime + fOffset, fTime * 0.75 - fOffset, fTime * 0.01 + fOffset, fTime * 1.0 + fOffset));
  576. // move to the origin and get the growth direction
  577. float3 vOriginPos = vPos.xyz - vAnchor;
  578. float fLength = length(vOriginPos);
  579. // twist
  580. float fOsc = vOscillations.x + vOscillations.y * vOscillations.y;
  581. float3x3 matTumble = RotationMatrix(vGrowthDir, fScale * fTwist * fOsc);
  582. // with wind
  583. float3 vAxis = wind_cross(vGrowthDir.xyz, vRotatedWindVector.xyz);
  584. float fDot = clamp(dot(vRotatedWindVector, vGrowthDir), -1.0, 1.0);
  585. #ifdef SPEEDTREE_Z_UP
  586. vAxis.z += fDot;
  587. #else
  588. vAxis.y += fDot;
  589. #endif
  590. vAxis = normalize(vAxis);
  591. float fAngle = acos(fDot);
  592. float fAdherenceScale = 1.0;
  593. //if (bRoll)
  594. //{
  595. // fAdherenceScale = Roll(fAdherenceScale, vRoll.x, vRoll.y, vRoll.z, vRoll.w, vAnchor.xyz, fTime, vRotatedWindVector);
  596. //}
  597. fOsc = vOscillations.y - vOscillations.x * vOscillations.x;
  598. float fTwitch = 0.0;
  599. if (bTwitch)
  600. fTwitch = Twitch(vAnchor.xyz, vTwitch.x, vTwitch.y, vTwitch.z + fOffset);
  601. matTumble = mul_float3x3_float3x3(matTumble, RotationMatrix(vAxis, fScale * (fAngle * fAdherence * fAdherenceScale + fOsc * fFlip + fTwitch)));
  602. vDirection = mul_float3x3_float3(matTumble, vDirection);
  603. vOriginPos = mul_float3x3_float3(matTumble, vOriginPos);
  604. vOriginPos = normalize(vOriginPos) * fLength;
  605. return (vOriginPos + vAnchor);
  606. }
  607. ///////////////////////////////////////////////////////////////////////
  608. // LeafWind
  609. // Optimized (for instruction count) version. Assumes leaf 1 and 2 have the same options
  610. float3 LeafWind(bool isBestWind,
  611. bool bLeaf2,
  612. float3 vPos,
  613. inout float3 vDirection,
  614. float fScale,
  615. float3 vAnchor,
  616. float fPackedGrowthDir,
  617. float fPackedRippleDir,
  618. float fRippleTrigOffset,
  619. float3 vRotatedWindVector,
  620. bool bHistory)
  621. {
  622. const float4 windLeaf2Ripple = Get_WindLeaf2Ripple(bHistory);
  623. const float4 windLeaf1Ripple = Get_WindLeaf1Ripple(bHistory);
  624. const float4 windLeaf1Tumble = Get_WindLeaf1Tumble(bHistory);
  625. const float4 windLeaf2Tumble = Get_WindLeaf2Tumble(bHistory);
  626. const float4 windLeaf1Twitch = Get_WindLeaf2Twitch(bHistory);
  627. const float4 windLeaf2Twitch = Get_WindLeaf2Twitch(bHistory);
  628. vPos = LeafRipple(vPos, vDirection, fScale, fPackedRippleDir,
  629. (bLeaf2 ? windLeaf2Ripple.x : windLeaf1Ripple.x),
  630. (bLeaf2 ? windLeaf2Ripple.y : windLeaf1Ripple.y),
  631. false, fRippleTrigOffset);
  632. if (isBestWind)
  633. {
  634. float3 vGrowthDir = UnpackNormalFromFloat(fPackedGrowthDir);
  635. vPos = LeafTumble(vPos, vDirection, fScale, vAnchor, vGrowthDir, fPackedGrowthDir,
  636. (bLeaf2 ? windLeaf2Tumble.x : windLeaf1Tumble.x),
  637. (bLeaf2 ? windLeaf2Tumble.y : windLeaf1Tumble.y),
  638. (bLeaf2 ? windLeaf2Tumble.z : windLeaf1Tumble.z),
  639. (bLeaf2 ? windLeaf2Tumble.w : windLeaf1Tumble.w),
  640. (bLeaf2 ? windLeaf2Twitch.xyz : windLeaf1Twitch.xyz),
  641. 0.0f,
  642. true,
  643. true,
  644. vRotatedWindVector);
  645. }
  646. return vPos;
  647. }
  648. ///////////////////////////////////////////////////////////////////////
  649. // RippleFrondOneSided
  650. float3 RippleFrondOneSided(float3 vPos,
  651. inout float3 vDirection,
  652. float fU,
  653. float fV,
  654. float fRippleScale,
  655. bool bHistory
  656. #ifdef WIND_EFFECT_FROND_RIPPLE_ADJUST_LIGHTING
  657. , float3 vBinormal
  658. , float3 vTangent
  659. #endif
  660. )
  661. {
  662. float fOffset = 0.0;
  663. if (fU < 0.5)
  664. fOffset = 0.75;
  665. const float4 windFrondRipple = Get_WindFrondRipple(bHistory);
  666. float4 vOscillations = TrigApproximate(float4((windFrondRipple.x + fV) * windFrondRipple.z + fOffset, 0.0, 0.0, 0.0));
  667. float fAmount = fRippleScale * vOscillations.x * windFrondRipple.y;
  668. float3 vOffset = fAmount * vDirection;
  669. vPos.xyz += vOffset;
  670. #ifdef WIND_EFFECT_FROND_RIPPLE_ADJUST_LIGHTING
  671. vTangent.xyz = normalize(vTangent.xyz + vOffset * windFrondRipple.w);
  672. float3 vNewNormal = normalize(wind_cross(vBinormal.xyz, vTangent.xyz));
  673. if (dot(vNewNormal, vDirection.xyz) < 0.0)
  674. vNewNormal = -vNewNormal;
  675. vDirection.xyz = vNewNormal;
  676. #endif
  677. return vPos;
  678. }
  679. ///////////////////////////////////////////////////////////////////////
  680. // RippleFrondTwoSided
  681. float3 RippleFrondTwoSided(float3 vPos,
  682. inout float3 vDirection,
  683. float fU,
  684. float fLengthPercent,
  685. float fPackedRippleDir,
  686. float fRippleScale,
  687. bool bHistory
  688. #ifdef WIND_EFFECT_FROND_RIPPLE_ADJUST_LIGHTING
  689. , float3 vBinormal
  690. , float3 vTangent
  691. #endif
  692. )
  693. {
  694. const float4 windFrondRipple = Get_WindFrondRipple(bHistory);
  695. float4 vOscillations = TrigApproximate(float4(windFrondRipple.x * fLengthPercent * windFrondRipple.z, 0.0, 0.0, 0.0));
  696. float3 vRippleDir = UnpackNormalFromFloat(fPackedRippleDir);
  697. float fAmount = fRippleScale * vOscillations.x * windFrondRipple.y;
  698. float3 vOffset = fAmount * vRippleDir;
  699. vPos.xyz += vOffset;
  700. #ifdef WIND_EFFECT_FROND_RIPPLE_ADJUST_LIGHTING
  701. vTangent.xyz = normalize(vTangent.xyz + vOffset * windFrondRipple.w);
  702. float3 vNewNormal = normalize(wind_cross(vBinormal.xyz, vTangent.xyz));
  703. if (dot(vNewNormal, vDirection.xyz) < 0.0)
  704. vNewNormal = -vNewNormal;
  705. vDirection.xyz = vNewNormal;
  706. #endif
  707. return vPos;
  708. }
  709. ///////////////////////////////////////////////////////////////////////
  710. // RippleFrond
  711. float3 RippleFrond(float3 vPos,
  712. inout float3 vDirection,
  713. float fU,
  714. float fV,
  715. float fPackedRippleDir,
  716. float fRippleScale,
  717. float fLenghtPercent,
  718. bool bHistory
  719. #ifdef WIND_EFFECT_FROND_RIPPLE_ADJUST_LIGHTING
  720. , float3 vBinormal
  721. , float3 vTangent
  722. #endif
  723. )
  724. {
  725. return RippleFrondOneSided(vPos,
  726. vDirection,
  727. fU,
  728. fV,
  729. fRippleScale,
  730. bHistory
  731. #ifdef WIND_EFFECT_FROND_RIPPLE_ADJUST_LIGHTING
  732. , vBinormal
  733. , vTangent
  734. #endif
  735. );
  736. }
  737. ///////////////////////////////////////////////////////////////////////
  738. // SpeedTreeWind
  739. float3 SpeedTreeWind(
  740. float3 vPos,
  741. float3 vNormal,
  742. float4 vTexcoord0,
  743. float4 vTexcoord1,
  744. float4 vTexcoord2,
  745. float4 vTexcoord3,
  746. int iWindQuality,
  747. bool bBillboard,
  748. bool bHistory
  749. )
  750. {
  751. float3 vReturnPos = vPos;
  752. // check wind enabled & data available
  753. float3 windVector = Get_WindVector(bHistory).xyz;
  754. float3 rotatedWindVector = TransformWindVectorFromWorldToLocalSpace(windVector);
  755. if (iWindQuality == 0 || (length(rotatedWindVector) < 1.0e-5) )
  756. {
  757. return vReturnPos; // sanity check that wind data is available
  758. }
  759. // do wind
  760. float4x4 matObjectToWorld = GetObjectToWorldMatrix();
  761. float3 treePos = GetAbsolutePositionWS(float3(matObjectToWorld[0].w, matObjectToWorld[1].w, matObjectToWorld[2].w));
  762. float globalWindTime = Get_WindGlobal(bHistory).x;
  763. // BILLBOARD WIND =======================================================================================================================
  764. if(bBillboard)
  765. {
  766. vReturnPos = GlobalWind(vReturnPos, treePos, true, rotatedWindVector, globalWindTime, bHistory);
  767. return vReturnPos;
  768. }
  769. // 3D GEOMETRY WIND =====================================================================================================================
  770. // leaf
  771. bool leafTwo = false;
  772. const int geometryType = GetGeometryType(vTexcoord3, leafTwo);
  773. const bool bDoLeafWind = ((iWindQuality == ST_WIND_QUALITY_FAST) || (iWindQuality == ST_WIND_QUALITY_BETTER) || (iWindQuality == ST_WIND_QUALITY_BEST))
  774. && geometryType > ST_GEOM_TYPE_FROND;
  775. if (bDoLeafWind)
  776. {
  777. const float3 anchor = float3(vTexcoord1.zw, vTexcoord2.w);
  778. const float leafWindTrigOffset = anchor.x + anchor.y;
  779. const bool bBestWind = (iWindQuality == ST_WIND_QUALITY_BEST);
  780. vReturnPos -= anchor; // remove anchor position
  781. vReturnPos = LeafWind(bBestWind, leafTwo, vReturnPos, vNormal, vTexcoord3.x, float3(0, 0, 0), vTexcoord3.y, vTexcoord3.z, leafWindTrigOffset, rotatedWindVector, bHistory);
  782. vReturnPos += anchor; // move back out to anchor
  783. }
  784. // frond wind (palm-only)
  785. const bool bDoPalmWind = iWindQuality == ST_WIND_QUALITY_PALM && geometryType == ST_GEOM_TYPE_FROND;
  786. if (bDoPalmWind)
  787. {
  788. vReturnPos = RippleFrond(vReturnPos, vNormal, vTexcoord0.x, vTexcoord0.y, vTexcoord3.x, vTexcoord3.y, vTexcoord3.z, bHistory);
  789. }
  790. // branch wind (applies to all 3D geometry)
  791. const bool bDoBranchWind = (iWindQuality == ST_WIND_QUALITY_BETTER) || (iWindQuality == ST_WIND_QUALITY_BEST) || (iWindQuality == ST_WIND_QUALITY_PALM);
  792. if (bDoBranchWind)
  793. {
  794. const float4 windBranchAnchorHistory = Get_WindBranchAnchor(bHistory);
  795. const float3 rotatedBranchAnchor = TransformWorldToObjectDir(windBranchAnchorHistory.xyz) * windBranchAnchorHistory.w;
  796. vReturnPos = BranchWind(bDoPalmWind, vReturnPos, treePos, float4(vTexcoord0.zw, 0, 0), rotatedWindVector, rotatedBranchAnchor, bHistory);
  797. }
  798. // global wind
  799. vReturnPos = GlobalWind(vReturnPos, treePos, true, rotatedWindVector, globalWindTime, bHistory);
  800. return vReturnPos;
  801. }
  802. // ShaderGraph stub
  803. void SpeedTreeWind_float(float3 vPos, float3 vNormal, float4 vTexcoord0, float4 vTexcoord1, float4 vTexcoord2, float4 vTexcoord3, int iWindQuality, bool bBillboard, bool bHistory, out float3 outPos)
  804. {
  805. outPos = SpeedTreeWind(vPos, vNormal, vTexcoord0, vTexcoord1, vTexcoord2, vTexcoord3, iWindQuality, bBillboard, bHistory);
  806. }
  807. #endif // SPEEDTREE_WIND_8_INCLUDED