CTI URP Bending.hlsl 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. float4 _CTI_SRP_Wind;
  2. float _CTI_SRP_Turbulence;
  3. float4 SmoothCurve( float4 x ) {
  4. return x * x *( 3.0 - 2.0 * x );
  5. }
  6. float4 TriangleWave( float4 x ) {
  7. return abs( frac( x + 0.5 ) * 2.0 - 1.0 );
  8. }
  9. float4 SmoothTriangleWave( float4 x ) {
  10. return SmoothCurve( TriangleWave( x ) );
  11. }
  12. // Overlaods for single float
  13. float SmoothCurve( float x ) {
  14. return x * x *( 3.0 - 2.0 * x );
  15. }
  16. float TriangleWave( float x ) {
  17. return abs( frac( x + 0.5 ) * 2.0 - 1.0 );
  18. }
  19. float SmoothTriangleWave( float x ) {
  20. return SmoothCurve( TriangleWave( x ) );
  21. }
  22. half3 CTI_UnpackScaleNormal(half4 packednormal, half bumpScale)
  23. {
  24. half3 normal;
  25. normal.xy = (packednormal.wy * 2 - 1);
  26. #if (SHADER_TARGET >= 30)
  27. // SM2.0: instruction count limitation
  28. // SM2.0: normal scaler is not supported
  29. normal.xy *= bumpScale;
  30. #endif
  31. normal.z = sqrt(1.0f - saturate(dot(normal.xy, normal.xy)));
  32. return normal;
  33. }
  34. float4 AfsSmoothTriangleWave( float4 x ) {
  35. return (SmoothCurve( TriangleWave( x )) - 0.5f) * 2.0f;
  36. }
  37. // see http://www.neilmendoza.com/glsl-rotation-about-an-arbitrary-axis/
  38. // 13fps
  39. float3x3 AfsRotationMatrix(float3 axis, float angle)
  40. {
  41. //axis = normalize(axis); // moved to calling function
  42. float s = sin(angle);
  43. float c = cos(angle);
  44. float oc = 1.0f - c;
  45. return float3x3 ( oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s,
  46. oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s,
  47. oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c);
  48. }
  49. void CTI_AnimateVertex( inout Attributes v, float4 animParams, float3 baseWindMultipliers) {
  50. // animParams.x = branch phase
  51. // animParams.y = edge flutter factor
  52. // animParams.z = primary factor UV2.x
  53. // animParams.w = secondary factor UV2.y
  54. float fDetailAmp = 0.1f;
  55. float fBranchAmp = 0.3f;
  56. // float3 TreeWorldPos = float3(unity_ObjectToWorld[0].w, unity_ObjectToWorld[1].w, unity_ObjectToWorld[2].w);
  57. float3 TreeWorldPos = UNITY_MATRIX_M._m03_m13_m23; //SHADERGRAPH_OBJECT_POSITION; //float3(UNITY_MATRIX_M[0].w, UNITY_MATRIX_M[1].w, UNITY_MATRIX_M[2].w);
  58. TreeWorldPos.xyz = abs(TreeWorldPos.xyz * 0.125f);
  59. float sinuswave = _SinTime.z;
  60. //#if defined (_LEAFTUMBLING)
  61. // float shiftedsinuswave = sin(_Time.y * 0.5 + _TimeOffset);
  62. // float4 vOscillations = AfsSmoothTriangleWave(float4(TreeWorldPos.x + sinuswave, TreeWorldPos.z + sinuswave * 0.7, TreeWorldPos.x + shiftedsinuswave, TreeWorldPos.z + shiftedsinuswave * 0.8));
  63. //#else
  64. float4 vOscillations = AfsSmoothTriangleWave(float4(TreeWorldPos.x + sinuswave, TreeWorldPos.z + sinuswave * 0.7, 0.0, 0.0));
  65. //#endif
  66. // x used for main wind bending / y used for tumbling
  67. float2 fOsc = vOscillations.xz + (vOscillations.yw * vOscillations.yw);
  68. fOsc = 0.75 + (fOsc + 3.33) * 0.33;
  69. // cti: float fObjPhase = abs ( frac( (TreeWorldPos.x + TreeWorldPos.z) * 0.5 ) * 2 - 1 );
  70. float fObjPhase = dot(TreeWorldPos, 1);
  71. float fBranchPhase = fObjPhase + animParams.x; // * 3.3;
  72. float fVtxPhase = dot(v.positionOS.xyz, animParams.y + fBranchPhase);
  73. // x is used for edges; y is used for branches
  74. float2 vWavesIn = _Time.yy + float2(fVtxPhase, fBranchPhase );
  75. // 1.975, 0.793, 0.375, 0.193 are good frequencies
  76. float4 vWaves = (frac( vWavesIn.xxyy * float4(1.975, 0.793, 0.375, 0.193) ) * 2.0 - 1.0);
  77. vWaves = SmoothTriangleWave( vWaves );
  78. float2 vWavesSum = vWaves.xz + vWaves.yw;
  79. // --------------
  80. // Get local Wind
  81. float4 xWind = _CTI_SRP_Wind;
  82. xWind.xyz = mul(GetWorldToObjectMatrix(), float4(xWind.xyz, 0)).xyz;
  83. // Animate Wind
  84. xWind.w *= fOsc.x;
  85. // New in URP 12: Break up wind input - just a bit.
  86. xWind.w += xWind.w * (fOsc.x * 0.1 + frac(fObjPhase) * 0.25);
  87. // New in URP 12: Break up wind direction (and strength) over time.
  88. float offsetWind = (vOscillations.x + vOscillations.y + vOscillations.z) * _WindVariation;
  89. xWind.xz += xWind.w * float2( offsetWind, -offsetWind);
  90. animParams.zwy *= baseWindMultipliers.xyz;
  91. // --------------
  92. #if defined(CTILEAVES)
  93. // Decode UV3
  94. float3 pivot;
  95. // 15bit compression 2 components only, important: sign of y
  96. pivot.xz = (frac(float2(1.0f, 32768.0f) * v.texcoord2.xx) * 2) - 1;
  97. pivot.y = sqrt(1 - saturate(dot(pivot.xz, pivot.xz)));
  98. pivot *= v.texcoord2.y;
  99. // Move point to 0,0,0
  100. v.positionOS.xyz -= pivot;
  101. // Tumbling
  102. #if defined(_LEAFTUMBLING) || defined (_LEAFTURBULENCE)
  103. real3 fracs = frac( pivot * 33.3 ); //fBranchPhase * 0.1); // + pos.w
  104. real offset = fracs.x + fracs.y + fracs.z;
  105. real tFrequency = _TumbleFrequency * (_Time.y + fObjPhase * 10.0 );
  106. real4 vWaves1 = SmoothTriangleWave( real4( (tFrequency + offset) * (1.0 + offset * 0.25), tFrequency * 0.75 + offset, tFrequency * 0.5 + offset, tFrequency * 1.5 + offset));
  107. #define packedBranchAxis v.texcoord2.z
  108. #define windDir xWind.xyz
  109. #define absWindStrength xWind.w
  110. //#if defined (_EMISSION)
  111. // This was the root of the fern issue: branchAxes slightly varied on different LODs!
  112. real3 branchAxis = frac( packedBranchAxis * float3(1.0f, 256.0f, 65536.0f) );
  113. branchAxis = branchAxis * 2.0 - 1.0;
  114. branchAxis = normalize(branchAxis);
  115. // we can do better in case we have the baked branch main axis
  116. real facingWind = (dot(branchAxis, windDir));
  117. //#else
  118. // half facingWind = (dot(normalize(float3(v.positionOS.x, 0, v.positionOS.z)), windDir)); //saturate
  119. //#endif
  120. real3 windTangent = real3(-windDir.z, windDir.y, windDir.x);
  121. real twigPhase = vWaves1.x + vWaves1.y + (vWaves1.z * vWaves1.z);
  122. //float windStrength = dot(abs(xWind.xyz), 1) * tumbleInfluence * (1.35 - facingWind) * xWind.w + absWindStrength; // Use abs(_Wind)!!!!!!
  123. half tumbleInfluence = frac(v.color.b * 2.0h);
  124. half windStrength = (1.35h - facingWind) * tumbleInfluence * xWind.w;
  125. // turbulence
  126. #if defined (_LEAFTURBULENCE)
  127. float angleTurbulence =
  128. // center rotation so the leaves rotate leftwards as well as rightwards according to the incoming waves
  129. // ((twigPhase + vWaves1.w + fBranchPhase) * 0.2 - 0.5) // not so good to add fBranchPhase here...
  130. ((twigPhase + vWaves1.w ) * 0.25 - 0.5)
  131. // make rotation strength depend on absWindStrength and all other inputs
  132. * 4.0 * absWindStrength * _LeafTurbulence * tumbleInfluence * (0.5 + animParams.w) * saturate(lerp(1.0, animParams.y * 8, _EdgeFlutterInfluence))
  133. ;
  134. float3x3 turbulenceRot = AfsRotationMatrix( -branchAxis, angleTurbulence);
  135. v.positionOS.xyz = mul( turbulenceRot, v.positionOS.xyz);
  136. #if defined(_NORMALROTATION)
  137. v.normalOS = mul(turbulenceRot, v.normalOS);
  138. #endif
  139. #endif
  140. #if defined(_LEAFTUMBLING)
  141. //float angleTumble = ( windStrength * (twigPhase + fBranchPhase * 0.25) * _TumbleStrength * tumbleInfluence); // * fOsc.y );
  142. float angleTumble = _TumbleStrength * tumbleInfluence * windStrength * (twigPhase) ;
  143. float3x3 tumbleRot = AfsRotationMatrix( windTangent, angleTumble);
  144. v.positionOS.xyz = mul(tumbleRot, v.positionOS.xyz);
  145. #if defined(_NORMALROTATION)
  146. v.normalOS = mul(tumbleRot, v.normalOS);
  147. #endif
  148. #endif
  149. #endif
  150. // fade in/out leave planes
  151. #if defined(LOD_FADE_PERCENTAGE)
  152. real lodfade = (v.color.b > 0.5) ? 1 : 0;
  153. if (lodfade) {
  154. v.positionOS.xyz *= 1.0 - unity_LODFade.x;
  155. }
  156. #endif
  157. // Move point back to origin
  158. v.positionOS.xyz += pivot;
  159. #endif
  160. // --------------
  161. // Preserve Length
  162. float origLength = length(v.positionOS.xyz);
  163. // Primary bending / Displace position
  164. v.positionOS.xyz += animParams.z * xWind.xyz * xWind.w ;
  165. #if defined(_NORMALIZEBRANCH)
  166. // Preserve Length - good here but stretches real branches
  167. v.positionOS.xyz = normalize(v.positionOS.xyz) * origLength;
  168. #endif
  169. float3 bend = animParams.y * fDetailAmp * abs(v.normalOS.xyz);
  170. bend.y = animParams.w * fBranchAmp;
  171. // Apply secondary bending and edge flutter
  172. v.positionOS.xyz += ((vWavesSum.xyx * bend) + (xWind.xyz * vWavesSum.y * animParams.w)) * xWind.w * _CTI_SRP_Turbulence;
  173. #if !defined(_NORMALIZEBRANCH)
  174. // Preserve Length - good here but stretches real branches
  175. v.positionOS.xyz = normalize(v.positionOS.xyz) * origLength;
  176. #endif
  177. // Store Variation
  178. #if !defined(SHADOWSONLYPASS) && !defined(DEPTHONLYPASS) && !defined(DEPTHNORMALPASS)
  179. v.color.r = saturate ( ( frac(TreeWorldPos.x + TreeWorldPos.y + TreeWorldPos.z) + frac( (TreeWorldPos.x + TreeWorldPos.y + TreeWorldPos.z) * 3.3 ) ) * 0.5 );
  180. #endif
  181. }