123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977 |
- // Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
-
- #ifndef SPEEDTREE_WIND_8_INCLUDED
- #define SPEEDTREE_WIND_8_INCLUDED
-
- #define SPEEDTREE_VERSION_8 1
- #include "SpeedTreeCommon.hlsl"
-
- ///////////////////////////////////////////////////////////////////////
- // Wind Info
-
- CBUFFER_START(SpeedTreeWind)
- float4 _ST_WindVector;
- float4 _ST_WindGlobal;
- float4 _ST_WindBranch;
- float4 _ST_WindBranchTwitch;
- float4 _ST_WindBranchWhip;
- float4 _ST_WindBranchAnchor;
- float4 _ST_WindBranchAdherences;
- float4 _ST_WindTurbulences;
- float4 _ST_WindLeaf1Ripple;
- float4 _ST_WindLeaf1Tumble;
- float4 _ST_WindLeaf1Twitch;
- float4 _ST_WindLeaf2Ripple;
- float4 _ST_WindLeaf2Tumble;
- float4 _ST_WindLeaf2Twitch;
- float4 _ST_WindFrondRipple;
- float4 _ST_WindAnimation;
- CBUFFER_END
-
- CBUFFER_START(SpeedTreeWindHistory)
- float4 _ST_WindVectorHistory;
- float4 _ST_WindGlobalHistory;
- float4 _ST_WindBranchHistory;
- float4 _ST_WindBranchTwitchHistory;
- float4 _ST_WindBranchWhipHistory;
- float4 _ST_WindBranchAnchorHistory;
- float4 _ST_WindBranchAdherencesHistory;
- float4 _ST_WindTurbulencesHistory;
- float4 _ST_WindLeaf1RippleHistory;
- float4 _ST_WindLeaf1TumbleHistory;
- float4 _ST_WindLeaf1TwitchHistory;
- float4 _ST_WindLeaf2RippleHistory;
- float4 _ST_WindLeaf2TumbleHistory;
- float4 _ST_WindLeaf2TwitchHistory;
- float4 _ST_WindFrondRippleHistory;
- float4 _ST_WindAnimationHistory;
- CBUFFER_END
-
- #ifdef UNITY_DOTS_INSTANCING_ENABLED
-
- #define DOTS_ST_WindVector DOTS_ST_WindParam0
- #define DOTS_ST_WindGlobal DOTS_ST_WindParam1
- #define DOTS_ST_WindBranch DOTS_ST_WindParam2
- #define DOTS_ST_WindBranchTwitch DOTS_ST_WindParam3
- #define DOTS_ST_WindBranchWhip DOTS_ST_WindParam4
- #define DOTS_ST_WindBranchAnchor DOTS_ST_WindParam5
- #define DOTS_ST_WindBranchAdherences DOTS_ST_WindParam6
- #define DOTS_ST_WindTurbulences DOTS_ST_WindParam7
- #define DOTS_ST_WindLeaf1Ripple DOTS_ST_WindParam8
- #define DOTS_ST_WindLeaf1Tumble DOTS_ST_WindParam9
- #define DOTS_ST_WindLeaf1Twitch DOTS_ST_WindParam10
- #define DOTS_ST_WindLeaf2Ripple DOTS_ST_WindParam11
- #define DOTS_ST_WindLeaf2Tumble DOTS_ST_WindParam12
- #define DOTS_ST_WindLeaf2Twitch DOTS_ST_WindParam13
- #define DOTS_ST_WindFrondRipple DOTS_ST_WindParam14
- #define DOTS_ST_WindAnimation DOTS_ST_WindParam15
-
- #define DOTS_ST_WindVectorHistory DOTS_ST_WindHistoryParam0
- #define DOTS_ST_WindGlobalHistory DOTS_ST_WindHistoryParam1
- #define DOTS_ST_WindBranchHistory DOTS_ST_WindHistoryParam2
- #define DOTS_ST_WindBranchTwitchHistory DOTS_ST_WindHistoryParam3
- #define DOTS_ST_WindBranchWhipHistory DOTS_ST_WindHistoryParam4
- #define DOTS_ST_WindBranchAnchorHistory DOTS_ST_WindHistoryParam5
- #define DOTS_ST_WindBranchAdherencesHistory DOTS_ST_WindHistoryParam6
- #define DOTS_ST_WindTurbulencesHistory DOTS_ST_WindHistoryParam7
- #define DOTS_ST_WindLeaf1RippleHistory DOTS_ST_WindHistoryParam8
- #define DOTS_ST_WindLeaf1TumbleHistory DOTS_ST_WindHistoryParam9
- #define DOTS_ST_WindLeaf1TwitchHistory DOTS_ST_WindHistoryParam10
- #define DOTS_ST_WindLeaf2RippleHistory DOTS_ST_WindHistoryParam11
- #define DOTS_ST_WindLeaf2TumbleHistory DOTS_ST_WindHistoryParam12
- #define DOTS_ST_WindLeaf2TwitchHistory DOTS_ST_WindHistoryParam13
- #define DOTS_ST_WindFrondRippleHistory DOTS_ST_WindHistoryParam14
- #define DOTS_ST_WindAnimationHistory DOTS_ST_WindHistoryParam15
-
- UNITY_DOTS_INSTANCING_START(UserPropertyMetadata)
- UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindVector)
- UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindGlobal)
- UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindBranch)
- UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindBranchTwitch)
- UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindBranchWhip)
- UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindBranchAnchor)
- UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindBranchAdherences)
- UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindTurbulences)
- UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindLeaf1Ripple)
- UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindLeaf1Tumble)
- UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindLeaf1Twitch)
- UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindLeaf2Ripple)
- UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindLeaf2Tumble)
- UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindLeaf2Twitch)
- UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindFrondRipple)
- UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindAnimation)
-
- UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindVectorHistory)
- UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindGlobalHistory)
- UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindBranchHistory)
- UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindBranchTwitchHistory)
- UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindBranchWhipHistory)
- UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindBranchAnchorHistory)
- UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindBranchAdherencesHistory)
- UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindTurbulencesHistory)
- UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindLeaf1RippleHistory)
- UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindLeaf1TumbleHistory)
- UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindLeaf1TwitchHistory)
- UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindLeaf2RippleHistory)
- UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindLeaf2TumbleHistory)
- UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindLeaf2TwitchHistory)
- UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindFrondRippleHistory)
- UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindAnimationHistory)
- UNITY_DOTS_INSTANCING_END(UserPropertyMetadata)
-
- #define _ST_WindVector UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindVector)
- #define _ST_WindGlobal UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindGlobal)
- #define _ST_WindBranch UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindBranch)
- #define _ST_WindBranchTwitch UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindBranchTwitch)
- #define _ST_WindBranchWhip UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindBranchWhip)
- #define _ST_WindBranchAnchor UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindBranchAnchor)
- #define _ST_WindBranchAdherences UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindBranchAdherences)
- #define _ST_WindTurbulences UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindTurbulences)
- #define _ST_WindLeaf1Ripple UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindLeaf1Ripple)
- #define _ST_WindLeaf1Tumble UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindLeaf1Tumble)
- #define _ST_WindLeaf1Twitch UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindLeaf1Twitch)
- #define _ST_WindLeaf2Ripple UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindLeaf2Ripple)
- #define _ST_WindLeaf2Tumble UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindLeaf2Tumble)
- #define _ST_WindLeaf2Twitch UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindLeaf2Twitch)
- #define _ST_WindFrondRipple UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindFrondRipple)
- #define _ST_WindAnimation UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindAnimation)
-
- #define _ST_WindVectorHistory UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindVectorHistory)
- #define _ST_WindGlobalHistory UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindGlobalHistory)
- #define _ST_WindBranchHistory UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindBranchHistory)
- #define _ST_WindBranchTwitchHistory UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindBranchTwitchHistory)
- #define _ST_WindBranchWhipHistory UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindBranchWhipHistory)
- #define _ST_WindBranchAnchorHistory UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindBranchAnchorHistory)
- #define _ST_WindBranchAdherencesHistory UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindBranchAdherencesHistory)
- #define _ST_WindTurbulencesHistory UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindTurbulencesHistory)
- #define _ST_WindLeaf1RippleHistory UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindLeaf1RippleHistory)
- #define _ST_WindLeaf1TumbleHistory UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindLeaf1TumbleHistory)
- #define _ST_WindLeaf1TwitchHistory UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindLeaf1TwitchHistory)
- #define _ST_WindLeaf2RippleHistory UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindLeaf2RippleHistory)
- #define _ST_WindLeaf2TumbleHistory UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindLeaf2TumbleHistory)
- #define _ST_WindLeaf2TwitchHistory UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindLeaf2TwitchHistory)
- #define _ST_WindFrondRippleHistory UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindFrondRippleHistory)
- #define _ST_WindAnimationHistory UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindAnimationHistory)
-
- #endif
-
- #define ST_WIND_QUALITY_NONE 0
- #define ST_WIND_QUALITY_FASTEST 1
- #define ST_WIND_QUALITY_FAST 2
- #define ST_WIND_QUALITY_BETTER 3
- #define ST_WIND_QUALITY_BEST 4
- #define ST_WIND_QUALITY_PALM 5
-
- ///////////////////////////////////////////////////////////////////////
- // Get_Wind*() functions
-
- float4 Get_WindVector(bool bHistory) { return bHistory ? _ST_WindVectorHistory : _ST_WindVector; }
- float4 Get_WindGlobal(bool bHistory) { return bHistory ? _ST_WindGlobalHistory : _ST_WindGlobal; }
- float4 Get_WindBranch(bool bHistory) { return bHistory ? _ST_WindBranchHistory : _ST_WindBranch; }
- float4 Get_WindBranchTwitch(bool bHistory) { return bHistory ? _ST_WindBranchTwitchHistory : _ST_WindBranchTwitch; }
- float4 Get_WindBranchWhip(bool bHistory) { return bHistory ? _ST_WindBranchWhipHistory : _ST_WindBranchWhip; }
- float4 Get_WindBranchAnchor(bool bHistory) { return bHistory ? _ST_WindBranchAnchorHistory : _ST_WindBranchAnchor; }
- float4 Get_WindBranchAdherences(bool bHistory) { return bHistory ? _ST_WindBranchAdherencesHistory : _ST_WindBranchAdherences; }
- float4 Get_WindTurbulences(bool bHistory) { return bHistory ? _ST_WindTurbulencesHistory : _ST_WindTurbulences; }
- float4 Get_WindLeaf1Ripple(bool bHistory) { return bHistory ? _ST_WindLeaf1RippleHistory : _ST_WindLeaf1Ripple; }
- float4 Get_WindLeaf1Tumble(bool bHistory) { return bHistory ? _ST_WindLeaf1TumbleHistory : _ST_WindLeaf1Tumble; }
- float4 Get_WindLeaf1Twitch(bool bHistory) { return bHistory ? _ST_WindLeaf1TwitchHistory : _ST_WindLeaf1Twitch; }
- float4 Get_WindLeaf2Ripple(bool bHistory) { return bHistory ? _ST_WindLeaf2RippleHistory : _ST_WindLeaf2Ripple; }
- float4 Get_WindLeaf2Tumble(bool bHistory) { return bHistory ? _ST_WindLeaf2TumbleHistory : _ST_WindLeaf2Tumble; }
- float4 Get_WindLeaf2Twitch(bool bHistory) { return bHistory ? _ST_WindLeaf2TwitchHistory : _ST_WindLeaf2Twitch; }
- float4 Get_WindFrondRipple(bool bHistory) { return bHistory ? _ST_WindFrondRippleHistory : _ST_WindFrondRipple; }
- float4 Get_WindAnimation(bool bHistory) { return bHistory ? _ST_WindAnimationHistory : _ST_WindAnimation; }
-
- ///////////////////////////////////////////////////////////////////////
- // UnpackNormalFromFloat
-
- float3 UnpackNormalFromFloat(float fValue)
- {
- float3 vDecodeKey = float3(16.0, 1.0, 0.0625);
-
- // decode into [0,1] range
- float3 vDecodedValue = frac(fValue / vDecodeKey);
-
- // move back into [-1,1] range & normalize
- return (vDecodedValue * 2.0 - 1.0);
- }
-
-
- ///////////////////////////////////////////////////////////////////////
- // CubicSmooth
-
- float4 CubicSmooth(float4 vData)
- {
- return vData * vData * (3.0 - 2.0 * vData);
- }
-
-
- ///////////////////////////////////////////////////////////////////////
- // TriangleWave
-
- float4 TriangleWave(float4 vData)
- {
- return abs((frac(vData + 0.5) * 2.0) - 1.0);
- }
-
-
- ///////////////////////////////////////////////////////////////////////
- // TrigApproximate
-
- float4 TrigApproximate(float4 vData)
- {
- return (CubicSmooth(TriangleWave(vData)) - 0.5) * 2.0;
- }
-
-
- ///////////////////////////////////////////////////////////////////////
- // RotationMatrix
- //
- // Constructs an arbitrary axis rotation matrix
-
- float3x3 RotationMatrix(float3 vAxis, float fAngle)
- {
- // compute sin/cos of fAngle
- float2 vSinCos;
- #ifdef OPENGL
- vSinCos.x = sin(fAngle);
- vSinCos.y = cos(fAngle);
- #else
- sincos(fAngle, vSinCos.x, vSinCos.y);
- #endif
-
- const float c = vSinCos.y;
- const float s = vSinCos.x;
- const float t = 1.0 - c;
- const float x = vAxis.x;
- const float y = vAxis.y;
- const float z = vAxis.z;
-
- return float3x3(t * x * x + c, t * x * y - s * z, t * x * z + s * y,
- t * x * y + s * z, t * y * y + c, t * y * z - s * x,
- t * x * z - s * y, t * y * z + s * x, t * z * z + c);
- }
-
-
- ///////////////////////////////////////////////////////////////////////
- // mul_float3x3_float3x3
-
- float3x3 mul_float3x3_float3x3(float3x3 mMatrixA, float3x3 mMatrixB)
- {
- return mul(mMatrixA, mMatrixB);
- }
-
-
- ///////////////////////////////////////////////////////////////////////
- // mul_float3x3_float3
-
- float3 mul_float3x3_float3(float3x3 mMatrix, float3 vVector)
- {
- return mul(mMatrix, vVector);
- }
-
-
- ///////////////////////////////////////////////////////////////////////
- // cross()'s parameters are backwards in GLSL
-
- #define wind_cross(a, b) cross((a), (b))
-
-
- ///////////////////////////////////////////////////////////////////////
- // Roll
-
- float Roll(float fCurrent,
- float fMaxScale,
- float fMinScale,
- float fSpeed,
- float fRipple,
- float3 vPos,
- float fTime,
- float3 vRotatedWindVector)
- {
- float fWindAngle = dot(vPos, -vRotatedWindVector) * fRipple;
- float fAdjust = TrigApproximate(float4(fWindAngle + fTime * fSpeed, 0.0, 0.0, 0.0)).x;
- fAdjust = (fAdjust + 1.0) * 0.5;
-
- return lerp(fCurrent * fMinScale, fCurrent * fMaxScale, fAdjust);
- }
-
-
- ///////////////////////////////////////////////////////////////////////
- // Twitch
-
- float Twitch(float3 vPos, float fAmount, float fSharpness, float fTime)
- {
- const float c_fTwitchFudge = 0.87;
- float4 vOscillations = TrigApproximate(float4(fTime + (vPos.x + vPos.z), c_fTwitchFudge * fTime + vPos.y, 0.0, 0.0));
-
- //float fTwitch = sin(fFreq1 * fTime + (vPos.x + vPos.z)) * cos(fFreq2 * fTime + vPos.y);
- float fTwitch = vOscillations.x * vOscillations.y * vOscillations.y;
- fTwitch = (fTwitch + 1.0) * 0.5;
-
- return fAmount * pow(saturate(fTwitch), fSharpness);
- }
-
-
- ///////////////////////////////////////////////////////////////////////
- // Oscillate
- //
- // This function computes an oscillation value and whip value if necessary.
- // Whip and oscillation are combined like this to minimize calls to
- // TrigApproximate( ) when possible.
-
- float Oscillate(float3 vPos,
- float fTime,
- float fOffset,
- float fWeight,
- float fWhip,
- bool bWhip,
- bool bRoll,
- bool bComplex,
- float fTwitch,
- float fTwitchFreqScale,
- inout float4 vOscillations,
- float3 vRotatedWindVector,
- bool bHistory)
- {
- float fOscillation = 1.0;
- if (bComplex)
- {
- if (bWhip)
- vOscillations = TrigApproximate(float4(fTime + fOffset, fTime * fTwitchFreqScale + fOffset, fTwitchFreqScale * 0.5 * (fTime + fOffset), fTime + fOffset + (1.0 - fWeight)));
- else
- vOscillations = TrigApproximate(float4(fTime + fOffset, fTime * fTwitchFreqScale + fOffset, fTwitchFreqScale * 0.5 * (fTime + fOffset), 0.0));
-
- float fFineDetail = vOscillations.x;
- float fBroadDetail = vOscillations.y * vOscillations.z;
-
- float fTarget = 1.0;
- float fAmount = fBroadDetail;
- if (fBroadDetail < 0.0)
- {
- fTarget = -fTarget;
- fAmount = -fAmount;
- }
-
- fBroadDetail = lerp(fBroadDetail, fTarget, fAmount);
- fBroadDetail = lerp(fBroadDetail, fTarget, fAmount);
-
- fOscillation = fBroadDetail * fTwitch * (1.0 - Get_WindVector(bHistory).w) + fFineDetail * (1.0 - fTwitch);
-
- if (bWhip)
- fOscillation *= 1.0 + (vOscillations.w * fWhip);
- }
- else
- {
- if (bWhip)
- vOscillations = TrigApproximate(float4(fTime + fOffset, fTime * 0.689 + fOffset, 0.0, fTime + fOffset + (1.0 - fWeight)));
- else
- vOscillations = TrigApproximate(float4(fTime + fOffset, fTime * 0.689 + fOffset, 0.0, 0.0));
-
- fOscillation = vOscillations.x + vOscillations.y * vOscillations.x;
-
- if (bWhip)
- fOscillation *= 1.0 + (vOscillations.w * fWhip);
- }
-
- //if (bRoll)
- //{
- // fOscillation = Roll(fOscillation, _ST_WindRollingBranches.x, _ST_WindRollingBranches.y, _ST_WindRollingBranches.z, _ST_WindRollingBranches.w, vPos.xyz, fTime + fOffset, vRotatedWindVector);
- //}
-
- return fOscillation;
- }
-
-
- ///////////////////////////////////////////////////////////////////////
- // Turbulence
-
- float Turbulence(float fTime, float fOffset, float fGlobalTime, float fTurbulence)
- {
- const float c_fTurbulenceFactor = 0.1;
-
- float4 vOscillations = TrigApproximate(float4(fTime * c_fTurbulenceFactor + fOffset, fGlobalTime * fTurbulence * c_fTurbulenceFactor + fOffset, 0.0, 0.0));
-
- return 1.0 - (vOscillations.x * vOscillations.y * vOscillations.x * vOscillations.y * fTurbulence);
- }
-
-
- ///////////////////////////////////////////////////////////////////////
- // GlobalWind
- //
- // This function positions any tree geometry based on their untransformed
- // position and 4 wind floats.
-
- float3 GlobalWind(float3 vPos, float3 vInstancePos, bool bPreserveShape, float3 vRotatedWindVector, float time, bool bHistory)
- {
- // WIND_LOD_GLOBAL may be on, but if the global wind effect (WIND_EFFECT_GLOBAL_ST_Wind)
- // was disabled for the tree in the Modeler, we should skip it
- const float4 windGlobal = Get_WindGlobal(bHistory);
- const float4 windBranchAdherences = Get_WindBranchAdherences(bHistory);
-
- float fLength = 1.0;
- if (bPreserveShape)
- fLength = length(vPos.xyz);
-
- // compute how much the height contributes
- #ifdef SPEEDTREE_Z_UP
- float fAdjust = max(vPos.z - (1.0 / windGlobal.z) * 0.25, 0.0) * windGlobal.z;
- #else
- float fAdjust = max(vPos.y - (1.0 / windGlobal.z) * 0.25, 0.0) * windGlobal.z;
- #endif
- if (fAdjust != 0.0)
- fAdjust = pow(abs(fAdjust), windGlobal.w);
-
- // primary oscillation
- float4 vOscillations = TrigApproximate(float4(vInstancePos.x + time, vInstancePos.y + time * 0.8, 0.0, 0.0));
- float fOsc = vOscillations.x + (vOscillations.y * vOscillations.y);
- float fMoveAmount = windGlobal.y * fOsc;
-
- // move a minimum amount based on direction adherence
- fMoveAmount += windBranchAdherences.x / windGlobal.z;
-
- // adjust based on how high up the tree this vertex is
- fMoveAmount *= fAdjust;
-
- // xy component
- #ifdef SPEEDTREE_Z_UP
- vPos.xy += vRotatedWindVector.xy * fMoveAmount;
- #else
- vPos.xz += vRotatedWindVector.xz * fMoveAmount;
- #endif
-
- if (bPreserveShape)
- vPos.xyz = normalize(vPos.xyz) * fLength;
-
- return vPos;
- }
-
-
- ///////////////////////////////////////////////////////////////////////
- // SimpleBranchWind
-
- float3 SimpleBranchWind(float3 vPos,
- float3 vInstancePos,
- float fWeight,
- float fOffset,
- float fTime,
- float fDistance,
- float fTwitch,
- float fTwitchScale,
- float fWhip,
- bool bWhip,
- bool bRoll,
- bool bComplex,
- float3 vRotatedWindVector,
- bool bHistory)
- {
- // turn the offset back into a nearly normalized vector
- float3 vWindVector = UnpackNormalFromFloat(fOffset);
- vWindVector = vWindVector * fWeight;
-
- // try to fudge time a bit so that instances aren't in sync
- fTime += vInstancePos.x + vInstancePos.y;
-
- // oscillate
- float4 vOscillations;
- float fOsc = Oscillate(vPos, fTime, fOffset, fWeight, fWhip, bWhip, bRoll, bComplex, fTwitch, fTwitchScale, vOscillations, vRotatedWindVector, bHistory);
-
- vPos.xyz += vWindVector * fOsc * fDistance;
-
- return vPos;
- }
-
-
- ///////////////////////////////////////////////////////////////////////
- // DirectionalBranchWind
-
- float3 DirectionalBranchWind(float3 vPos,
- float3 vInstancePos,
- float fWeight,
- float fOffset,
- float fTime,
- float fDistance,
- float fTurbulence,
- float fAdherence,
- float fTwitch,
- float fTwitchScale,
- float fWhip,
- bool bWhip,
- bool bRoll,
- bool bComplex,
- bool bTurbulence,
- float3 vRotatedWindVector,
- bool bHistory)
- {
- // turn the offset back into a nearly normalized vector
- float3 vWindVector = UnpackNormalFromFloat(fOffset);
- vWindVector = vWindVector * fWeight;
-
- // try to fudge time a bit so that instances aren't in sync
- fTime += vInstancePos.x + vInstancePos.y;
-
- // oscillate
- float4 vOscillations;
- float fOsc = Oscillate(vPos, fTime, fOffset, fWeight, fWhip, bWhip, false, bComplex, fTwitch, fTwitchScale, vOscillations, vRotatedWindVector, bHistory);
-
- vPos.xyz += vWindVector * fOsc * fDistance;
-
- // add in the direction, accounting for turbulence
- float fAdherenceScale = 1.0;
- if (bTurbulence)
- fAdherenceScale = Turbulence(fTime, fOffset, Get_WindAnimation(bHistory).x, fTurbulence);
-
- if (bWhip)
- fAdherenceScale += vOscillations.w * Get_WindVector(bHistory).w * fWhip;
-
- //if (bRoll)
- // fAdherenceScale = Roll(fAdherenceScale, _ST_WindRollingBranches.x, _ST_WindRollingBranches.y, _ST_WindRollingBranches.z, _ST_WindRollingBranches.w, vPos.xyz, fTime + fOffset, vRotatedWindVector);
-
- vPos.xyz += vRotatedWindVector * fAdherence * fAdherenceScale * fWeight;
-
- return vPos;
- }
-
-
- ///////////////////////////////////////////////////////////////////////
- // DirectionalBranchWindFrondStyle
-
- float3 DirectionalBranchWindFrondStyle(float3 vPos,
- float3 vInstancePos,
- float fWeight,
- float fOffset,
- float fTime,
- float fDistance,
- float fTurbulence,
- float fAdherence,
- float fTwitch,
- float fTwitchScale,
- float fWhip,
- bool bWhip,
- bool bRoll,
- bool bComplex,
- bool bTurbulence,
- float3 vRotatedWindVector,
- float3 vRotatedBranchAnchor,
- bool bHistory)
- {
- // turn the offset back into a nearly normalized vector
- float3 vWindVector = UnpackNormalFromFloat(fOffset);
- vWindVector = vWindVector * fWeight;
-
- // try to fudge time a bit so that instances aren't in sync
- fTime += vInstancePos.x + vInstancePos.y;
-
- // oscillate
- float4 vOscillations;
- float fOsc = Oscillate(vPos, fTime, fOffset, fWeight, fWhip, bWhip, false, bComplex, fTwitch, fTwitchScale, vOscillations, vRotatedWindVector, bHistory);
-
- vPos.xyz += vWindVector * fOsc * fDistance;
-
- // add in the direction, accounting for turbulence
- float fAdherenceScale = 1.0;
- if (bTurbulence)
- fAdherenceScale = Turbulence(fTime, fOffset, Get_WindAnimation(bHistory).x, fTurbulence);
-
- //if (bRoll)
- // fAdherenceScale = Roll(fAdherenceScale, _ST_WindRollingBranches.x, _ST_WindRollingBranches.y, _ST_WindRollingBranches.z, _ST_WindRollingBranches.w, vPos.xyz, fTime + fOffset, vRotatedWindVector);
-
- if (bWhip)
- fAdherenceScale += vOscillations.w * Get_WindVector(bHistory).w * fWhip;
-
- float3 vWindAdherenceVector = vRotatedBranchAnchor - vPos.xyz;
- vPos.xyz += vWindAdherenceVector * fAdherence * fAdherenceScale * fWeight;
-
- return vPos;
- }
-
-
- ///////////////////////////////////////////////////////////////////////
- // BranchWind
-
- // Apply only to better, best, palm winds
- float3 BranchWind(bool isPalmWind, float3 vPos, float3 vInstancePos, float4 vWindData, float3 vRotatedWindVector, float3 vRotatedBranchAnchor, bool bHistory)
- {
- const float4 windBranch = Get_WindBranch(bHistory);
- const float4 windBranchTwitch = Get_WindBranchTwitch(bHistory);
- const float4 windBranchAdherences = Get_WindBranchAdherences(bHistory);
- const float4 windBarnchWhip = Get_WindBranchWhip(bHistory);
- const float4 windTurbulences = Get_WindTurbulences(bHistory);
- const bool bWhip = isPalmWind;
- const bool bRoll = false;
- const bool bComplex = true;
-
- if (isPalmWind)
- {
- const bool bTurbulence = true;
- vPos = DirectionalBranchWindFrondStyle(
- vPos,
- vInstancePos,
- vWindData.x, vWindData.y,
- windBranch.x, windBranch.y,
- windTurbulences.x, windBranchAdherences.y,
- windBranchTwitch.x, windBranchTwitch.y,
- windBarnchWhip.x,
- bWhip,
- bRoll,
- bComplex,
- bTurbulence,
- vRotatedWindVector,
- vRotatedBranchAnchor,
- bHistory
- );
- }
- else
- {
- vPos = SimpleBranchWind(
- vPos,
- vInstancePos,
- vWindData.x, vWindData.y,
- windBranch.x, windBranch.y,
- windBranchTwitch.x, windBranchTwitch.y,
- windBarnchWhip.x,
- bWhip,
- bRoll,
- bComplex,
- vRotatedWindVector,
- bHistory
- );
- }
-
- return vPos;
- }
-
-
- ///////////////////////////////////////////////////////////////////////
- // LeafRipple
-
- float3 LeafRipple(float3 vPos,
- inout float3 vDirection,
- float fScale,
- float fPackedRippleDir,
- float fTime,
- float fAmount,
- bool bDirectional,
- float fTrigOffset)
- {
- // compute how much to move
- float4 vInput = float4(fTime + fTrigOffset, 0.0, 0.0, 0.0);
- float fMoveAmount = fAmount * TrigApproximate(vInput).x;
-
- if (bDirectional)
- {
- vPos.xyz += vDirection.xyz * fMoveAmount * fScale;
- }
- else
- {
- float3 vRippleDir = UnpackNormalFromFloat(fPackedRippleDir);
- vPos.xyz += vRippleDir * fMoveAmount * fScale;
- }
-
- return vPos;
- }
-
-
- ///////////////////////////////////////////////////////////////////////
- // LeafTumble
-
- float3 LeafTumble(float3 vPos,
- inout float3 vDirection,
- float fScale,
- float3 vAnchor,
- float3 vGrowthDir,
- float fTrigOffset,
- float fTime,
- float fFlip,
- float fTwist,
- float fAdherence,
- float3 vTwitch,
- float4 vRoll,
- bool bTwitch,
- bool bRoll,
- float3 vRotatedWindVector)
- {
- // compute all oscillations up front
- float3 vFracs = frac((vAnchor + fTrigOffset) * 30.3);
- float fOffset = vFracs.x + vFracs.y + vFracs.z;
- float4 vOscillations = TrigApproximate(float4(fTime + fOffset, fTime * 0.75 - fOffset, fTime * 0.01 + fOffset, fTime * 1.0 + fOffset));
-
- // move to the origin and get the growth direction
- float3 vOriginPos = vPos.xyz - vAnchor;
- float fLength = length(vOriginPos);
-
- // twist
- float fOsc = vOscillations.x + vOscillations.y * vOscillations.y;
- float3x3 matTumble = RotationMatrix(vGrowthDir, fScale * fTwist * fOsc);
-
- // with wind
- float3 vAxis = wind_cross(vGrowthDir.xyz, vRotatedWindVector.xyz);
- float fDot = clamp(dot(vRotatedWindVector, vGrowthDir), -1.0, 1.0);
- #ifdef SPEEDTREE_Z_UP
- vAxis.z += fDot;
- #else
- vAxis.y += fDot;
- #endif
- vAxis = normalize(vAxis);
-
- float fAngle = acos(fDot);
-
- float fAdherenceScale = 1.0;
- //if (bRoll)
- //{
- // fAdherenceScale = Roll(fAdherenceScale, vRoll.x, vRoll.y, vRoll.z, vRoll.w, vAnchor.xyz, fTime, vRotatedWindVector);
- //}
-
- fOsc = vOscillations.y - vOscillations.x * vOscillations.x;
-
- float fTwitch = 0.0;
- if (bTwitch)
- fTwitch = Twitch(vAnchor.xyz, vTwitch.x, vTwitch.y, vTwitch.z + fOffset);
-
- matTumble = mul_float3x3_float3x3(matTumble, RotationMatrix(vAxis, fScale * (fAngle * fAdherence * fAdherenceScale + fOsc * fFlip + fTwitch)));
-
- vDirection = mul_float3x3_float3(matTumble, vDirection);
- vOriginPos = mul_float3x3_float3(matTumble, vOriginPos);
-
- vOriginPos = normalize(vOriginPos) * fLength;
-
- return (vOriginPos + vAnchor);
- }
-
-
- ///////////////////////////////////////////////////////////////////////
- // LeafWind
- // Optimized (for instruction count) version. Assumes leaf 1 and 2 have the same options
-
- float3 LeafWind(bool isBestWind,
- bool bLeaf2,
- float3 vPos,
- inout float3 vDirection,
- float fScale,
- float3 vAnchor,
- float fPackedGrowthDir,
- float fPackedRippleDir,
- float fRippleTrigOffset,
- float3 vRotatedWindVector,
- bool bHistory)
- {
- const float4 windLeaf2Ripple = Get_WindLeaf2Ripple(bHistory);
- const float4 windLeaf1Ripple = Get_WindLeaf1Ripple(bHistory);
- const float4 windLeaf1Tumble = Get_WindLeaf1Tumble(bHistory);
- const float4 windLeaf2Tumble = Get_WindLeaf2Tumble(bHistory);
- const float4 windLeaf1Twitch = Get_WindLeaf2Twitch(bHistory);
- const float4 windLeaf2Twitch = Get_WindLeaf2Twitch(bHistory);
-
- vPos = LeafRipple(vPos, vDirection, fScale, fPackedRippleDir,
- (bLeaf2 ? windLeaf2Ripple.x : windLeaf1Ripple.x),
- (bLeaf2 ? windLeaf2Ripple.y : windLeaf1Ripple.y),
- false, fRippleTrigOffset);
-
- if (isBestWind)
- {
- float3 vGrowthDir = UnpackNormalFromFloat(fPackedGrowthDir);
- vPos = LeafTumble(vPos, vDirection, fScale, vAnchor, vGrowthDir, fPackedGrowthDir,
- (bLeaf2 ? windLeaf2Tumble.x : windLeaf1Tumble.x),
- (bLeaf2 ? windLeaf2Tumble.y : windLeaf1Tumble.y),
- (bLeaf2 ? windLeaf2Tumble.z : windLeaf1Tumble.z),
- (bLeaf2 ? windLeaf2Tumble.w : windLeaf1Tumble.w),
- (bLeaf2 ? windLeaf2Twitch.xyz : windLeaf1Twitch.xyz),
- 0.0f,
- true,
- true,
- vRotatedWindVector);
- }
-
- return vPos;
- }
-
-
- ///////////////////////////////////////////////////////////////////////
- // RippleFrondOneSided
-
- float3 RippleFrondOneSided(float3 vPos,
- inout float3 vDirection,
- float fU,
- float fV,
- float fRippleScale,
- bool bHistory
- #ifdef WIND_EFFECT_FROND_RIPPLE_ADJUST_LIGHTING
- , float3 vBinormal
- , float3 vTangent
- #endif
- )
- {
- float fOffset = 0.0;
- if (fU < 0.5)
- fOffset = 0.75;
-
- const float4 windFrondRipple = Get_WindFrondRipple(bHistory);
-
- float4 vOscillations = TrigApproximate(float4((windFrondRipple.x + fV) * windFrondRipple.z + fOffset, 0.0, 0.0, 0.0));
-
- float fAmount = fRippleScale * vOscillations.x * windFrondRipple.y;
- float3 vOffset = fAmount * vDirection;
- vPos.xyz += vOffset;
-
- #ifdef WIND_EFFECT_FROND_RIPPLE_ADJUST_LIGHTING
- vTangent.xyz = normalize(vTangent.xyz + vOffset * windFrondRipple.w);
- float3 vNewNormal = normalize(wind_cross(vBinormal.xyz, vTangent.xyz));
- if (dot(vNewNormal, vDirection.xyz) < 0.0)
- vNewNormal = -vNewNormal;
- vDirection.xyz = vNewNormal;
- #endif
-
- return vPos;
- }
-
- ///////////////////////////////////////////////////////////////////////
- // RippleFrondTwoSided
-
- float3 RippleFrondTwoSided(float3 vPos,
- inout float3 vDirection,
- float fU,
- float fLengthPercent,
- float fPackedRippleDir,
- float fRippleScale,
- bool bHistory
- #ifdef WIND_EFFECT_FROND_RIPPLE_ADJUST_LIGHTING
- , float3 vBinormal
- , float3 vTangent
- #endif
- )
- {
- const float4 windFrondRipple = Get_WindFrondRipple(bHistory);
- float4 vOscillations = TrigApproximate(float4(windFrondRipple.x * fLengthPercent * windFrondRipple.z, 0.0, 0.0, 0.0));
-
- float3 vRippleDir = UnpackNormalFromFloat(fPackedRippleDir);
-
- float fAmount = fRippleScale * vOscillations.x * windFrondRipple.y;
- float3 vOffset = fAmount * vRippleDir;
-
- vPos.xyz += vOffset;
-
- #ifdef WIND_EFFECT_FROND_RIPPLE_ADJUST_LIGHTING
- vTangent.xyz = normalize(vTangent.xyz + vOffset * windFrondRipple.w);
- float3 vNewNormal = normalize(wind_cross(vBinormal.xyz, vTangent.xyz));
- if (dot(vNewNormal, vDirection.xyz) < 0.0)
- vNewNormal = -vNewNormal;
- vDirection.xyz = vNewNormal;
- #endif
-
- return vPos;
- }
-
-
- ///////////////////////////////////////////////////////////////////////
- // RippleFrond
-
- float3 RippleFrond(float3 vPos,
- inout float3 vDirection,
- float fU,
- float fV,
- float fPackedRippleDir,
- float fRippleScale,
- float fLenghtPercent,
- bool bHistory
- #ifdef WIND_EFFECT_FROND_RIPPLE_ADJUST_LIGHTING
- , float3 vBinormal
- , float3 vTangent
- #endif
- )
- {
- return RippleFrondOneSided(vPos,
- vDirection,
- fU,
- fV,
- fRippleScale,
- bHistory
- #ifdef WIND_EFFECT_FROND_RIPPLE_ADJUST_LIGHTING
- , vBinormal
- , vTangent
- #endif
- );
- }
-
- ///////////////////////////////////////////////////////////////////////
- // SpeedTreeWind
-
-
- float3 SpeedTreeWind(
- float3 vPos,
- float3 vNormal,
- float4 vTexcoord0,
- float4 vTexcoord1,
- float4 vTexcoord2,
- float4 vTexcoord3,
- int iWindQuality,
- bool bBillboard,
- bool bHistory
- )
- {
- float3 vReturnPos = vPos;
-
- // check wind enabled & data available
- float3 windVector = Get_WindVector(bHistory).xyz;
- float3 rotatedWindVector = TransformWindVectorFromWorldToLocalSpace(windVector);
-
- if (iWindQuality == 0 || (length(rotatedWindVector) < 1.0e-5) )
- {
- return vReturnPos; // sanity check that wind data is available
- }
-
- // do wind
- float4x4 matObjectToWorld = GetObjectToWorldMatrix();
- float3 treePos = GetAbsolutePositionWS(float3(matObjectToWorld[0].w, matObjectToWorld[1].w, matObjectToWorld[2].w));
- float globalWindTime = Get_WindGlobal(bHistory).x;
-
- // BILLBOARD WIND =======================================================================================================================
- if(bBillboard)
- {
- vReturnPos = GlobalWind(vReturnPos, treePos, true, rotatedWindVector, globalWindTime, bHistory);
- return vReturnPos;
- }
-
- // 3D GEOMETRY WIND =====================================================================================================================
- // leaf
- bool leafTwo = false;
- const int geometryType = GetGeometryType(vTexcoord3, leafTwo);
- const bool bDoLeafWind = ((iWindQuality == ST_WIND_QUALITY_FAST) || (iWindQuality == ST_WIND_QUALITY_BETTER) || (iWindQuality == ST_WIND_QUALITY_BEST))
- && geometryType > ST_GEOM_TYPE_FROND;
- if (bDoLeafWind)
- {
- const float3 anchor = float3(vTexcoord1.zw, vTexcoord2.w);
- const float leafWindTrigOffset = anchor.x + anchor.y;
- const bool bBestWind = (iWindQuality == ST_WIND_QUALITY_BEST);
-
- vReturnPos -= anchor; // remove anchor position
- vReturnPos = LeafWind(bBestWind, leafTwo, vReturnPos, vNormal, vTexcoord3.x, float3(0, 0, 0), vTexcoord3.y, vTexcoord3.z, leafWindTrigOffset, rotatedWindVector, bHistory);
- vReturnPos += anchor; // move back out to anchor
- }
-
- // frond wind (palm-only)
- const bool bDoPalmWind = iWindQuality == ST_WIND_QUALITY_PALM && geometryType == ST_GEOM_TYPE_FROND;
- if (bDoPalmWind)
- {
- vReturnPos = RippleFrond(vReturnPos, vNormal, vTexcoord0.x, vTexcoord0.y, vTexcoord3.x, vTexcoord3.y, vTexcoord3.z, bHistory);
- }
-
- // branch wind (applies to all 3D geometry)
- const bool bDoBranchWind = (iWindQuality == ST_WIND_QUALITY_BETTER) || (iWindQuality == ST_WIND_QUALITY_BEST) || (iWindQuality == ST_WIND_QUALITY_PALM);
- if (bDoBranchWind)
- {
- const float4 windBranchAnchorHistory = Get_WindBranchAnchor(bHistory);
- const float3 rotatedBranchAnchor = TransformWorldToObjectDir(windBranchAnchorHistory.xyz) * windBranchAnchorHistory.w;
- vReturnPos = BranchWind(bDoPalmWind, vReturnPos, treePos, float4(vTexcoord0.zw, 0, 0), rotatedWindVector, rotatedBranchAnchor, bHistory);
- }
-
- // global wind
- vReturnPos = GlobalWind(vReturnPos, treePos, true, rotatedWindVector, globalWindTime, bHistory);
- return vReturnPos;
- }
-
- // ShaderGraph stub
- void SpeedTreeWind_float(float3 vPos, float3 vNormal, float4 vTexcoord0, float4 vTexcoord1, float4 vTexcoord2, float4 vTexcoord3, int iWindQuality, bool bBillboard, bool bHistory, out float3 outPos)
- {
- outPos = SpeedTreeWind(vPos, vNormal, vTexcoord0, vTexcoord1, vTexcoord2, vTexcoord3, iWindQuality, bBillboard, bHistory);
- }
- #endif // SPEEDTREE_WIND_8_INCLUDED
|