CTI URP SG Bending.hlsl 9.7 KB

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