PolylineShadowVolumeFS.glsl 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. #ifdef GL_EXT_frag_depth
  2. #extension GL_EXT_frag_depth : enable
  3. #endif
  4. varying vec4 v_startPlaneNormalEcAndHalfWidth;
  5. varying vec4 v_endPlaneNormalEcAndBatchId;
  6. varying vec4 v_rightPlaneEC; // Technically can compute distance for this here
  7. varying vec4 v_endEcAndStartEcX;
  8. varying vec4 v_texcoordNormalizationAndStartEcYZ;
  9. #ifdef PER_INSTANCE_COLOR
  10. varying vec4 v_color;
  11. #endif
  12. void main(void)
  13. {
  14. float logDepthOrDepth = czm_branchFreeTernary(czm_sceneMode == czm_sceneMode2D, gl_FragCoord.z, czm_unpackDepth(texture2D(czm_globeDepthTexture, gl_FragCoord.xy / czm_viewport.zw)));
  15. vec3 ecStart = vec3(v_endEcAndStartEcX.w, v_texcoordNormalizationAndStartEcYZ.zw);
  16. // Discard for sky
  17. if (logDepthOrDepth == 0.0) {
  18. #ifdef DEBUG_SHOW_VOLUME
  19. gl_FragColor = vec4(1.0, 0.0, 0.0, 0.5);
  20. return;
  21. #else // DEBUG_SHOW_VOLUME
  22. discard;
  23. #endif // DEBUG_SHOW_VOLUME
  24. }
  25. vec4 eyeCoordinate = czm_windowToEyeCoordinates(gl_FragCoord.xy, logDepthOrDepth);
  26. eyeCoordinate /= eyeCoordinate.w;
  27. float halfMaxWidth = v_startPlaneNormalEcAndHalfWidth.w * czm_metersPerPixel(eyeCoordinate);
  28. // Check distance of the eye coordinate against the right-facing plane
  29. float widthwiseDistance = czm_planeDistance(v_rightPlaneEC, eyeCoordinate.xyz);
  30. // Check eye coordinate against the mitering planes
  31. float distanceFromStart = czm_planeDistance(v_startPlaneNormalEcAndHalfWidth.xyz, -dot(ecStart, v_startPlaneNormalEcAndHalfWidth.xyz), eyeCoordinate.xyz);
  32. float distanceFromEnd = czm_planeDistance(v_endPlaneNormalEcAndBatchId.xyz, -dot(v_endEcAndStartEcX.xyz, v_endPlaneNormalEcAndBatchId.xyz), eyeCoordinate.xyz);
  33. if (abs(widthwiseDistance) > halfMaxWidth || distanceFromStart < 0.0 || distanceFromEnd < 0.0) {
  34. #ifdef DEBUG_SHOW_VOLUME
  35. gl_FragColor = vec4(1.0, 0.0, 0.0, 0.5);
  36. return;
  37. #else // DEBUG_SHOW_VOLUME
  38. discard;
  39. #endif // DEBUG_SHOW_VOLUME
  40. }
  41. // Check distance of the eye coordinate against start and end planes with normals in the right plane.
  42. // For computing unskewed lengthwise texture coordinate.
  43. // Can also be used for clipping extremely pointy miters, but in practice unnecessary because of miter breaking.
  44. // aligned plane: cross the right plane normal with miter plane normal, then cross the result with right again to point it more "forward"
  45. vec3 alignedPlaneNormal;
  46. // start aligned plane
  47. alignedPlaneNormal = cross(v_rightPlaneEC.xyz, v_startPlaneNormalEcAndHalfWidth.xyz);
  48. alignedPlaneNormal = normalize(cross(alignedPlaneNormal, v_rightPlaneEC.xyz));
  49. distanceFromStart = czm_planeDistance(alignedPlaneNormal, -dot(alignedPlaneNormal, ecStart), eyeCoordinate.xyz);
  50. // end aligned plane
  51. alignedPlaneNormal = cross(v_rightPlaneEC.xyz, v_endPlaneNormalEcAndBatchId.xyz);
  52. alignedPlaneNormal = normalize(cross(alignedPlaneNormal, v_rightPlaneEC.xyz));
  53. distanceFromEnd = czm_planeDistance(alignedPlaneNormal, -dot(alignedPlaneNormal, v_endEcAndStartEcX.xyz), eyeCoordinate.xyz);
  54. #ifdef PER_INSTANCE_COLOR
  55. gl_FragColor = czm_gammaCorrect(v_color);
  56. #else // PER_INSTANCE_COLOR
  57. // Clamp - distance to aligned planes may be negative due to mitering,
  58. // so fragment texture coordinate might be out-of-bounds.
  59. float s = clamp(distanceFromStart / (distanceFromStart + distanceFromEnd), 0.0, 1.0);
  60. s = (s * v_texcoordNormalizationAndStartEcYZ.x) + v_texcoordNormalizationAndStartEcYZ.y;
  61. float t = (widthwiseDistance + halfMaxWidth) / (2.0 * halfMaxWidth);
  62. czm_materialInput materialInput;
  63. materialInput.s = s;
  64. materialInput.st = vec2(s, t);
  65. materialInput.str = vec3(s, t, 0.0);
  66. czm_material material = czm_getMaterial(materialInput);
  67. gl_FragColor = vec4(material.diffuse + material.emission, material.alpha);
  68. #endif // PER_INSTANCE_COLOR
  69. // Premultiply alpha. Required for classification primitives on translucent globe.
  70. gl_FragColor.rgb *= gl_FragColor.a;
  71. czm_writeDepthClamp();
  72. }