common-clip.glsl.ts 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. /**
  2. * Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author Ludovic Autin <autin@scripps.edu>
  5. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  6. */
  7. export default `
  8. #if dClipObjectCount != 0
  9. vec3 quaternionTransform(vec4 q, vec3 v) {
  10. vec3 t = 2.0 * cross(q.xyz, v);
  11. return v + q.w * t + cross(q.xyz, t);
  12. }
  13. vec4 computePlane(vec3 normal, vec3 inPoint) {
  14. return vec4(normalize(normal), -dot(normal, inPoint));
  15. }
  16. float planeSD(vec4 plane, vec3 center) {
  17. return -dot(plane.xyz, center - plane.xyz * -plane.w);
  18. }
  19. float sphereSD(vec3 position, vec4 rotation, vec3 size, vec3 center) {
  20. return (
  21. length(quaternionTransform(vec4(-rotation.x, -rotation.y, -rotation.z, rotation.w), center - position) / size) - 1.0
  22. ) * min(min(size.x, size.y), size.z);
  23. }
  24. float cubeSD(vec3 position, vec4 rotation, vec3 size, vec3 center) {
  25. vec3 d = abs(quaternionTransform(vec4(-rotation.x, -rotation.y, -rotation.z, rotation.w), center - position)) - size;
  26. return min(max(d.x, max(d.y, d.z)), 0.0) + length(max(d, 0.0));
  27. }
  28. float cylinderSD(vec3 position, vec4 rotation, vec3 size, vec3 center) {
  29. vec3 t = quaternionTransform(vec4(-rotation.x, -rotation.y, -rotation.z, rotation.w), center - position);
  30. vec2 d = abs(vec2(length(t.xz), t.y)) - size.xy;
  31. return min(max(d.x, d.y), 0.0) + length(max(d, 0.0));
  32. }
  33. float infiniteConeSD(vec3 position, vec4 rotation, vec3 size, vec3 center) {
  34. vec3 t = quaternionTransform(vec4(-rotation.x, -rotation.y, -rotation.z, rotation.w), center - position);
  35. float q = length(t.xy);
  36. return dot(size.xy, vec2(q, t.z));
  37. }
  38. float getSignedDistance(vec3 center, int type, vec3 position, vec4 rotation, vec3 scale) {
  39. if (type == 1) {
  40. vec3 normal = quaternionTransform(rotation, vec3(0.0, 1.0, 0.0));
  41. vec4 plane = computePlane(normal, position);
  42. return planeSD(plane, center);
  43. } else if (type == 2) {
  44. return sphereSD(position, rotation, scale * 0.5, center);
  45. } else if (type == 3) {
  46. return cubeSD(position, rotation, scale * 0.5, center);
  47. } else if (type == 4) {
  48. return cylinderSD(position, rotation, scale * 0.5, center);
  49. } else if (type == 5) {
  50. return infiniteConeSD(position, rotation, scale * 0.5, center);
  51. } else {
  52. return 0.1;
  53. }
  54. }
  55. #if __VERSION__ != 300
  56. // 8-bit
  57. int bitwiseAnd(int a, int b) {
  58. int d = 128;
  59. int result = 0;
  60. for (int i = 0; i < 8; ++i) {
  61. if (d <= 0) break;
  62. if (a >= d && b >= d) result += d;
  63. if (a >= d) a -= d;
  64. if (b >= d) b -= d;
  65. d /= 2;
  66. }
  67. return result;
  68. }
  69. bool hasBit(int mask, int bit) {
  70. return bitwiseAnd(mask, bit) == 0;
  71. }
  72. #else
  73. bool hasBit(int mask, int bit) {
  74. return (mask & bit) == 0;
  75. }
  76. #endif
  77. // flag is a bit-flag for clip-objects to ignore (note, object ids start at 1 not 0)
  78. bool clipTest(vec4 sphere, int flag) {
  79. for (int i = 0; i < dClipObjectCount; ++i) {
  80. if (flag == 0 || hasBit(flag, i + 1)) {
  81. // TODO take sphere radius into account?
  82. if (getSignedDistance(sphere.xyz, uClipObjectType[i], uClipObjectPosition[i], uClipObjectRotation[i], uClipObjectScale[i]) <= 0.0)
  83. return true;
  84. }
  85. }
  86. return false;
  87. }
  88. #endif
  89. `;