暫無描述
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.

SpeedTreeCommon.hlsl 5.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. // Unity built-in shader source. Copyright (c) 2023 Unity Technologies. MIT license (see license.txt)
  2. #ifndef SPEEDTREE_COMMON_INCLUDED
  3. #define SPEEDTREE_COMMON_INCLUDED
  4. float3 DoLeafFacing(float3 vPos, float3 anchor)
  5. {
  6. float3 facingPosition = vPos - anchor; // move to origin
  7. float offsetLen = length(facingPosition);
  8. // rotate X -90deg: normals keep looking 'up' while cards/leaves now 'stand up' and face the view plane
  9. facingPosition = float3(facingPosition.x, -facingPosition.z, facingPosition.y);
  10. // extract scale from model matrix
  11. float3x3 modelMatrix = (float3x3) GetObjectToWorldMatrix(); // UNITY_MATRIX_M
  12. float3 scale = float3(
  13. length(float3(modelMatrix[0][0], modelMatrix[1][0], modelMatrix[2][0])),
  14. length(float3(modelMatrix[0][1], modelMatrix[1][1], modelMatrix[2][1])),
  15. length(float3(modelMatrix[0][2], modelMatrix[1][2], modelMatrix[2][2]))
  16. );
  17. // inverse of model : discards object rotations & scale
  18. // inverse of view : discards camera rotations
  19. float3x3 modelMatrixInv = (float3x3) GetWorldToObjectMatrix(); // UNITY_MATRIX_I_M
  20. float3x3 viewMatrixInv = (float3x3) GetViewToWorldMatrix(); // UNITY_MATRIX_I_V
  21. float3x3 matCardFacingTransform = mul(modelMatrixInv, viewMatrixInv);
  22. // re-encode the scale into the final transformation (otherwise cards would look small if tree is scaled up via world transform)
  23. matCardFacingTransform[0] *= scale.x;
  24. matCardFacingTransform[1] *= scale.y;
  25. matCardFacingTransform[2] *= scale.z;
  26. // make the leaves/cards face the camera
  27. facingPosition = mul(matCardFacingTransform, facingPosition.xyz);
  28. facingPosition = normalize(facingPosition) * offsetLen; // make sure the offset vector is still scaled
  29. return facingPosition + anchor; // move back to branch
  30. }
  31. #define SPEEDTREE_SUPPORT_NON_UNIFORM_SCALING 0
  32. float3 TransformWindVectorFromWorldToLocalSpace(float3 vWindDirection)
  33. {
  34. // we intend to transform the world-space wind vector into local space.
  35. float3x3 modelMatrixInv = (float3x3) GetWorldToObjectMatrix(); // UNITY_MATRIX_I_M
  36. #if SPEEDTREE_SUPPORT_NON_UNIFORM_SCALING
  37. // the inverse world matrix would contain scale transformation as well, so we need
  38. // to get rid of scaling of the wind direction while doing inverse rotation.
  39. float3x3 modelMatrix = (float3x3) GetObjectToWorldMatrix(); // UNITY_MATRIX_M
  40. float3 scaleInv = float3(
  41. length(float3(modelMatrix[0][0], modelMatrix[1][0], modelMatrix[2][0])),
  42. length(float3(modelMatrix[0][1], modelMatrix[1][1], modelMatrix[2][1])),
  43. length(float3(modelMatrix[0][2], modelMatrix[1][2], modelMatrix[2][2]))
  44. );
  45. float3x3 matWorldToLocalSpaceRotation = float3x3( // 3x3 discards translation
  46. modelMatrixInv[0][0] * scaleInv.x, modelMatrixInv[0][1] , modelMatrixInv[0][2],
  47. modelMatrixInv[1][0] , modelMatrixInv[1][1] * scaleInv.y, modelMatrixInv[1][2],
  48. modelMatrixInv[2][0] , modelMatrixInv[2][1] , modelMatrixInv[2][2] * scaleInv.z
  49. );
  50. float3 vLocalSpaceWind = mul(matWorldToLocalSpaceRotation, vWindDirection);
  51. #else
  52. // Assume uniform scaling for the object -- discard translation and invert object rotations (and scale).
  53. // We'll normalize to get rid of scaling after the transformation.
  54. float3 vLocalSpaceWind = mul(modelMatrixInv, vWindDirection);
  55. #endif
  56. float windVecLength = length(vLocalSpaceWind);
  57. if (windVecLength > 1e-5)
  58. vLocalSpaceWind *= (1.0f / windVecLength); // normalize
  59. return vLocalSpaceWind;
  60. }
  61. #define ST_GEOM_TYPE_BRANCH 0
  62. #define ST_GEOM_TYPE_FROND 1
  63. #define ST_GEOM_TYPE_LEAF 2
  64. #define ST_GEOM_TYPE_FACINGLEAF 3
  65. int GetGeometryType(float4 uv3, out bool bLeafTwo)
  66. {
  67. int geometryType = (int) (uv3.w + 0.25);
  68. bLeafTwo = geometryType > ST_GEOM_TYPE_FACINGLEAF;
  69. if (bLeafTwo)
  70. {
  71. geometryType -= 2;
  72. }
  73. return geometryType;
  74. }
  75. // shadergraph stubs
  76. void SpeedTree8LeafFacing_float(float3 vVertexLocalPosition, float4 UV1, float4 UV2, float4 UV3, out float3 vVertexLocalPositionOut)
  77. {
  78. vVertexLocalPositionOut = vVertexLocalPosition;
  79. bool bDummy = false;
  80. if (GetGeometryType(UV3, bDummy) == ST_GEOM_TYPE_FACINGLEAF)
  81. {
  82. float3 vAnchorPosition = float3(UV1.zw, UV2.w);
  83. vVertexLocalPositionOut = DoLeafFacing(vVertexLocalPosition, vAnchorPosition);
  84. }
  85. }
  86. void SpeedTree9LeafFacing_float(float3 vVertexLocalPosition, float4 UV2, float4 UV3, out float3 vVertexLocalPositionOut)
  87. {
  88. vVertexLocalPositionOut = vVertexLocalPosition;
  89. const bool bHasCameraFacingLeaf = UV3.w > 0.0f || UV2.w > 0.0f;
  90. if (bHasCameraFacingLeaf)
  91. {
  92. const float3 vAnchorPosition = UV3.w > 0.0f ? UV3.xyz : UV2.xyz;
  93. vVertexLocalPositionOut = DoLeafFacing(vVertexLocalPosition, vAnchorPosition);
  94. }
  95. }
  96. void SpeedTreeLODTransition_float(float3 ObjectSpacePosition, float4 ObjectSpacePositionNextLOD, const bool bBillboard, out float3 OutObjectSpacePosition)
  97. {
  98. OutObjectSpacePosition = bBillboard
  99. ? ObjectSpacePosition
  100. : lerp(ObjectSpacePosition, ObjectSpacePositionNextLOD.xyz, unity_LODFade.x);
  101. }
  102. #endif // SPEEDTREE_COMMON_INCLUDED