PolylineShadowVolumeVS.glsl 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. in vec3 position3DHigh;
  2. in vec3 position3DLow;
  3. // In 2D and in 3D, texture coordinate normalization component signs encodes:
  4. // * X sign - sidedness relative to right plane
  5. // * Y sign - is negative OR magnitude is greater than 1.0 if vertex is on bottom of volume
  6. #ifndef COLUMBUS_VIEW_2D
  7. in vec4 startHiAndForwardOffsetX;
  8. in vec4 startLoAndForwardOffsetY;
  9. in vec4 startNormalAndForwardOffsetZ;
  10. in vec4 endNormalAndTextureCoordinateNormalizationX;
  11. in vec4 rightNormalAndTextureCoordinateNormalizationY;
  12. #else
  13. in vec4 startHiLo2D;
  14. in vec4 offsetAndRight2D;
  15. in vec4 startEndNormals2D;
  16. in vec2 texcoordNormalization2D;
  17. #endif
  18. in float batchId;
  19. out vec4 v_startPlaneNormalEcAndHalfWidth;
  20. out vec4 v_endPlaneNormalEcAndBatchId;
  21. out vec4 v_rightPlaneEC;
  22. out vec4 v_endEcAndStartEcX;
  23. out vec4 v_texcoordNormalizationAndStartEcYZ;
  24. // For materials
  25. #ifdef WIDTH_VARYING
  26. out float v_width;
  27. #endif
  28. #ifdef ANGLE_VARYING
  29. out float v_polylineAngle;
  30. #endif
  31. #ifdef PER_INSTANCE_COLOR
  32. out vec4 v_color;
  33. #endif
  34. void main()
  35. {
  36. #ifdef COLUMBUS_VIEW_2D
  37. vec3 ecStart = (czm_modelViewRelativeToEye * czm_translateRelativeToEye(vec3(0.0, startHiLo2D.xy), vec3(0.0, startHiLo2D.zw))).xyz;
  38. vec3 forwardDirectionEC = czm_normal * vec3(0.0, offsetAndRight2D.xy);
  39. vec3 ecEnd = forwardDirectionEC + ecStart;
  40. forwardDirectionEC = normalize(forwardDirectionEC);
  41. // Right plane
  42. v_rightPlaneEC.xyz = czm_normal * vec3(0.0, offsetAndRight2D.zw);
  43. v_rightPlaneEC.w = -dot(v_rightPlaneEC.xyz, ecStart);
  44. // start plane
  45. vec4 startPlaneEC;
  46. startPlaneEC.xyz = czm_normal * vec3(0.0, startEndNormals2D.xy);
  47. startPlaneEC.w = -dot(startPlaneEC.xyz, ecStart);
  48. // end plane
  49. vec4 endPlaneEC;
  50. endPlaneEC.xyz = czm_normal * vec3(0.0, startEndNormals2D.zw);
  51. endPlaneEC.w = -dot(endPlaneEC.xyz, ecEnd);
  52. v_texcoordNormalizationAndStartEcYZ.x = abs(texcoordNormalization2D.x);
  53. v_texcoordNormalizationAndStartEcYZ.y = texcoordNormalization2D.y;
  54. #else // COLUMBUS_VIEW_2D
  55. vec3 ecStart = (czm_modelViewRelativeToEye * czm_translateRelativeToEye(startHiAndForwardOffsetX.xyz, startLoAndForwardOffsetY.xyz)).xyz;
  56. vec3 offset = czm_normal * vec3(startHiAndForwardOffsetX.w, startLoAndForwardOffsetY.w, startNormalAndForwardOffsetZ.w);
  57. vec3 ecEnd = ecStart + offset;
  58. vec3 forwardDirectionEC = normalize(offset);
  59. // start plane
  60. vec4 startPlaneEC;
  61. startPlaneEC.xyz = czm_normal * startNormalAndForwardOffsetZ.xyz;
  62. startPlaneEC.w = -dot(startPlaneEC.xyz, ecStart);
  63. // end plane
  64. vec4 endPlaneEC;
  65. endPlaneEC.xyz = czm_normal * endNormalAndTextureCoordinateNormalizationX.xyz;
  66. endPlaneEC.w = -dot(endPlaneEC.xyz, ecEnd);
  67. // Right plane
  68. v_rightPlaneEC.xyz = czm_normal * rightNormalAndTextureCoordinateNormalizationY.xyz;
  69. v_rightPlaneEC.w = -dot(v_rightPlaneEC.xyz, ecStart);
  70. v_texcoordNormalizationAndStartEcYZ.x = abs(endNormalAndTextureCoordinateNormalizationX.w);
  71. v_texcoordNormalizationAndStartEcYZ.y = rightNormalAndTextureCoordinateNormalizationY.w;
  72. #endif // COLUMBUS_VIEW_2D
  73. v_endEcAndStartEcX.xyz = ecEnd;
  74. v_endEcAndStartEcX.w = ecStart.x;
  75. v_texcoordNormalizationAndStartEcYZ.zw = ecStart.yz;
  76. #ifdef PER_INSTANCE_COLOR
  77. v_color = czm_batchTable_color(batchId);
  78. #endif // PER_INSTANCE_COLOR
  79. // Compute a normal along which to "push" the position out, extending the miter depending on view distance.
  80. // Position has already been "pushed" by unit length along miter normal, and miter normals are encoded in the planes.
  81. // Decode the normal to use at this specific vertex, push the position back, and then push to where it needs to be.
  82. vec4 positionRelativeToEye = czm_computePosition();
  83. // Check distance to the end plane and start plane, pick the plane that is closer
  84. vec4 positionEC = czm_modelViewRelativeToEye * positionRelativeToEye; // w = 1.0, see czm_computePosition
  85. float absStartPlaneDistance = abs(czm_planeDistance(startPlaneEC, positionEC.xyz));
  86. float absEndPlaneDistance = abs(czm_planeDistance(endPlaneEC, positionEC.xyz));
  87. vec3 planeDirection = czm_branchFreeTernary(absStartPlaneDistance < absEndPlaneDistance, startPlaneEC.xyz, endPlaneEC.xyz);
  88. vec3 upOrDown = normalize(cross(v_rightPlaneEC.xyz, planeDirection)); // Points "up" for start plane, "down" at end plane.
  89. vec3 normalEC = normalize(cross(planeDirection, upOrDown)); // In practice, the opposite seems to work too.
  90. // Extrude bottom vertices downward for far view distances, like for GroundPrimitives
  91. upOrDown = cross(forwardDirectionEC, normalEC);
  92. upOrDown = float(czm_sceneMode == czm_sceneMode3D) * upOrDown;
  93. upOrDown = float(v_texcoordNormalizationAndStartEcYZ.y > 1.0 || v_texcoordNormalizationAndStartEcYZ.y < 0.0) * upOrDown;
  94. upOrDown = min(GLOBE_MINIMUM_ALTITUDE, czm_geometricToleranceOverMeter * length(positionRelativeToEye.xyz)) * upOrDown;
  95. positionEC.xyz += upOrDown;
  96. v_texcoordNormalizationAndStartEcYZ.y = czm_branchFreeTernary(v_texcoordNormalizationAndStartEcYZ.y > 1.0, 0.0, abs(v_texcoordNormalizationAndStartEcYZ.y));
  97. // Determine distance along normalEC to push for a volume of appropriate width.
  98. // Make volumes about double pixel width for a conservative fit - in practice the
  99. // extra cost here is minimal compared to the loose volume heights.
  100. //
  101. // N = normalEC (guaranteed "right-facing")
  102. // R = rightEC
  103. // p = angle between N and R
  104. // w = distance to push along R if R == N
  105. // d = distance to push along N
  106. //
  107. // N R
  108. // { \ p| } * cos(p) = dot(N, R) = w / d
  109. // d\ \ | |w * d = w / dot(N, R)
  110. // { \| }
  111. // o---------- polyline segment ---->
  112. //
  113. float width = czm_batchTable_width(batchId);
  114. #ifdef WIDTH_VARYING
  115. v_width = width;
  116. #endif
  117. v_startPlaneNormalEcAndHalfWidth.xyz = startPlaneEC.xyz;
  118. v_startPlaneNormalEcAndHalfWidth.w = width * 0.5;
  119. v_endPlaneNormalEcAndBatchId.xyz = endPlaneEC.xyz;
  120. v_endPlaneNormalEcAndBatchId.w = batchId;
  121. width = width * max(0.0, czm_metersPerPixel(positionEC)); // width = distance to push along R
  122. width = width / dot(normalEC, v_rightPlaneEC.xyz); // width = distance to push along N
  123. // Determine if this vertex is on the "left" or "right"
  124. #ifdef COLUMBUS_VIEW_2D
  125. normalEC *= sign(texcoordNormalization2D.x);
  126. #else
  127. normalEC *= sign(endNormalAndTextureCoordinateNormalizationX.w);
  128. #endif
  129. positionEC.xyz += width * normalEC;
  130. gl_Position = czm_depthClamp(czm_projection * positionEC);
  131. #ifdef ANGLE_VARYING
  132. // Approximate relative screen space direction of the line.
  133. vec2 approxLineDirection = normalize(vec2(forwardDirectionEC.x, -forwardDirectionEC.y));
  134. approxLineDirection.y = czm_branchFreeTernary(approxLineDirection.x == 0.0 && approxLineDirection.y == 0.0, -1.0, approxLineDirection.y);
  135. v_polylineAngle = czm_fastApproximateAtan(approxLineDirection.x, approxLineDirection.y);
  136. #endif
  137. }