lines.vert 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. /**
  2. * Copyright (c) 2018 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. precision highp float;
  9. precision highp int;
  10. #pragma glslify: import('./chunks/common-vert-params.glsl')
  11. #pragma glslify: import('./chunks/color-vert-params.glsl')
  12. uniform float uPixelRatio;
  13. uniform float uViewportHeight;
  14. #if defined(dSizeType_uniform)
  15. uniform float uSize;
  16. #elif defined(dSizeType_attribute)
  17. attribute float aSize;
  18. #elif defined(dSizeType_instance) || defined(dSizeType_group) || defined(dSizeType_groupInstance)
  19. varying vec4 vSize;
  20. uniform vec2 uSizeTexDim;
  21. uniform sampler2D tSize;
  22. #endif
  23. attribute vec3 aPosition;
  24. attribute mat4 aTransform;
  25. attribute float aInstance;
  26. attribute float aGroup;
  27. attribute vec2 aMapping;
  28. attribute vec3 aStart;
  29. attribute vec3 aEnd;
  30. void trimSegment(const in vec4 start, inout vec4 end) {
  31. // trim end segment so it terminates between the camera plane and the near plane
  32. // conservative estimate of the near plane
  33. float a = uProjection[2][2]; // 3nd entry in 3th column
  34. float b = uProjection[3][2]; // 3nd entry in 4th column
  35. float nearEstimate = -0.5 * b / a;
  36. float alpha = (nearEstimate - start.z) / (end.z - start.z);
  37. end.xyz = mix(start.xyz, end.xyz, alpha);
  38. }
  39. void main(){
  40. #pragma glslify: import('./chunks/assign-color-varying.glsl')
  41. // TODO move to chunk (also in point.vert)
  42. #if defined(dSizeType_uniform)
  43. float size = uSize;
  44. #elif defined(dSizeType_attribute)
  45. float size = aSize;
  46. #elif defined(dSizeType_instance)
  47. float size = readFromTexture(tSize, aInstance, uSizeTexDim).r;
  48. #elif defined(dSizeType_group)
  49. float size = readFromTexture(tSize, aGroup, uSizeTexDim).r;
  50. #elif defined(dSizeType_groupInstance)
  51. float size = readFromTexture(tSize, aInstance * float(uGroupCount) + aGroup, uSizeTexDim).r;
  52. #endif
  53. float linewidth = 3.0; // size;
  54. mat4 modelView = uView * uModel * aTransform;
  55. // camera space
  56. vec4 start = modelView * vec4(aStart, 1.0);
  57. vec4 end = modelView * vec4(aEnd, 1.0);
  58. // special case for perspective projection, and segments that terminate either in, or behind, the camera plane
  59. // clearly the gpu firmware has a way of addressing this issue when projecting into ndc space
  60. // but we need to perform ndc-space calculations in the shader, so we must address this issue directly
  61. // perhaps there is a more elegant solution -- WestLangley
  62. bool perspective = (uProjection[2][3] == -1.0); // 4th entry in the 3rd column
  63. if (perspective) {
  64. if (start.z < 0.0 && end.z >= 0.0) {
  65. trimSegment(start, end);
  66. } else if (end.z < 0.0 && start.z >= 0.0) {
  67. trimSegment(end, start);
  68. }
  69. }
  70. // clip space
  71. vec4 clipStart = uProjection * start;
  72. vec4 clipEnd = uProjection * end;
  73. // ndc space
  74. vec2 ndcStart = clipStart.xy / clipStart.w;
  75. vec2 ndcEnd = clipEnd.xy / clipEnd.w;
  76. // direction
  77. vec2 dir = ndcEnd - ndcStart;
  78. // account for clip-space aspect ratio
  79. dir.x *= uPixelRatio;
  80. dir = normalize(dir);
  81. // perpendicular to dir
  82. vec2 offset = vec2(dir.y, - dir.x);
  83. // undo aspect ratio adjustment
  84. dir.x /= uPixelRatio;
  85. offset.x /= uPixelRatio;
  86. // sign flip
  87. if (aMapping.x < 0.0) offset *= -1.0;
  88. // adjust for linewidth
  89. offset *= linewidth;
  90. // adjust for clip-space to screen-space conversion
  91. offset /= uViewportHeight;
  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. }