SpeedTree7Passes.hlsl 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. #ifndef UNIVERSAL_SPEEDTREE7_PASSES_INCLUDED
  2. #define UNIVERSAL_SPEEDTREE7_PASSES_INCLUDED
  3. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
  4. #include "SpeedTree7CommonPasses.hlsl"
  5. void InitializeData(inout SpeedTreeVertexInput input, float lodValue)
  6. {
  7. float3 finalPosition = input.vertex.xyz;
  8. #ifdef ENABLE_WIND
  9. half windQuality = _WindQuality * _WindEnabled;
  10. float3 rotatedWindVector, rotatedBranchAnchor;
  11. if (windQuality <= WIND_QUALITY_NONE)
  12. {
  13. rotatedWindVector = float3(0.0f, 0.0f, 0.0f);
  14. rotatedBranchAnchor = float3(0.0f, 0.0f, 0.0f);
  15. }
  16. else
  17. {
  18. // compute rotated wind parameters
  19. rotatedWindVector = normalize(mul(_ST_WindVector.xyz, (float3x3)UNITY_MATRIX_M));
  20. rotatedBranchAnchor = normalize(mul(_ST_WindBranchAnchor.xyz, (float3x3)UNITY_MATRIX_M)) * _ST_WindBranchAnchor.w;
  21. }
  22. #endif
  23. #if defined(GEOM_TYPE_BRANCH) || defined(GEOM_TYPE_FROND)
  24. // smooth LOD
  25. #ifdef LOD_FADE_PERCENTAGE
  26. finalPosition = lerp(finalPosition, input.texcoord1.xyz, lodValue);
  27. #endif
  28. // frond wind, if needed
  29. #if defined(ENABLE_WIND) && defined(GEOM_TYPE_FROND)
  30. if (windQuality == WIND_QUALITY_PALM)
  31. finalPosition = RippleFrond(finalPosition, input.normal, input.texcoord.x, input.texcoord.y, input.texcoord2.x, input.texcoord2.y, input.texcoord2.z);
  32. #endif
  33. #elif defined(GEOM_TYPE_LEAF)
  34. // remove anchor position
  35. finalPosition -= input.texcoord1.xyz;
  36. bool isFacingLeaf = input.color.a == 0;
  37. if (isFacingLeaf)
  38. {
  39. #ifdef LOD_FADE_PERCENTAGE
  40. finalPosition *= lerp(1.0, input.texcoord1.w, lodValue);
  41. #endif
  42. // face camera-facing leaf to camera
  43. float offsetLen = length(finalPosition);
  44. finalPosition = mul(finalPosition.xyz, (float3x3)UNITY_MATRIX_IT_MV); // inv(MV) * finalPosition
  45. finalPosition = normalize(finalPosition) * offsetLen; // make sure the offset vector is still scaled
  46. }
  47. else
  48. {
  49. #ifdef LOD_FADE_PERCENTAGE
  50. float3 lodPosition = float3(input.texcoord1.w, input.texcoord3.x, input.texcoord3.y);
  51. finalPosition = lerp(finalPosition, lodPosition, lodValue);
  52. #endif
  53. }
  54. #ifdef ENABLE_WIND
  55. // leaf wind
  56. if (windQuality > WIND_QUALITY_FASTEST && windQuality < WIND_QUALITY_PALM)
  57. {
  58. float leafWindTrigOffset = input.texcoord1.x + input.texcoord1.y;
  59. finalPosition = LeafWind(windQuality == WIND_QUALITY_BEST, input.texcoord2.w > 0.0, finalPosition, input.normal, input.texcoord2.x, float3(0,0,0), input.texcoord2.y, input.texcoord2.z, leafWindTrigOffset, rotatedWindVector);
  60. }
  61. #endif
  62. // move back out to anchor
  63. finalPosition += input.texcoord1.xyz;
  64. #endif
  65. #ifdef ENABLE_WIND
  66. float3 treePos = float3(UNITY_MATRIX_M[0].w, UNITY_MATRIX_M[1].w, UNITY_MATRIX_M[2].w);
  67. #ifndef GEOM_TYPE_MESH
  68. if (windQuality >= WIND_QUALITY_BETTER)
  69. {
  70. // branch wind (applies to all 3D geometry)
  71. finalPosition = BranchWind(windQuality == WIND_QUALITY_PALM, finalPosition, treePos, float4(input.texcoord.zw, 0, 0), rotatedWindVector, rotatedBranchAnchor);
  72. }
  73. #endif
  74. if (windQuality > WIND_QUALITY_NONE)
  75. {
  76. // global wind
  77. finalPosition = GlobalWind(finalPosition, treePos, true, rotatedWindVector, _ST_WindGlobal.x);
  78. }
  79. #endif
  80. input.vertex.xyz = finalPosition;
  81. }
  82. SpeedTreeVertexOutput SpeedTree7Vert(SpeedTreeVertexInput input)
  83. {
  84. SpeedTreeVertexOutput output = (SpeedTreeVertexOutput)0;
  85. UNITY_SETUP_INSTANCE_ID(input);
  86. UNITY_TRANSFER_INSTANCE_ID(input, output);
  87. UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
  88. // handle speedtree wind and lod
  89. InitializeData(input, unity_LODFade.x);
  90. #ifdef VERTEX_COLOR
  91. output.color = _Color;
  92. output.color.rgb *= input.color.r; // ambient occlusion factor
  93. #endif
  94. output.uvHueVariation.xy = input.texcoord.xy;
  95. #ifdef EFFECT_HUE_VARIATION
  96. half hueVariationAmount = frac(UNITY_MATRIX_M[0].w + UNITY_MATRIX_M[1].w + UNITY_MATRIX_M[2].w);
  97. hueVariationAmount += frac(input.vertex.x + input.normal.y + input.normal.x) * 0.5 - 0.3;
  98. output.uvHueVariation.z = saturate(hueVariationAmount * _HueVariation.a);
  99. #endif
  100. #ifdef GEOM_TYPE_BRANCH_DETAIL
  101. // The two types are always in different sub-range of the mesh so no interpolation (between detail and blend) problem.
  102. output.detail.xy = input.texcoord2.xy;
  103. output.detail.z = input.color.a == 0 ? input.texcoord2.z : 2.5; // stay out of Blend's .z range
  104. #endif
  105. VertexPositionInputs vertexInput = GetVertexPositionInputs(input.vertex.xyz);
  106. half3 normalWS = TransformObjectToWorldNormal(input.normal);
  107. half3 vertexLight = VertexLighting(vertexInput.positionWS, normalWS);
  108. half fogFactor = ComputeFogFactor(vertexInput.positionCS.z);
  109. output.fogFactorAndVertexLight = half4(fogFactor, vertexLight);
  110. half3 viewDirWS = GetCameraPositionWS() - vertexInput.positionWS;
  111. #ifdef EFFECT_BUMP
  112. real sign = input.tangent.w * GetOddNegativeScale();
  113. output.normalWS.xyz = normalWS;
  114. output.tangentWS.xyz = TransformObjectToWorldDir(input.tangent.xyz);
  115. output.bitangentWS.xyz = cross(output.normalWS.xyz, output.tangentWS.xyz) * sign;
  116. // View dir packed in w.
  117. output.normalWS.w = viewDirWS.x;
  118. output.tangentWS.w = viewDirWS.y;
  119. output.bitangentWS.w = viewDirWS.z;
  120. #else
  121. output.normalWS = normalWS;
  122. output.viewDirWS = viewDirWS;
  123. #endif
  124. #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
  125. output.shadowCoord = GetShadowCoord(vertexInput);
  126. #endif
  127. output.positionWS = vertexInput.positionWS;
  128. output.clipPos = vertexInput.positionCS;
  129. return output;
  130. }
  131. SpeedTreeVertexDepthOutput SpeedTree7VertDepth(SpeedTreeVertexInput input)
  132. {
  133. SpeedTreeVertexDepthOutput output = (SpeedTreeVertexDepthOutput)0;
  134. UNITY_SETUP_INSTANCE_ID(input);
  135. UNITY_TRANSFER_INSTANCE_ID(input, output);
  136. UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
  137. // handle speedtree wind and lod
  138. InitializeData(input, unity_LODFade.x);
  139. output.uvHueVariation.xy = input.texcoord.xy;
  140. VertexPositionInputs vertexInput = GetVertexPositionInputs(input.vertex.xyz);
  141. #ifdef SHADOW_CASTER
  142. half3 normalWS = TransformObjectToWorldNormal(input.normal);
  143. output.clipPos = TransformWorldToHClip(ApplyShadowBias(vertexInput.positionWS, normalWS, _LightDirection));
  144. #else
  145. output.clipPos = vertexInput.positionCS;
  146. #endif
  147. return output;
  148. }
  149. #endif