lines.vert.ts 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /**
  2. * Copyright (c) 2018-2020 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 float uViewportHeight;
  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. #include assign_group
  36. #include assign_color_varying
  37. #include assign_marker_varying
  38. #include assign_clipping_varying
  39. #include assign_size
  40. mat4 modelView = uView * uModel * aTransform;
  41. // camera space
  42. vec4 start = modelView * vec4(aStart, 1.0);
  43. vec4 end = modelView * vec4(aEnd, 1.0);
  44. // assign position
  45. vec4 position4 = vec4((aMapping.y < 0.5) ? aStart : aEnd, 1.0);
  46. vec4 mvPosition = modelView * position4;
  47. vViewPosition = mvPosition.xyz;
  48. vModelPosition = (uModel * aTransform * position4).xyz; // for clipping in frag shader
  49. // special case for perspective projection, and segments that terminate either in, or behind, the camera plane
  50. // clearly the gpu firmware has a way of addressing this issue when projecting into ndc space
  51. // but we need to perform ndc-space calculations in the shader, so we must address this issue directly
  52. // perhaps there is a more elegant solution -- WestLangley
  53. bool perspective = (uProjection[2][3] == -1.0); // 4th entry in the 3rd column
  54. if (perspective) {
  55. if (start.z < 0.0 && end.z >= 0.0) {
  56. trimSegment(start, end);
  57. } else if (end.z < 0.0 && start.z >= 0.0) {
  58. trimSegment(end, start);
  59. }
  60. }
  61. // clip space
  62. vec4 clipStart = uProjection * start;
  63. vec4 clipEnd = uProjection * end;
  64. // ndc space
  65. vec2 ndcStart = clipStart.xy / clipStart.w;
  66. vec2 ndcEnd = clipEnd.xy / clipEnd.w;
  67. // direction
  68. vec2 dir = ndcEnd - ndcStart;
  69. // account for clip-space aspect ratio
  70. dir.x *= uPixelRatio;
  71. dir = normalize(dir);
  72. // perpendicular to dir
  73. vec2 offset = vec2(dir.y, - dir.x);
  74. // undo aspect ratio adjustment
  75. dir.x /= uPixelRatio;
  76. offset.x /= uPixelRatio;
  77. // sign flip
  78. if (aMapping.x < 0.0) offset *= -1.0;
  79. // calculate linewidth
  80. float linewidth;
  81. #ifdef dLineSizeAttenuation
  82. linewidth = size * uPixelRatio * ((uViewportHeight / 2.0) / -start.z) * 5.0;
  83. #else
  84. linewidth = size * uPixelRatio;
  85. #endif
  86. // adjust for linewidth
  87. offset *= linewidth;
  88. // adjust for clip-space to screen-space conversion
  89. offset /= uViewportHeight;
  90. // select end
  91. vec4 clip = (aMapping.y < 0.5) ? clipStart : clipEnd;
  92. // back to clip space
  93. offset *= clip.w;
  94. clip.xy += offset;
  95. gl_Position = clip;
  96. #include clip_instance
  97. }
  98. `;