lines.vert.ts 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. /**
  2. * Copyright (c) 2018-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  5. *
  6. * heavily based on code by WestLangley from https://github.com/WestLangley/three.js/blob/af28b2fb706ac109771ecad0a7447fad90ab3210/examples/js/lines/LineMaterial.js
  7. */
  8. export const lines_vert = `
  9. precision highp float;
  10. precision highp int;
  11. #include common
  12. #include read_from_texture
  13. #include common_vert_params
  14. #include color_vert_params
  15. #include size_vert_params
  16. #include common_clip
  17. uniform float uPixelRatio;
  18. uniform vec4 uViewport;
  19. attribute mat4 aTransform;
  20. attribute float aInstance;
  21. attribute float aGroup;
  22. attribute vec2 aMapping;
  23. attribute vec3 aStart;
  24. attribute vec3 aEnd;
  25. void trimSegment(const in vec4 start, inout vec4 end) {
  26. // trim end segment so it terminates between the camera plane and the near plane
  27. // conservative estimate of the near plane
  28. float a = uProjection[2][2]; // 3rd entry in 3rd column
  29. float b = uProjection[3][2]; // 3rd entry in 4th column
  30. float nearEstimate = -0.5 * b / a;
  31. float alpha = (nearEstimate - start.z) / (end.z - start.z);
  32. end.xyz = mix(start.xyz, end.xyz, alpha);
  33. }
  34. void main(){
  35. float aspect = uViewport.z / uViewport.w;
  36. #include assign_group
  37. #include assign_color_varying
  38. #include assign_marker_varying
  39. #include assign_clipping_varying
  40. #include assign_size
  41. mat4 modelView = uView * uModel * aTransform;
  42. // camera space
  43. vec4 start = modelView * vec4(aStart, 1.0);
  44. vec4 end = modelView * vec4(aEnd, 1.0);
  45. // assign position
  46. vec4 position4 = vec4((aMapping.y < 0.5) ? aStart : aEnd, 1.0);
  47. vec4 mvPosition = modelView * position4;
  48. vViewPosition = mvPosition.xyz;
  49. vModelPosition = (uModel * aTransform * position4).xyz; // for clipping in frag shader
  50. // special case for perspective projection, and segments that terminate either in, or behind, the camera plane
  51. // clearly the gpu firmware has a way of addressing this issue when projecting into ndc space
  52. // but we need to perform ndc-space calculations in the shader, so we must address this issue directly
  53. // perhaps there is a more elegant solution -- WestLangley
  54. bool perspective = (uProjection[2][3] == -1.0); // 4th entry in the 3rd column
  55. if (perspective) {
  56. if (start.z < 0.0 && end.z >= 0.0) {
  57. trimSegment(start, end);
  58. } else if (end.z < 0.0 && start.z >= 0.0) {
  59. trimSegment(end, start);
  60. }
  61. }
  62. // clip space
  63. vec4 clipStart = uProjection * start;
  64. vec4 clipEnd = uProjection * end;
  65. // ndc space
  66. vec2 ndcStart = clipStart.xy / clipStart.w;
  67. vec2 ndcEnd = clipEnd.xy / clipEnd.w;
  68. // direction
  69. vec2 dir = ndcEnd - ndcStart;
  70. // account for clip-space aspect ratio
  71. dir.x *= aspect;
  72. dir = normalize(dir);
  73. // perpendicular to dir
  74. vec2 offset = vec2(dir.y, - dir.x);
  75. // undo aspect ratio adjustment
  76. dir.x /= aspect;
  77. offset.x /= aspect;
  78. // sign flip
  79. if (aMapping.x < 0.0) offset *= -1.0;
  80. // calculate linewidth
  81. float linewidth;
  82. #ifdef dLineSizeAttenuation
  83. linewidth = size * uPixelRatio * ((uViewport.w / 2.0) / -start.z) * 5.0;
  84. #else
  85. linewidth = size * uPixelRatio;
  86. #endif
  87. linewidth = max(1.0, linewidth);
  88. // adjust for linewidth
  89. offset *= linewidth;
  90. // adjust for clip-space to screen-space conversion
  91. offset /= uViewport.w;
  92. // select end
  93. vec4 clip = (aMapping.y < 0.5) ? clipStart : clipEnd;
  94. // back to clip space
  95. offset *= clip.w;
  96. clip.xy += offset;
  97. gl_Position = clip;
  98. #include clip_instance
  99. }
  100. `;