EllipsoidFS.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. //This file is automatically rebuilt by the Cesium build process.
  2. /*global define*/
  3. define(function() {
  4. "use strict";
  5. return "#ifdef WRITE_DEPTH\n\
  6. #ifdef GL_EXT_frag_depth\n\
  7. #extension GL_EXT_frag_depth : enable\n\
  8. #endif\n\
  9. #endif\n\
  10. \n\
  11. uniform vec3 u_radii;\n\
  12. uniform vec3 u_oneOverEllipsoidRadiiSquared;\n\
  13. \n\
  14. varying vec3 v_positionEC;\n\
  15. \n\
  16. vec4 computeEllipsoidColor(czm_ray ray, float intersection, float side)\n\
  17. {\n\
  18. vec3 positionEC = czm_pointAlongRay(ray, intersection);\n\
  19. vec3 positionMC = (czm_inverseModelView * vec4(positionEC, 1.0)).xyz;\n\
  20. vec3 geodeticNormal = normalize(czm_geodeticSurfaceNormal(positionMC, vec3(0.0), u_oneOverEllipsoidRadiiSquared));\n\
  21. vec3 sphericalNormal = normalize(positionMC / u_radii);\n\
  22. vec3 normalMC = geodeticNormal * side; // normalized surface normal (always facing the viewer) in model coordinates\n\
  23. vec3 normalEC = normalize(czm_normal * normalMC); // normalized surface normal in eye coordiantes\n\
  24. \n\
  25. vec2 st = czm_ellipsoidWgs84TextureCoordinates(sphericalNormal);\n\
  26. vec3 positionToEyeEC = -positionEC;\n\
  27. \n\
  28. czm_materialInput materialInput;\n\
  29. materialInput.s = st.s;\n\
  30. materialInput.st = st;\n\
  31. materialInput.str = (positionMC + u_radii) / u_radii;\n\
  32. materialInput.normalEC = normalEC;\n\
  33. materialInput.tangentToEyeMatrix = czm_eastNorthUpToEyeCoordinates(positionMC, normalEC);\n\
  34. materialInput.positionToEyeEC = positionToEyeEC;\n\
  35. czm_material material = czm_getMaterial(materialInput);\n\
  36. \n\
  37. #ifdef ONLY_SUN_LIGHTING\n\
  38. return czm_private_phong(normalize(positionToEyeEC), material);\n\
  39. #else\n\
  40. return czm_phong(normalize(positionToEyeEC), material);\n\
  41. #endif\n\
  42. }\n\
  43. \n\
  44. void main()\n\
  45. {\n\
  46. // PERFORMANCE_TODO: When dynamic branching is available, compute ratio of maximum and minimum radii\n\
  47. // in the vertex shader. Only when it is larger than some constant, march along the ray.\n\
  48. // Otherwise perform one intersection test which will be the common case.\n\
  49. \n\
  50. // Test if the ray intersects a sphere with the ellipsoid's maximum radius.\n\
  51. // For very oblate ellipsoids, using the ellipsoid's radii for an intersection test\n\
  52. // may cause false negatives. This will discard fragments before marching the ray forward.\n\
  53. float maxRadius = max(u_radii.x, max(u_radii.y, u_radii.z)) * 1.5;\n\
  54. vec3 direction = normalize(v_positionEC);\n\
  55. vec3 ellipsoidCenter = czm_modelView[3].xyz;\n\
  56. \n\
  57. float t1 = -1.0;\n\
  58. float t2 = -1.0;\n\
  59. \n\
  60. float b = -2.0 * dot(direction, ellipsoidCenter);\n\
  61. float c = dot(ellipsoidCenter, ellipsoidCenter) - maxRadius * maxRadius;\n\
  62. \n\
  63. float discriminant = b * b - 4.0 * c;\n\
  64. if (discriminant >= 0.0) {\n\
  65. t1 = (-b - sqrt(discriminant)) * 0.5;\n\
  66. t2 = (-b + sqrt(discriminant)) * 0.5;\n\
  67. }\n\
  68. \n\
  69. if (t1 < 0.0 && t2 < 0.0) {\n\
  70. discard;\n\
  71. }\n\
  72. \n\
  73. float t = min(t1, t2);\n\
  74. if (t < 0.0) {\n\
  75. t = 0.0;\n\
  76. }\n\
  77. \n\
  78. // March ray forward to intersection with larger sphere and find\n\
  79. // actual intersection point with ellipsoid.\n\
  80. czm_ellipsoid ellipsoid = czm_ellipsoidNew(ellipsoidCenter, u_radii);\n\
  81. czm_ray ray = czm_ray(t * direction, direction);\n\
  82. czm_raySegment intersection = czm_rayEllipsoidIntersectionInterval(ray, ellipsoid);\n\
  83. \n\
  84. if (czm_isEmpty(intersection))\n\
  85. {\n\
  86. discard;\n\
  87. }\n\
  88. \n\
  89. // If the viewer is outside, compute outsideFaceColor, with normals facing outward.\n\
  90. vec4 outsideFaceColor = (intersection.start != 0.0) ? computeEllipsoidColor(ray, intersection.start, 1.0) : vec4(0.0);\n\
  91. \n\
  92. // If the viewer either is inside or can see inside, compute insideFaceColor, with normals facing inward.\n\
  93. vec4 insideFaceColor = (outsideFaceColor.a < 1.0) ? computeEllipsoidColor(ray, intersection.stop, -1.0) : vec4(0.0);\n\
  94. \n\
  95. gl_FragColor = mix(insideFaceColor, outsideFaceColor, outsideFaceColor.a);\n\
  96. gl_FragColor.a = 1.0 - (1.0 - insideFaceColor.a) * (1.0 - outsideFaceColor.a);\n\
  97. \n\
  98. #ifdef WRITE_DEPTH\n\
  99. #ifdef GL_EXT_frag_depth\n\
  100. t = (intersection.start != 0.0) ? intersection.start : intersection.stop;\n\
  101. vec3 positionEC = czm_pointAlongRay(ray, t);\n\
  102. vec4 positionCC = czm_projection * vec4(positionEC, 1.0);\n\
  103. float z = positionCC.z / positionCC.w;\n\
  104. \n\
  105. float n = czm_depthRange.near;\n\
  106. float f = czm_depthRange.far;\n\
  107. \n\
  108. gl_FragDepthEXT = (z * (f - n) + f + n) * 0.5;\n\
  109. #endif\n\
  110. #endif\n\
  111. }\n\
  112. ";
  113. });