cylinders.frag.ts 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /**
  2. * Copyright (c) 2020-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  5. */
  6. export const cylinders_frag = `
  7. precision highp float;
  8. precision highp int;
  9. #define bumpEnabled
  10. uniform mat4 uView;
  11. varying mat4 vTransform;
  12. varying vec3 vStart;
  13. varying vec3 vEnd;
  14. varying float vSize;
  15. varying float vCap;
  16. uniform vec3 uCameraDir;
  17. uniform vec3 uCameraPosition;
  18. uniform mat4 uInvView;
  19. #include common
  20. #include common_frag_params
  21. #include color_frag_params
  22. #include light_frag_params
  23. #include common_clip
  24. // adapted from https://www.shadertoy.com/view/4lcSRn
  25. // The MIT License, Copyright 2016 Inigo Quilez
  26. bool CylinderImpostor(
  27. in vec3 rayOrigin, in vec3 rayDir,
  28. in vec3 start, in vec3 end, in float radius,
  29. out vec4 intersection, out bool interior
  30. ){
  31. vec3 ba = end - start;
  32. vec3 oc = rayOrigin - start;
  33. float baba = dot(ba, ba);
  34. float bard = dot(ba, rayDir);
  35. float baoc = dot(ba, oc);
  36. float k2 = baba - bard*bard;
  37. float k1 = baba * dot(oc, rayDir) - baoc * bard;
  38. float k0 = baba * dot(oc, oc) - baoc * baoc - radius * radius * baba;
  39. float h = k1 * k1 - k2 * k0;
  40. if (h < 0.0) return false;
  41. bool topCap = (vCap > 0.9 && vCap < 1.1) || vCap >= 2.9;
  42. bool bottomCap = (vCap > 1.9 && vCap < 2.1) || vCap >= 2.9;
  43. // body outside
  44. h = sqrt(h);
  45. float t = (-k1 - h) / k2;
  46. float y = baoc + t * bard;
  47. if (y > 0.0 && y < baba) {
  48. interior = false;
  49. intersection = vec4(t, (oc + t * rayDir - ba * y / baba) / radius);
  50. return true;
  51. }
  52. if (topCap && y < 0.0) {
  53. // top cap
  54. t = -baoc / bard;
  55. if (abs(k1 + k2 * t) < h) {
  56. interior = false;
  57. intersection = vec4(t, ba * sign(y) / baba);
  58. return true;
  59. }
  60. } else if(bottomCap && y >= 0.0) {
  61. // bottom cap
  62. t = (baba - baoc) / bard;
  63. if (abs(k1 + k2 * t) < h) {
  64. interior = false;
  65. intersection = vec4(t, ba * sign(y) / baba);
  66. return true;
  67. }
  68. }
  69. if (uDoubleSided) {
  70. // body inside
  71. h = -h;
  72. t = (-k1 - h) / k2;
  73. y = baoc + t * bard;
  74. if (y > 0.0 && y < baba) {
  75. interior = true;
  76. intersection = vec4(t, (oc + t * rayDir - ba * y / baba) / radius);
  77. return true;
  78. }
  79. // TODO: handle inside caps???
  80. }
  81. return false;
  82. }
  83. void main() {
  84. #include clip_pixel
  85. vec3 rayDir = mix(normalize(vModelPosition - uCameraPosition), uCameraDir, uIsOrtho);
  86. vec4 intersection;
  87. bool interior;
  88. bool hit = CylinderImpostor(vModelPosition, rayDir, vStart, vEnd, vSize, intersection, interior);
  89. if (!hit) discard;
  90. vec3 vViewPosition = vModelPosition + intersection.x * rayDir;
  91. vViewPosition = (uView * vec4(vViewPosition, 1.0)).xyz;
  92. float fragmentDepth = calcDepth(vViewPosition);
  93. if (fragmentDepth < 0.0) discard;
  94. if (fragmentDepth > 1.0) discard;
  95. gl_FragDepthEXT = fragmentDepth;
  96. vec3 vModelPosition = (uInvView * vec4(vViewPosition, 1.0)).xyz;
  97. #include assign_material_color
  98. #if defined(dRenderVariant_pick)
  99. #include check_picking_alpha
  100. #ifdef requiredDrawBuffers
  101. gl_FragColor = vObject;
  102. gl_FragData[1] = vInstance;
  103. gl_FragData[2] = vGroup;
  104. gl_FragData[3] = packDepthToRGBA(fragmentDepth);
  105. #else
  106. gl_FragColor = vColor;
  107. #endif
  108. #elif defined(dRenderVariant_depth)
  109. gl_FragColor = material;
  110. #elif defined(dRenderVariant_marking)
  111. gl_FragColor = material;
  112. #elif defined(dRenderVariant_color)
  113. mat3 normalMatrix = transpose3(inverse3(mat3(uView)));
  114. vec3 normal = normalize(normalMatrix * -normalize(intersection.yzw));
  115. #include apply_light_color
  116. #include apply_interior_color
  117. #include apply_marker_color
  118. #include apply_fog
  119. #include wboit_write
  120. #include dpoit_write
  121. #endif
  122. }
  123. `;