spheres.frag 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. /**
  2. * Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  5. */
  6. precision highp float;
  7. precision highp int;
  8. #include common
  9. #include common_frag_params
  10. #include color_frag_params
  11. #include light_frag_params
  12. uniform mat4 uProjection;
  13. // uniform vec3 uInteriorColor;
  14. // uniform float uInteriorDarkening;
  15. vec3 uInteriorColor = vec3(0.5, 0.5, 0.5);
  16. float uInteriorDarkening = 0.0;
  17. uniform float uClipNear;
  18. uniform float uIsOrtho;
  19. varying float vRadius;
  20. varying float vRadiusSq;
  21. varying vec3 vPoint;
  22. varying vec3 vPointViewPosition;
  23. bool flag2 = false;
  24. bool interior = false;
  25. vec3 cameraPos;
  26. vec3 cameraNormal;
  27. // Calculate depth based on the given camera position.
  28. float calcDepth(const in vec3 cameraPos){
  29. vec2 clipZW = cameraPos.z * uProjection[2].zw + uProjection[3].zw;
  30. return 0.5 + 0.5 * clipZW.x / clipZW.y;
  31. }
  32. float calcClip(const in vec3 cameraPos) {
  33. return dot(vec4(cameraPos, 1.0), vec4(0.0, 0.0, 1.0, uClipNear - 0.5));
  34. }
  35. bool Impostor(out vec3 cameraPos, out vec3 cameraNormal){
  36. vec3 cameraSpherePos = -vPointViewPosition;
  37. cameraSpherePos.z += vRadius;
  38. vec3 rayOrigin = mix(vec3(0.0, 0.0, 0.0), vPoint, uIsOrtho);
  39. vec3 rayDirection = mix(normalize(vPoint), vec3(0.0, 0.0, 1.0), uIsOrtho);
  40. vec3 cameraSphereDir = mix(cameraSpherePos, rayOrigin - cameraSpherePos, uIsOrtho);
  41. float B = dot(rayDirection, cameraSphereDir);
  42. float det = B * B + vRadiusSq - dot(cameraSphereDir, cameraSphereDir);
  43. if(det < 0.0){
  44. discard;
  45. return false;
  46. }
  47. float sqrtDet = sqrt(det);
  48. float posT = mix(B + sqrtDet, B + sqrtDet, uIsOrtho);
  49. float negT = mix(B - sqrtDet, sqrtDet - B, uIsOrtho);
  50. cameraPos = rayDirection * negT + rayOrigin;
  51. #ifdef NEAR_CLIP
  52. if(calcDepth(cameraPos) <= 0.0){
  53. cameraPos = rayDirection * posT + rayOrigin;
  54. interior = true;
  55. }else if(calcClip(cameraPos) > 0.0){
  56. cameraPos = rayDirection * posT + rayOrigin;
  57. interior = true;
  58. flag2 = true;
  59. }
  60. #else
  61. if(calcDepth(cameraPos) <= 0.0){
  62. cameraPos = rayDirection * posT + rayOrigin;
  63. interior = true;
  64. }
  65. #endif
  66. cameraNormal = normalize(cameraPos - cameraSpherePos);
  67. cameraNormal *= float(!interior) * 2.0 - 1.0;
  68. return !interior;
  69. }
  70. void main(void){
  71. bool flag = Impostor(cameraPos, cameraNormal);
  72. #ifdef NEAR_CLIP
  73. if(calcClip(cameraPos) > 0.0)
  74. discard;
  75. #endif
  76. // FIXME not compatible with custom clipping plane
  77. // Set the depth based on the new cameraPos.
  78. gl_FragDepthEXT = calcDepth(cameraPos);
  79. if(!flag){
  80. // clamp to near clipping plane and add a tiny value to
  81. // make spheres with a greater radius occlude smaller ones
  82. #ifdef NEAR_CLIP
  83. if( flag2 ){
  84. gl_FragDepthEXT = max(0.0, calcDepth(vec3(-(uClipNear - 0.5))) + (0.0000001 / vRadius));
  85. }else if(gl_FragDepthEXT >= 0.0){
  86. gl_FragDepthEXT = 0.0 + (0.0000001 / vRadius);
  87. }
  88. #else
  89. if(gl_FragDepthEXT >= 0.0){
  90. gl_FragDepthEXT = 0.0 + (0.0000001 / vRadius);
  91. }
  92. #endif
  93. }
  94. // bugfix (mac only?)
  95. if (gl_FragDepthEXT < 0.0)
  96. discard;
  97. if (gl_FragDepthEXT > 1.0)
  98. discard;
  99. #include assign_material_color
  100. #if defined(dColorType_objectPicking) || defined(dColorType_instancePicking) || defined(dColorType_groupPicking)
  101. if (uAlpha < uPickingAlphaThreshold)
  102. discard; // ignore so the element below can be picked
  103. gl_FragColor = material;
  104. #else
  105. vec3 normal = cameraNormal;
  106. vec3 vViewPosition = -cameraPos;
  107. #include apply_light_color
  108. if(interior){
  109. #ifdef USE_INTERIOR_COLOR
  110. gl_FragColor.rgb = uInteriorColor;
  111. #endif
  112. gl_FragColor.rgb *= 1.0 - uInteriorDarkening;
  113. }
  114. #include apply_marker_color
  115. #include apply_fog
  116. #endif
  117. }