You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

148 lines
4.3 KiB

5 years ago
  1. #ifndef SPEEDTREE_VERTEX_INCLUDED
  2. #define SPEEDTREE_VERTEX_INCLUDED
  3. ///////////////////////////////////////////////////////////////////////
  4. // SpeedTree v6 Vertex Processing
  5. ///////////////////////////////////////////////////////////////////////
  6. // struct SpeedTreeVB
  7. // texcoord setup
  8. //
  9. // BRANCHES FRONDS LEAVES
  10. // 0 diffuse uv, branch wind xy " "
  11. // 1 lod xyz, 0 lod xyz, 0 anchor xyz, lod scalar
  12. // 2 detail/seam uv, seam amount, 0 frond wind xyz, 0 leaf wind xyz, leaf group
  13. struct SpeedTreeVB
  14. {
  15. float4 vertex : POSITION;
  16. float4 tangent : TANGENT;
  17. float3 normal : NORMAL;
  18. float4 texcoord : TEXCOORD0;
  19. float4 texcoord1 : TEXCOORD1;
  20. float4 texcoord2 : TEXCOORD2;
  21. float2 texcoord3 : TEXCOORD3;
  22. half4 color : COLOR;
  23. UNITY_VERTEX_INPUT_INSTANCE_ID
  24. };
  25. ///////////////////////////////////////////////////////////////////////
  26. // SpeedTree winds
  27. #ifdef ENABLE_WIND
  28. #define WIND_QUALITY_NONE 0
  29. #define WIND_QUALITY_FASTEST 1
  30. #define WIND_QUALITY_FAST 2
  31. #define WIND_QUALITY_BETTER 3
  32. #define WIND_QUALITY_BEST 4
  33. #define WIND_QUALITY_PALM 5
  34. uniform half _WindQuality;
  35. uniform half _WindEnabled;
  36. #include "SpeedTreeWind.cginc"
  37. #endif
  38. ///////////////////////////////////////////////////////////////////////
  39. // OffsetSpeedTreeVertex
  40. void OffsetSpeedTreeVertex(inout SpeedTreeVB data, float lodValue)
  41. {
  42. float3 finalPosition = data.vertex.xyz;
  43. #ifdef ENABLE_WIND
  44. half windQuality = _WindQuality * _WindEnabled;
  45. float3 rotatedWindVector, rotatedBranchAnchor;
  46. if (windQuality <= WIND_QUALITY_NONE)
  47. {
  48. rotatedWindVector = float3(0.0f, 0.0f, 0.0f);
  49. rotatedBranchAnchor = float3(0.0f, 0.0f, 0.0f);
  50. }
  51. else
  52. {
  53. // compute rotated wind parameters
  54. rotatedWindVector = normalize(mul(_ST_WindVector.xyz, (float3x3)unity_ObjectToWorld));
  55. rotatedBranchAnchor = normalize(mul(_ST_WindBranchAnchor.xyz, (float3x3)unity_ObjectToWorld)) * _ST_WindBranchAnchor.w;
  56. }
  57. #endif
  58. #if defined(GEOM_TYPE_BRANCH) || defined(GEOM_TYPE_FROND)
  59. // smooth LOD
  60. #ifdef LOD_FADE_PERCENTAGE
  61. finalPosition = lerp(finalPosition, data.texcoord1.xyz, lodValue);
  62. #endif
  63. // frond wind, if needed
  64. #if defined(ENABLE_WIND) && defined(GEOM_TYPE_FROND)
  65. if (windQuality == WIND_QUALITY_PALM)
  66. finalPosition = RippleFrond(finalPosition, data.normal, data.texcoord.x, data.texcoord.y, data.texcoord2.x, data.texcoord2.y, data.texcoord2.z);
  67. #endif
  68. #elif defined(GEOM_TYPE_LEAF)
  69. // remove anchor position
  70. finalPosition -= data.texcoord1.xyz;
  71. bool isFacingLeaf = data.color.a == 0;
  72. if (isFacingLeaf)
  73. {
  74. #ifdef LOD_FADE_PERCENTAGE
  75. finalPosition *= lerp(1.0, data.texcoord1.w, lodValue);
  76. #endif
  77. // face camera-facing leaf to camera
  78. float offsetLen = length(finalPosition);
  79. finalPosition = mul(finalPosition.xyz, (float3x3)UNITY_MATRIX_IT_MV); // inv(MV) * finalPosition
  80. finalPosition = normalize(finalPosition) * offsetLen; // make sure the offset vector is still scaled
  81. }
  82. else
  83. {
  84. #ifdef LOD_FADE_PERCENTAGE
  85. float3 lodPosition = float3(data.texcoord1.w, data.texcoord3.x, data.texcoord3.y);
  86. finalPosition = lerp(finalPosition, lodPosition, lodValue);
  87. #endif
  88. }
  89. #ifdef ENABLE_WIND
  90. // leaf wind
  91. if (windQuality > WIND_QUALITY_FASTEST && windQuality < WIND_QUALITY_PALM)
  92. {
  93. float leafWindTrigOffset = data.texcoord1.x + data.texcoord1.y;
  94. finalPosition = LeafWind(windQuality == WIND_QUALITY_BEST, data.texcoord2.w > 0.0, finalPosition, data.normal, data.texcoord2.x, float3(0,0,0), data.texcoord2.y, data.texcoord2.z, leafWindTrigOffset, rotatedWindVector);
  95. }
  96. #endif
  97. // move back out to anchor
  98. finalPosition += data.texcoord1.xyz;
  99. #endif
  100. #ifdef ENABLE_WIND
  101. float3 treePos = float3(unity_ObjectToWorld[0].w, unity_ObjectToWorld[1].w, unity_ObjectToWorld[2].w);
  102. #ifndef GEOM_TYPE_MESH
  103. if (windQuality >= WIND_QUALITY_BETTER)
  104. {
  105. // branch wind (applies to all 3D geometry)
  106. finalPosition = BranchWind(windQuality == WIND_QUALITY_PALM, finalPosition, treePos, float4(data.texcoord.zw, 0, 0), rotatedWindVector, rotatedBranchAnchor);
  107. }
  108. #endif
  109. if (windQuality > WIND_QUALITY_NONE)
  110. {
  111. // global wind
  112. finalPosition = GlobalWind(finalPosition, treePos, true, rotatedWindVector, _ST_WindGlobal.x);
  113. }
  114. #endif
  115. data.vertex.xyz = finalPosition;
  116. }
  117. #endif // SPEEDTREE_VERTEX_INCLUDED