CTI URP SG Billboard.hlsl 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. CBUFFER_START(UnityBillboardPerCamera)
  2. float3 unity_BillboardNormal;
  3. float3 unity_BillboardTangent;
  4. float4 unity_BillboardCameraParams;
  5. #define unity_BillboardCameraPosition (unity_BillboardCameraParams.xyz)
  6. #define unity_BillboardCameraXZAngle (unity_BillboardCameraParams.w)
  7. CBUFFER_END
  8. CBUFFER_START(UnityBillboardPerBatch)
  9. float3 unity_BillboardSize;
  10. CBUFFER_END
  11. //float4 _LightDirection;
  12. float4 _CTI_SRP_Wind;
  13. float _CTI_SRP_Turbulence;
  14. #if defined(_PARALLAXMAP)
  15. float2 _CTI_TransFade;
  16. #endif
  17. float4 SmoothCurve(float4 x) {
  18. return x * x * (3.0 - 2.0 * x);
  19. }
  20. float4 TriangleWave(float4 x) {
  21. return abs(frac(x + 0.5) * 2.0 - 1.0);
  22. }
  23. float4 AfsSmoothTriangleWave(float4 x) {
  24. return (SmoothCurve(TriangleWave(x)) - 0.5) * 2.0;
  25. }
  26. #define UNITY_PI 3.1415927f
  27. // Billboard Vertex Function
  28. void CTI_BillboardVert_float (
  29. float3 positionOS,
  30. float2 texcoord,
  31. float3 texcoord1,
  32. float3 lightDir,
  33. out float3 o_positionOS,
  34. out half3 o_normalOS,
  35. out half3 o_tangentOS,
  36. out float4 o_UvColorVariationStipple // These contain UVs -> float
  37. )
  38. {
  39. float3 position = positionOS;
  40. float3 worldPos = positionOS.xyz + UNITY_MATRIX_M._m03_m13_m23;
  41. o_UvColorVariationStipple = 0;
  42. // Store Color Variation
  43. float3 TreeWorldPos = abs(worldPos.xyz * 0.125f);
  44. o_UvColorVariationStipple.z = saturate((frac(TreeWorldPos.x + TreeWorldPos.y + TreeWorldPos.z) + frac((TreeWorldPos.x + TreeWorldPos.y + TreeWorldPos.z) * 3.3)) * 0.5);
  45. // #if defined(_PARALLAXMAP)
  46. // float3 distVec = _WorldSpaceCameraPos - worldPos;
  47. // float distSq = dot(distVec, distVec);
  48. // o_UvColorVariationStipple.w = saturate( (_CTI_TransFade.x - distSq) / _CTI_TransFade.y);
  49. // #endif
  50. // ////////////////////////////////////
  51. // Set vertex position
  52. // #if (SHADERPASS == SHADERPASS_SHADOWCASTER)
  53. // float3 eyeVec = -lightDir; //normalize(GetCurrentViewPosition() - worldPos);
  54. // #else
  55. // float3 eyeVec = normalize(_WorldSpaceCameraPos - worldPos);
  56. // #endif
  57. float3 eyeVec = normalize(unity_BillboardCameraPosition - worldPos);
  58. float3 billboardTangent = normalize(float3(-eyeVec.z, 0, eyeVec.x));
  59. float3 billboardNormal = float3(billboardTangent.z, 0, -billboardTangent.x); // cross({0,1,0},billboardTangent)
  60. float2 percent = texcoord.xy;
  61. float3 billboardPos = (percent.x - 0.5) * unity_BillboardSize.x * texcoord1.x * billboardTangent;
  62. //billboardPos.y += (percent.y * unity_BillboardSize.y * 2.0 + unity_BillboardSize.z) * v.texcoord1.y;
  63. // nope: not y * 2 other wise billbords get culled too early: double the height in the bb asset!
  64. billboardPos.y += (percent.y * unity_BillboardSize.y * _BillboardScale + unity_BillboardSize.z) * texcoord1.y;
  65. // Wind
  66. // Make sure we apply it in "object space" (use billboardPos)
  67. //#if defined(_EMISSION)
  68. float origLength = length(billboardPos);
  69. worldPos.xyz = abs(worldPos.xyz * 0.125f);
  70. float sinuswave = _SinTime.z;
  71. float4 vOscillations = AfsSmoothTriangleWave(float4(worldPos.x + sinuswave, worldPos.z + sinuswave * 0.8, 0.0, 0.0));
  72. float fOsc = vOscillations.x + (vOscillations.y * vOscillations.y);
  73. fOsc = 0.75 + (fOsc + 3.33) * 0.33;
  74. // saturate added to stop warning on dx11...
  75. float percentage = pow(saturate(percent.y), 1.5); // pow(y,1.5) matches the wind baked to the mesh trees
  76. billboardPos.xyz += _CTI_SRP_Wind.w * _CTI_SRP_Wind.xyz * _WindStrength * fOsc * percentage;
  77. billboardPos = normalize(billboardPos) * origLength;
  78. //#endif
  79. // Now bring it to the proper position
  80. position.xyz += billboardPos;
  81. o_positionOS.xyz = position.xyz;
  82. // ////////////////////////////////////
  83. // Get billboard texture coords
  84. float angle = atan2(billboardNormal.z, billboardNormal.x); // signed angle between billboardNormal to {0,0,1}
  85. angle += angle < 0 ? 2 * UNITY_PI : 0;
  86. // Set Rotation
  87. angle += texcoord1.z;
  88. // Write final billboard texture coords
  89. const float invDelta = 1.0 / (45.0 * ((UNITY_PI * 2.0) / 360.0));
  90. float imageIndex = fmod(floor(angle * invDelta + 0.5f), 8);
  91. float2 column_row;
  92. column_row.x = imageIndex * 0.25; // we do not care about the horizontal coord that much as our billboard texture tiles
  93. column_row.y = saturate(4 - imageIndex) * 0.5;
  94. o_UvColorVariationStipple.xy = column_row + texcoord.xy * float2(0.25, 0.5);
  95. // ////////////////////////////////////
  96. // Set Normal and Tangent
  97. o_normalOS = billboardNormal.xyz;
  98. // We have to fix normalTS in pixel shader as up is flipped!?
  99. o_tangentOS = billboardTangent.xyz;
  100. }