coordinates.chunk 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. // When screenSpaceSingY and clipSpaceSignY have different signs, need to flip the uv
  2. // cc_cameraPos.w is flipNDCSign
  3. #pragma define CC_HANDLE_NDC_SAMPLE_FLIP(uv, flipNDCSign) uv = flipNDCSign == 1.0 ? vec2(uv.x, 1.0 - uv.y) : uv
  4. #if defined(CC_USE_METAL) || defined(CC_USE_WGPU)
  5. #define CC_HANDLE_SAMPLE_NDC_FLIP_STATIC(y) y = -y
  6. #else
  7. #define CC_HANDLE_SAMPLE_NDC_FLIP_STATIC(y)
  8. #endif
  9. // return 0-1
  10. vec2 GetScreenUV(vec4 clipPos, float flipNDCSign)
  11. {
  12. vec2 screenUV = clipPos.xy / clipPos.w * 0.5 + 0.5;
  13. screenUV = vec2(screenUV.x, screenUV.y);
  14. CC_HANDLE_NDC_SAMPLE_FLIP(screenUV, flipNDCSign);
  15. return screenUV;
  16. }
  17. vec2 GetScreenUV(vec3 worldPos, mat4 matViewProj, float flipNDCSign)
  18. {
  19. vec4 clipPos = matViewProj * vec4(worldPos, 1.0);
  20. return GetScreenUV(clipPos, flipNDCSign);
  21. }
  22. vec2 GetPlanarReflectScreenUV(vec3 worldPos, mat4 matVirtualCameraViewProj, float flipNDCSign, vec3 viewDir, vec3 reflectDir)
  23. {
  24. vec4 clipPos = matVirtualCameraViewProj * vec4(worldPos, 1.0);
  25. vec2 screenUV = clipPos.xy / clipPos.w * 0.5 + 0.5;
  26. screenUV = vec2(1.0 - screenUV.x, screenUV.y);
  27. CC_HANDLE_NDC_SAMPLE_FLIP(screenUV, flipNDCSign);
  28. return screenUV;
  29. }
  30. // depthHS (Z) = ndc depth(-1 ~ +1)
  31. // return camera depth (W), negative in RH
  32. float GetCameraDepthRH(float depthHS, mat4 matProj)
  33. {
  34. return -matProj[3][2] / (depthHS + matProj[2][2]);
  35. }
  36. float GetCameraDepthRH(float depthHS, float matProj32, float matProj22)
  37. {
  38. return -matProj32 / (depthHS + matProj22);
  39. }
  40. // posHS = ndc pos (xyz: -1 ~ +1)
  41. vec4 GetViewPosFromNDCPosRH(vec3 posHS, mat4 matProj, mat4 matProjInv)
  42. {
  43. float w = -GetCameraDepthRH(posHS.z, matProj);
  44. return matProjInv * vec4(posHS * w, w);
  45. }
  46. vec4 GetWorldPosFromNDCPosRH(vec3 posHS, mat4 matProj, mat4 matViewProjInv)
  47. {
  48. float w = -GetCameraDepthRH(posHS.z, matProj);
  49. return matViewProjInv * vec4(posHS * w, w);
  50. }
  51. float GetLinearDepthFromViewSpace(vec3 viewPos, float near, float far) {
  52. float dist = length(viewPos);
  53. return (dist - near) / (far - near);
  54. }
  55. // for right-hand coordinates, params must be normalized
  56. vec3 CalculateBinormal(vec3 normal, vec3 tangent, float mirrorNormal)
  57. {
  58. return cross(normal, tangent) * mirrorNormal;
  59. }
  60. vec3 CalculateTangent(vec3 normal, vec3 binormal)
  61. {
  62. return cross(binormal, normal);
  63. }
  64. vec3 CalculateNormal(vec3 tangent, vec3 binormal)
  65. {
  66. return cross(tangent, binormal);
  67. }
  68. // param1 is normal from normalmap
  69. // return value is un-normalized
  70. vec3 CalculateNormalFromTangentSpace(vec3 normalFromTangentSpace, float normalStrength, vec3 normal, vec3 tangent, float mirrorNormal)
  71. {
  72. vec3 binormal = CalculateBinormal(normal, tangent, mirrorNormal);
  73. return (normalFromTangentSpace.x * normalStrength) * normalize(tangent) +
  74. (normalFromTangentSpace.y * normalStrength) * normalize(binormal) +
  75. normalFromTangentSpace.z * normalize(normal);
  76. }
  77. vec3 RotationVecFromAxisY(vec3 v, float cosTheta, float sinTheta)
  78. {
  79. vec3 result;
  80. result.x = dot(v, vec3(cosTheta, 0.0, -sinTheta));
  81. result.y = v.y;
  82. result.z = dot(v, vec3(sinTheta, 0.0, cosTheta));
  83. return result;
  84. }
  85. vec3 RotationVecFromAxisY(vec3 v, float rotateAngleArc)
  86. {
  87. return RotationVecFromAxisY(v, cos(rotateAngleArc), sin(rotateAngleArc));
  88. }
  89. vec3 RotationVecFromAxis(vec3 v, vec3 axis, float rotateAngleArc)
  90. {
  91. float cosAngle = cos(rotateAngleArc);
  92. float sinAngle = sin(rotateAngleArc);
  93. vec3 crossProd = cross(axis, v);
  94. float dotProd = dot(axis, v);
  95. vec3 axisScaled = axis * dotProd * (1.0 - cosAngle);
  96. return v * cosAngle + crossProd * sinAngle + axisScaled;
  97. }
  98. // rotationAngle: radians, 0-2Pi
  99. void RotateTangentAndBinormal(inout vec3 tangent, inout vec3 binormal, vec3 normal, float rotationAngle)
  100. {
  101. float cosTheta = cos(rotationAngle), sinTheta = sin(rotationAngle);
  102. vec3 B = RotationVecFromAxisY(vec3(1.0, 0.0, 0.0), cosTheta, sinTheta);
  103. vec3 T = RotationVecFromAxisY(vec3(0.0, 0.0, 1.0), cosTheta, sinTheta);
  104. vec3 tangentNew, binormalNew;
  105. binormalNew = B.x * binormal + B.y * normal + B.z * tangent;
  106. binormal = normalize(binormalNew);
  107. tangentNew = T.x * binormal + T.y * normal + T.z * tangent;
  108. tangent = normalize(tangentNew);
  109. }
  110. // fast rotation for anisotropic offset
  111. // rotationAngle: -1 - +1
  112. void RotateNormalAndBinormal(inout vec3 binormal, inout vec3 normal, in vec3 tangent, float rotationAngle, float mirrorNormal)
  113. {
  114. if(rotationAngle > 0.0)
  115. {
  116. normal += (binormal - normal) * rotationAngle;
  117. normal = normalize(normal);
  118. binormal = CalculateBinormal(normal, tangent, mirrorNormal);
  119. }
  120. else if(rotationAngle < 0.0)
  121. {
  122. binormal += (binormal - normal) * rotationAngle;
  123. binormal = normalize(binormal);
  124. normal = CalculateNormal(tangent, binormal);
  125. }
  126. }