A game about forced loneliness, made by TACStudios
1// Unity built-in shader source. Copyright (c) 2024 Unity Technologies. MIT license (see license.txt) 2 3#ifndef SPEEDTREE_WIND_9_INCLUDED 4#define SPEEDTREE_WIND_9_INCLUDED 5 6#define SPEEDTREE_VERSION_9 7#include "SpeedTreeCommon.hlsl" 8 9// 10// DATA DEFINITIONS 11// 12struct WindBranchState // 8 floats | 32B 13{ 14 float3 m_vNoisePosTurbulence; 15 float m_fIndependence; 16 float m_fBend; 17 float m_fOscillation; 18 float m_fTurbulence; 19 float m_fFlexibility; 20}; 21struct WindRippleState // 8 floats | 32B 22{ 23 float3 m_vNoisePosTurbulence; 24 float m_fIndependence; 25 float m_fPlanar; 26 float m_fDirectional; 27 float m_fFlexibility; 28 float m_fShimmer; 29}; 30struct CBufferSpeedTree9 // 44 floats | 176B 31{ 32 float3 m_vWindDirection; 33 float m_fWindStrength; 34 35 float3 m_vTreeExtents; 36 float m_fSharedHeightStart; 37 38 float m_fBranch1StretchLimit; 39 float m_fBranch2StretchLimit; 40 float m_fWindIndependence; 41 float m_fImportScaling; 42 43 WindBranchState m_sShared; 44 WindBranchState m_sBranch1; 45 WindBranchState m_sBranch2; 46 WindRippleState m_sRipple; 47}; 48 49CBUFFER_START(SpeedTreeWind) 50float4 _ST_WindVector; 51float4 _ST_TreeExtents_SharedHeightStart; 52float4 _ST_BranchStretchLimits; 53float4 _ST_Shared_NoisePosTurbulence_Independence; 54float4 _ST_Shared_Bend_Oscillation_Turbulence_Flexibility; 55float4 _ST_Branch1_NoisePosTurbulence_Independence; 56float4 _ST_Branch1_Bend_Oscillation_Turbulence_Flexibility; 57float4 _ST_Branch2_NoisePosTurbulence_Independence; 58float4 _ST_Branch2_Bend_Oscillation_Turbulence_Flexibility; 59float4 _ST_Ripple_NoisePosTurbulence_Independence; 60float4 _ST_Ripple_Planar_Directional_Flexibility_Shimmer; 61CBUFFER_END 62 63CBUFFER_START(SpeedTreeWindHistory) 64float4 _ST_HistoryWindVector; 65float4 _ST_HistoryTreeExtents_SharedHeightStart; 66float4 _ST_HistoryBranchStretchLimits; 67float4 _ST_HistoryShared_NoisePosTurbulence_Independence; 68float4 _ST_HistoryShared_Bend_Oscillation_Turbulence_Flexibility; 69float4 _ST_HistoryBranch1_NoisePosTurbulence_Independence; 70float4 _ST_HistoryBranch1_Bend_Oscillation_Turbulence_Flexibility; 71float4 _ST_HistoryBranch2_NoisePosTurbulence_Independence; 72float4 _ST_HistoryBranch2_Bend_Oscillation_Turbulence_Flexibility; 73float4 _ST_HistoryRipple_NoisePosTurbulence_Independence; 74float4 _ST_HistoryRipple_Planar_Directional_Flexibility_Shimmer; 75CBUFFER_END 76 77#ifdef UNITY_DOTS_INSTANCING_ENABLED 78 79#define DOTS_ST_WindVector DOTS_ST_WindParam0 80#define DOTS_ST_TreeExtents_SharedHeightStart DOTS_ST_WindParam1 81#define DOTS_ST_BranchStretchLimits DOTS_ST_WindParam2 82#define DOTS_ST_Shared_NoisePosTurbulence_Independence DOTS_ST_WindParam3 83#define DOTS_ST_Shared_Bend_Oscillation_Turbulence_Flexibility DOTS_ST_WindParam4 84#define DOTS_ST_Branch1_NoisePosTurbulence_Independence DOTS_ST_WindParam5 85#define DOTS_ST_Branch1_Bend_Oscillation_Turbulence_Flexibility DOTS_ST_WindParam6 86#define DOTS_ST_Branch2_NoisePosTurbulence_Independence DOTS_ST_WindParam7 87#define DOTS_ST_Branch2_Bend_Oscillation_Turbulence_Flexibility DOTS_ST_WindParam8 88#define DOTS_ST_Ripple_NoisePosTurbulence_Independence DOTS_ST_WindParam9 89#define DOTS_ST_Ripple_Planar_Directional_Flexibility_Shimmer DOTS_ST_WindParam10 90 91#define DOTS_ST_HistoryWindVector DOTS_ST_WindHistoryParam0 92#define DOTS_ST_HistoryTreeExtents_SharedHeightStart DOTS_ST_WindHistoryParam1 93#define DOTS_ST_HistoryBranchStretchLimits DOTS_ST_WindHistoryParam2 94#define DOTS_ST_HistoryShared_NoisePosTurbulence_Independence DOTS_ST_WindHistoryParam3 95#define DOTS_ST_HistoryShared_Bend_Oscillation_Turbulence_Flexibility DOTS_ST_WindHistoryParam4 96#define DOTS_ST_HistoryBranch1_NoisePosTurbulence_Independence DOTS_ST_WindHistoryParam5 97#define DOTS_ST_HistoryBranch1_Bend_Oscillation_Turbulence_Flexibility DOTS_ST_WindHistoryParam6 98#define DOTS_ST_HistoryBranch2_NoisePosTurbulence_Independence DOTS_ST_WindHistoryParam7 99#define DOTS_ST_HistoryBranch2_Bend_Oscillation_Turbulence_Flexibility DOTS_ST_WindHistoryParam8 100#define DOTS_ST_HistoryRipple_NoisePosTurbulence_Independence DOTS_ST_WindHistoryParam9 101#define DOTS_ST_HistoryRipple_Planar_Directional_Flexibility_Shimmer DOTS_ST_WindHistoryParam10 102 103UNITY_DOTS_INSTANCING_START(UserPropertyMetadata) 104 UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindVector) 105 UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_TreeExtents_SharedHeightStart) 106 UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_BranchStretchLimits) 107 UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_Shared_NoisePosTurbulence_Independence) 108 UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_Shared_Bend_Oscillation_Turbulence_Flexibility) 109 UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_Branch1_NoisePosTurbulence_Independence) 110 UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_Branch1_Bend_Oscillation_Turbulence_Flexibility) 111 UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_Branch2_NoisePosTurbulence_Independence) 112 UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_Branch2_Bend_Oscillation_Turbulence_Flexibility) 113 UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_Ripple_NoisePosTurbulence_Independence) 114 UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_Ripple_Planar_Directional_Flexibility_Shimmer) 115 116 UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_HistoryWindVector) 117 UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_HistoryTreeExtents_SharedHeightStart) 118 UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_HistoryBranchStretchLimits) 119 UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_HistoryShared_NoisePosTurbulence_Independence) 120 UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_HistoryShared_Bend_Oscillation_Turbulence_Flexibility) 121 UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_HistoryBranch1_NoisePosTurbulence_Independence) 122 UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_HistoryBranch1_Bend_Oscillation_Turbulence_Flexibility) 123 UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_HistoryBranch2_NoisePosTurbulence_Independence) 124 UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_HistoryBranch2_Bend_Oscillation_Turbulence_Flexibility) 125 UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_HistoryRipple_NoisePosTurbulence_Independence) 126 UNITY_DOTS_INSTANCED_PROP(float4, DOTS_ST_HistoryRipple_Planar_Directional_Flexibility_Shimmer) 127UNITY_DOTS_INSTANCING_END(UserPropertyMetadata) 128 129#define _ST_WindVector UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_WindVector) 130#define _ST_TreeExtents_SharedHeightStart UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_TreeExtents_SharedHeightStart) 131#define _ST_BranchStretchLimits UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_BranchStretchLimits) 132#define _ST_Shared_NoisePosTurbulence_Independence UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_Shared_NoisePosTurbulence_Independence) 133#define _ST_Shared_Bend_Oscillation_Turbulence_Flexibility UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_Shared_Bend_Oscillation_Turbulence_Flexibility) 134#define _ST_Branch1_NoisePosTurbulence_Independence UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_Branch1_NoisePosTurbulence_Independence) 135#define _ST_Branch1_Bend_Oscillation_Turbulence_Flexibility UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_Branch1_Bend_Oscillation_Turbulence_Flexibility) 136#define _ST_Branch2_NoisePosTurbulence_Independence UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_Branch2_NoisePosTurbulence_Independence) 137#define _ST_Branch2_Bend_Oscillation_Turbulence_Flexibility UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_Branch2_Bend_Oscillation_Turbulence_Flexibility) 138#define _ST_Ripple_NoisePosTurbulence_Independence UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_Ripple_NoisePosTurbulence_Independence) 139#define _ST_Ripple_Planar_Directional_Flexibility_Shimmer UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_Ripple_Planar_Directional_Flexibility_Shimmer) 140 141#define _ST_HistoryWindVector UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_HistoryWindVector) 142#define _ST_HistoryTreeExtents_SharedHeightStart UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_HistoryTreeExtents_SharedHeightStart) 143#define _ST_HistoryBranchStretchLimits UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_HistoryBranchStretchLimits) 144#define _ST_HistoryShared_NoisePosTurbulence_Independence UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_HistoryShared_NoisePosTurbulence_Independence) 145#define _ST_HistoryShared_Bend_Oscillation_Turbulence_Flexibility UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_HistoryShared_Bend_Oscillation_Turbulence_Flexibility) 146#define _ST_HistoryBranch1_NoisePosTurbulence_Independence UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_HistoryBranch1_NoisePosTurbulence_Independence) 147#define _ST_HistoryBranch1_Bend_Oscillation_Turbulence_Flexibility UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_HistoryBranch1_Bend_Oscillation_Turbulence_Flexibility) 148#define _ST_HistoryBranch2_NoisePosTurbulence_Independence UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_HistoryBranch2_NoisePosTurbulence_Independence) 149#define _ST_HistoryBranch2_Bend_Oscillation_Turbulence_Flexibility UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_HistoryBranch2_Bend_Oscillation_Turbulence_Flexibility) 150#define _ST_HistoryRipple_NoisePosTurbulence_Independence UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_HistoryRipple_NoisePosTurbulence_Independence) 151#define _ST_HistoryRipple_Planar_Directional_Flexibility_Shimmer UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, DOTS_ST_HistoryRipple_Planar_Directional_Flexibility_Shimmer) 152 153#endif 154 155CBufferSpeedTree9 ReadCBuffer(bool bHistory /*must be known compile-time*/) 156{ 157 CBufferSpeedTree9 cb; 158 cb.m_vWindDirection = bHistory ? _ST_HistoryWindVector.xyz : _ST_WindVector.xyz; 159 cb.m_fWindStrength = bHistory ? _ST_HistoryWindVector.w : _ST_WindVector.w; 160 cb.m_vTreeExtents = bHistory ? _ST_HistoryTreeExtents_SharedHeightStart.xyz : _ST_TreeExtents_SharedHeightStart.xyz; 161 cb.m_fSharedHeightStart = bHistory ? _ST_HistoryTreeExtents_SharedHeightStart.w : _ST_TreeExtents_SharedHeightStart.w; 162 cb.m_fBranch1StretchLimit = bHistory ? _ST_HistoryBranchStretchLimits.x : _ST_BranchStretchLimits.x; 163 cb.m_fBranch2StretchLimit = bHistory ? _ST_HistoryBranchStretchLimits.y : _ST_BranchStretchLimits.y; 164 cb.m_fWindIndependence = bHistory ? _ST_HistoryBranchStretchLimits.z : _ST_BranchStretchLimits.z; 165 cb.m_fImportScaling = bHistory ? _ST_HistoryBranchStretchLimits.w : _ST_BranchStretchLimits.w; 166 167 // Shared Wind State 168 cb.m_sShared.m_vNoisePosTurbulence = bHistory ? _ST_HistoryShared_NoisePosTurbulence_Independence.xyz : _ST_Shared_NoisePosTurbulence_Independence.xyz; 169 cb.m_sShared.m_fIndependence = bHistory ? _ST_HistoryShared_NoisePosTurbulence_Independence.w : _ST_Shared_NoisePosTurbulence_Independence.w; 170 cb.m_sShared.m_fBend = bHistory ? _ST_HistoryShared_Bend_Oscillation_Turbulence_Flexibility.x : _ST_Shared_Bend_Oscillation_Turbulence_Flexibility.x; 171 cb.m_sShared.m_fOscillation = bHistory ? _ST_HistoryShared_Bend_Oscillation_Turbulence_Flexibility.y : _ST_Shared_Bend_Oscillation_Turbulence_Flexibility.y; 172 cb.m_sShared.m_fTurbulence = bHistory ? _ST_HistoryShared_Bend_Oscillation_Turbulence_Flexibility.z : _ST_Shared_Bend_Oscillation_Turbulence_Flexibility.z; 173 cb.m_sShared.m_fFlexibility = bHistory ? _ST_HistoryShared_Bend_Oscillation_Turbulence_Flexibility.w : _ST_Shared_Bend_Oscillation_Turbulence_Flexibility.w; 174 175 // Branch1 Wind State 176 cb.m_sBranch1.m_vNoisePosTurbulence = bHistory ? _ST_HistoryBranch1_NoisePosTurbulence_Independence.xyz : _ST_Branch1_NoisePosTurbulence_Independence.xyz; 177 cb.m_sBranch1.m_fIndependence = bHistory ? _ST_HistoryBranch1_NoisePosTurbulence_Independence.w : _ST_Branch1_NoisePosTurbulence_Independence.w; 178 cb.m_sBranch1.m_fBend = bHistory ? _ST_HistoryBranch1_Bend_Oscillation_Turbulence_Flexibility.x : _ST_Branch1_Bend_Oscillation_Turbulence_Flexibility.x; 179 cb.m_sBranch1.m_fOscillation = bHistory ? _ST_HistoryBranch1_Bend_Oscillation_Turbulence_Flexibility.y : _ST_Branch1_Bend_Oscillation_Turbulence_Flexibility.y; 180 cb.m_sBranch1.m_fTurbulence = bHistory ? _ST_HistoryBranch1_Bend_Oscillation_Turbulence_Flexibility.z : _ST_Branch1_Bend_Oscillation_Turbulence_Flexibility.z; 181 cb.m_sBranch1.m_fFlexibility = bHistory ? _ST_HistoryBranch1_Bend_Oscillation_Turbulence_Flexibility.w : _ST_Branch1_Bend_Oscillation_Turbulence_Flexibility.w; 182 183 // Branch2 Wind State 184 cb.m_sBranch2.m_vNoisePosTurbulence = bHistory ? _ST_HistoryBranch2_NoisePosTurbulence_Independence.xyz : _ST_Branch2_NoisePosTurbulence_Independence.xyz; 185 cb.m_sBranch2.m_fIndependence = bHistory ? _ST_HistoryBranch2_NoisePosTurbulence_Independence.w : _ST_Branch2_NoisePosTurbulence_Independence.w; 186 cb.m_sBranch2.m_fBend = bHistory ? _ST_HistoryBranch2_Bend_Oscillation_Turbulence_Flexibility.x : _ST_Branch2_Bend_Oscillation_Turbulence_Flexibility.x; 187 cb.m_sBranch2.m_fOscillation = bHistory ? _ST_HistoryBranch2_Bend_Oscillation_Turbulence_Flexibility.y : _ST_Branch2_Bend_Oscillation_Turbulence_Flexibility.y; 188 cb.m_sBranch2.m_fTurbulence = bHistory ? _ST_HistoryBranch2_Bend_Oscillation_Turbulence_Flexibility.z : _ST_Branch2_Bend_Oscillation_Turbulence_Flexibility.z; 189 cb.m_sBranch2.m_fFlexibility = bHistory ? _ST_HistoryBranch2_Bend_Oscillation_Turbulence_Flexibility.w : _ST_Branch2_Bend_Oscillation_Turbulence_Flexibility.w; 190 191 // Ripple Wind State 192 cb.m_sRipple.m_vNoisePosTurbulence = bHistory ? _ST_HistoryRipple_NoisePosTurbulence_Independence.xyz : _ST_Ripple_NoisePosTurbulence_Independence.xyz; 193 cb.m_sRipple.m_fIndependence = bHistory ? _ST_HistoryRipple_NoisePosTurbulence_Independence.w : _ST_Ripple_NoisePosTurbulence_Independence.w; 194 cb.m_sRipple.m_fPlanar = bHistory ? _ST_HistoryRipple_Planar_Directional_Flexibility_Shimmer.x : _ST_Ripple_Planar_Directional_Flexibility_Shimmer.x; 195 cb.m_sRipple.m_fDirectional = bHistory ? _ST_HistoryRipple_Planar_Directional_Flexibility_Shimmer.y : _ST_Ripple_Planar_Directional_Flexibility_Shimmer.y; 196 cb.m_sRipple.m_fFlexibility = bHistory ? _ST_HistoryRipple_Planar_Directional_Flexibility_Shimmer.z : _ST_Ripple_Planar_Directional_Flexibility_Shimmer.z; 197 cb.m_sRipple.m_fShimmer = bHistory ? _ST_HistoryRipple_Planar_Directional_Flexibility_Shimmer.w : _ST_Ripple_Planar_Directional_Flexibility_Shimmer.w; 198 199 cb.m_vWindDirection = TransformWindVectorFromWorldToLocalSpace(cb.m_vWindDirection); 200 return cb; 201} 202 203 204// 205// UTILS 206// 207float NoiseHash(float n) { return frac(sin(n) * 1e4); } 208float NoiseHash(float2 p){ return frac(1e4 * sin(17.0f * p.x + p.y * 0.1f) * (0.1f + abs(sin(p.y * 13.0f + p.x)))); } 209float QNoise(float2 x) 210{ 211 float2 i = floor(x); 212 float2 f = frac(x); 213 214 // four corners in 2D of a tile 215 float a = NoiseHash(i); 216 float b = NoiseHash(i + float2(1.0, 0.0)); 217 float c = NoiseHash(i + float2(0.0, 1.0)); 218 float d = NoiseHash(i + float2(1.0, 1.0)); 219 220 // same code, with the clamps in smoothstep and common subexpressions optimized away. 221 float2 u = f * f * (float2(3.0, 3.0) - float2(2.0, 2.0) * f); 222 223 return lerp(a, b, u.x) + (c - a) * u.y * (1.0f - u.x) + (d - b) * u.x * u.y; 224} 225float4 RuntimeSdkNoise2DFlat(float3 vNoisePos3d) 226{ 227 float2 vNoisePos = vNoisePos3d.xz; 228 229#ifdef USE_ST_NOISE_TEXTURE // test this toggle during shader perf tuning 230 return texture2D(g_samNoiseKernel, vNoisePos.xy) - float4(0.5f, 0.5f, 0.5f, 0.5f); 231#else 232 // fallback, slower noise lookup method 233 const float c_fFrequecyScale = 20.0f; 234 const float c_fAmplitudeScale = 1.0f; 235 const float c_fAmplitueShift = 0.0f; 236 237 float fNoiseX = (QNoise(vNoisePos * c_fFrequecyScale) + c_fAmplitueShift) * c_fAmplitudeScale; 238 float fNoiseY = (QNoise(vNoisePos.yx * 0.5f * c_fFrequecyScale) + c_fAmplitueShift) * c_fAmplitudeScale; 239 return float4(fNoiseX, fNoiseY, fNoiseX+fNoiseY, 0.0f) - 0.5f.xxxx; 240#endif 241} 242float WindUtil_Square(float fValue) { return fValue * fValue; } 243float2 WindUtil_Square(float2 fValue) { return fValue * fValue; } 244float3 WindUtil_Square(float3 fValue) { return fValue * fValue; } 245float4 WindUtil_Square(float4 fValue) { return fValue * fValue; } 246 247float3 WindUtil_UnpackNormalizedFloat(float fValue) 248{ 249 float3 vReturn = frac(float3(fValue * 0.01f, fValue, fValue * 100.0f)); 250 251 vReturn -= 0.5f; 252 vReturn *= 2.0f; 253 vReturn = normalize(vReturn); 254 return vReturn; 255} 256 257 258 259// 260// SPEEDTREE WIND 9 FUNCTIONS 261// 262 263// returns position offset (caller must apply to the vertex position) 264float3 RippleWindMotion( 265 float3 vUp, 266 float3 vWindDirection, 267 float3 vVertexPositionIn, 268 float3 vGlobalNoisePosition, 269 270 float fRippleWeight, 271 float3 vRippleNoisePosTurbulence, 272 float fRippleIndependence, 273 float fRippleFlexibility, 274 float fRippleDirectional, 275 float fRipplePlanar, 276 float fTreeHeight, 277 float fImportScaling 278) 279{ 280 float fImportScalingInv = (1.0f / fImportScaling); 281 282 float3 vNoisePosition = vGlobalNoisePosition 283 + vRippleNoisePosTurbulence 284 + (vVertexPositionIn * fImportScalingInv) * fRippleIndependence 285 + vWindDirection * fRippleFlexibility * fRippleWeight; 286 287 float2 vNoise = RuntimeSdkNoise2DFlat(vNoisePosition); 288 vNoise.r += 0.25f; 289 290 float3 vMotion = vWindDirection * vNoise.r * fRippleDirectional 291 + vUp * (vNoise.g * fRipplePlanar) 292 ; 293 vMotion *= fRippleWeight; 294 295 return vMotion; 296} 297 298float3 RippleWindMotion_cb( 299 float3 vUpVector, 300 float3 vVertexPositionIn, 301 float3 vGlobalNoisePosition, 302 float fRippleWeight, 303 in CBufferSpeedTree9 cb 304) 305{ 306 return RippleWindMotion( 307 vUpVector, 308 cb.m_vWindDirection, 309 vVertexPositionIn, 310 vGlobalNoisePosition, 311 fRippleWeight, 312 cb.m_sRipple.m_vNoisePosTurbulence, 313 cb.m_sRipple.m_fIndependence, 314 cb.m_sRipple.m_fFlexibility, 315 cb.m_sRipple.m_fDirectional, 316 cb.m_sRipple.m_fPlanar, 317 cb.m_vTreeExtents.y, // y-up = height 318 cb.m_fImportScaling 319 ); 320} 321 322 323// returns updated position 324float3 BranchWindPosition( 325 float3 vUp, 326 float3 vWindDirection, 327 float3 vVertexPositionIn, 328 float3 vGlobalNoisePosition, 329 float fPackedBranchDir, 330 float fPackedBranchNoiseOffset, 331 float fBranchWeight, 332 float fBranchStretchLimit, 333 float3 vBranchNoisePosTurbulence, 334 float fBranchIndependence, 335 float fBranchTurbulence, 336 float fBranchOscillation, 337 float fBranchBend, 338 float fBranchFlexibility, 339 float fTreeHeight, 340 float fImportScaling 341) 342{ 343 float fImportScalingInv = (1.0f / fImportScaling); 344 float fLength = fBranchWeight * fBranchStretchLimit; 345 if (fBranchWeight * fBranchStretchLimit <= 0.0f) 346 { 347 return vVertexPositionIn; 348 } 349 350 float3 vBranchDir = WindUtil_UnpackNormalizedFloat(fPackedBranchDir); 351 float3 vBranchNoiseOffset = WindUtil_UnpackNormalizedFloat(fPackedBranchNoiseOffset); 352 353 // SpeedTree Modeler packs Z up, rotate around X for -90deg 354 vBranchDir = float3(vBranchDir.x, -vBranchDir.z, vBranchDir.y); 355 vBranchNoiseOffset = float3(vBranchNoiseOffset.x, -vBranchNoiseOffset.z, vBranchNoiseOffset.y); 356 357 float3 vAnchor = vVertexPositionIn - vBranchDir * fLength; 358 vVertexPositionIn -= vAnchor; 359 360 float fBranchDotWindSq = WindUtil_Square(dot(vBranchDir, vWindDirection)); 361 float3 vWind = normalize(vWindDirection + vUp * fBranchDotWindSq); 362 363 // Undo modifications to fBranchIndependence: 364 // (1) Modeler divides fBranchIndependence by fTreeHeight before export 365 // (2) Importer scales fTreeHeight by fImportScaling during import 366 fBranchIndependence *= (fTreeHeight * fImportScalingInv); 367 368 float3 vNoisePosition = vGlobalNoisePosition 369 + vBranchNoisePosTurbulence 370 + vBranchNoiseOffset * fBranchIndependence 371 + vWind * (fBranchFlexibility * fBranchWeight); 372 373 float4 vNoise = RuntimeSdkNoise2DFlat(vNoisePosition); 374 vNoise.r *= 0.65; // tune down the 'flexy' branches 375 vNoise.g *= 0.50; // tune down the 'flexy' branches 376 377 float3 vOscillationTurbulent = vUp * fBranchTurbulence; 378 379 float3 vMotion = (vWind * vNoise.r + vOscillationTurbulent * vNoise.g) * fBranchOscillation; 380 vMotion += vWind * (fBranchBend * (1.0f - vNoise.b)); 381 vMotion *= fBranchWeight; 382 383 return normalize(vVertexPositionIn + vMotion) * fLength + vAnchor; 384} 385float3 BranchWindPosition_cb( 386 float3 vUp, 387 float3 vGlobalNoisePosition, 388 float3 vVertexPositionIn, 389 390 float fBranchWeight, 391 float fPackedBranchDir, 392 float fPackedBranchNoiseOffset, 393 in CBufferSpeedTree9 cb, 394 const int iBranch // 1 or 2, compile time constants 395) 396{ 397 if (iBranch == 1) 398 { 399 return BranchWindPosition( 400 vUp, 401 cb.m_vWindDirection, 402 vVertexPositionIn, 403 vGlobalNoisePosition, 404 fPackedBranchDir, 405 fPackedBranchNoiseOffset, 406 fBranchWeight, 407 cb.m_fBranch1StretchLimit, 408 cb.m_sBranch1.m_vNoisePosTurbulence, 409 cb.m_sBranch1.m_fIndependence, 410 cb.m_sBranch1.m_fTurbulence, 411 cb.m_sBranch1.m_fOscillation, 412 cb.m_sBranch1.m_fBend, 413 cb.m_sBranch1.m_fFlexibility, 414 cb.m_vTreeExtents.y, // y-up = height 415 cb.m_fImportScaling 416 ); 417 } 418 419 return BranchWindPosition( 420 vUp, 421 cb.m_vWindDirection, 422 vVertexPositionIn, 423 vGlobalNoisePosition, 424 fPackedBranchDir, 425 fPackedBranchNoiseOffset, 426 fBranchWeight, 427 cb.m_fBranch2StretchLimit, 428 cb.m_sBranch2.m_vNoisePosTurbulence, 429 cb.m_sBranch2.m_fIndependence, 430 cb.m_sBranch2.m_fTurbulence, 431 cb.m_sBranch2.m_fOscillation, 432 cb.m_sBranch2.m_fBend, 433 cb.m_sBranch2.m_fFlexibility, 434 cb.m_vTreeExtents.y, // y-up = height 435 cb.m_fImportScaling 436 ); 437} 438 439 440// returns updated position 441float3 SharedWindPosition( 442 float3 vUp, 443 float3 vWindDirection, 444 float3 vVertexPositionIn, 445 float3 vGlobalNoisePosition, 446 447 float fTreeHeight, 448 float fSharedHeightStart, 449 float3 vSharedNoisePosTurbulence, 450 float fSharedTurbulence, 451 float fSharedOscillation, 452 float fSharedBend, 453 float fSharedFlexibility, 454 float fImportScaling 455) 456{ 457 float fImportScalingInv = (1.0f / fImportScaling); 458 float fLengthSq = dot(vVertexPositionIn, vVertexPositionIn); 459 if (fLengthSq == 0.0f) 460 { 461 return vVertexPositionIn; 462 } 463 float fLength = sqrt(fLengthSq); 464 465 float fHeight = vVertexPositionIn.y; // y-up 466 float fMaxHeight = fTreeHeight; 467 468 float fWeight = WindUtil_Square(max(fHeight - (fMaxHeight * fSharedHeightStart), 0.0f) / fMaxHeight); 469 470 float3 vNoisePosition = vGlobalNoisePosition 471 + vSharedNoisePosTurbulence; 472 + vWindDirection * (fSharedFlexibility * fWeight); 473 474 float4 vNoise = RuntimeSdkNoise2DFlat(vNoisePosition); 475 476 float3 vOscillationTurbulent = cross(vWindDirection, vUp) * fSharedTurbulence; 477 478 float3 vMotion = (vWindDirection * vNoise.r + vOscillationTurbulent * vNoise.g) * fSharedOscillation 479 + vWindDirection * (fSharedBend * (1.0f - vNoise.b)); 480 ; 481 vMotion *= fWeight; 482 483 return normalize(vVertexPositionIn + vMotion) * fLength; 484} 485 486 487float3 SharedWindPosition_cb( 488 float3 vUp, 489 float3 vVertexPositionIn, 490 float3 vGlobalNoisePosition, 491 492 in CBufferSpeedTree9 cb 493) 494{ 495 return SharedWindPosition( 496 vUp, 497 cb.m_vWindDirection, 498 vVertexPositionIn, 499 vGlobalNoisePosition, 500 cb.m_vTreeExtents.y, // y-up = height 501 cb.m_fSharedHeightStart, 502 cb.m_sShared.m_vNoisePosTurbulence, 503 cb.m_sShared.m_fTurbulence, 504 cb.m_sShared.m_fOscillation, 505 cb.m_sShared.m_fBend, 506 cb.m_sShared.m_fFlexibility, 507 cb.m_fImportScaling 508 ); 509} 510 511 512 513//==================================================================================================== 514 515// 516// SPEEDTREE WIND 9 ENTRY 517// 518float3 SpeedTree9Wind( 519 float3 vPos, 520 float3 vNormal, 521 float4 vTexcoord , 522 float4 vTexcoord1, 523 float4 vTexcoord2, 524 float4 vTexcoord3, 525 bool bHistory 526) 527{ 528 CBufferSpeedTree9 cb = ReadCBuffer(bHistory); 529 const float fWindDirectionLengthSq = dot(cb.m_vWindDirection, cb.m_vWindDirection); 530 if (fWindDirectionLengthSq == 0.0f) // check if we have valid wind vector 531 { 532 return vPos; 533 } 534 535 float3 vUp = float3(0.0, 1.0, 0.0); 536 float3 vWindyPosition = vPos; 537 538 // get world space sposition from the model matrix 539 float3 vWorldPosition = float3(UNITY_MATRIX_M[0].w, UNITY_MATRIX_M[1].w, UNITY_MATRIX_M[2].w); 540#if SHADEROPTIONS_CAMERA_RELATIVE_RENDERING // HDRP has camera translation encoded in the matrix 541 vWorldPosition += _WorldSpaceCameraPos; 542#endif 543 544 // global noise applied to animation instances to break off synchronized 545 // movement among multiple instances under wind effect. 546 float3 vGlobalNoisePosition = vWorldPosition * cb.m_fWindIndependence; 547 548 #if defined(_WIND_RIPPLE) 549 { 550 float fRippleWeight = vTexcoord1.w; 551 float3 vMotion = RippleWindMotion_cb( 552 vUp, 553 vWindyPosition, 554 vGlobalNoisePosition, 555 fRippleWeight, 556 cb 557 ); 558 vWindyPosition += vMotion; 559 560 #if defined(_WIND_SHIMMER) 561 { 562 vNormal = normalize(vNormal - (vMotion * cb.m_sRipple.m_fShimmer)); 563 } 564 #endif 565 } 566 #endif 567 568 #if defined(_WIND_BRANCH2) 569 { 570 const int BRANCH2 = 2; 571 float fBranch2Weight = vTexcoord2.z; 572 float fPackedBranch2Dir = vTexcoord2.y; 573 float fPackedBranch2NoiseOffset = vTexcoord2.x; 574 vWindyPosition = BranchWindPosition_cb( 575 vUp, 576 vGlobalNoisePosition, 577 vWindyPosition, 578 579 fBranch2Weight, 580 fPackedBranch2Dir, 581 fPackedBranch2NoiseOffset, 582 cb, 583 BRANCH2 584 ); 585 } 586 #endif 587 588 #if defined(_WIND_BRANCH1) 589 { 590 const int BRANCH1 = 1; 591 float fBranch1Weight = vTexcoord1.z; 592 float fPackedBranch1Dir = vTexcoord.w; 593 float fPackedBranch1NoiseOffset = vTexcoord.z; 594 vWindyPosition = BranchWindPosition_cb( 595 vUp, 596 vGlobalNoisePosition, 597 vWindyPosition, 598 599 fBranch1Weight, 600 fPackedBranch1Dir, 601 fPackedBranch1NoiseOffset, 602 cb, 603 BRANCH1 604 ); 605 } 606 #endif 607 608 #if defined(_WIND_SHARED) 609 { 610 vWindyPosition = SharedWindPosition_cb( 611 vUp, 612 vWindyPosition, 613 vGlobalNoisePosition, 614 cb 615 ); 616 } 617 #endif 618 619 return vWindyPosition; 620} 621 622// This version is used by ShaderGraph 623void SpeedTree9Wind_float( 624 // in 625 float3 vPos, 626 float3 vNormal, 627 float4 vTexcoord0, 628 float4 vTexcoord1, 629 float4 vTexcoord2, 630 float4 vTexcoord3, 631 bool bHistory, 632 633 // out 634 out float3 outPos 635) 636{ 637 outPos = SpeedTree9Wind( 638 vPos, 639 vNormal, 640 vTexcoord0, 641 vTexcoord1, 642 vTexcoord2, 643 vTexcoord3, 644 bHistory 645 ); 646} 647 648#endif // SPEEDTREE_WIND_9_INCLUDED