spheres.frag 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  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. #pragma glslify: import('./chunks/common-frag-params.glsl')
  9. #pragma glslify: import('./chunks/color-frag-params.glsl')
  10. #pragma glslify: import('./chunks/light-frag-params.glsl')
  11. uniform mat4 uProjection;
  12. // uniform vec3 interiorColor;
  13. // uniform float interiorDarkening;
  14. vec3 interiorColor = vec3(1.0, 0.5, 0.5);
  15. float interiorDarkening = 0.0;
  16. uniform float clipNear;
  17. // uniform float ortho;
  18. float ortho = 0.0;
  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, clipNear - 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, ortho);
  39. vec3 rayDirection = mix(normalize(vPoint), vec3(0.0, 0.0, 1.0), ortho);
  40. vec3 cameraSphereDir = mix(cameraSpherePos, rayOrigin - cameraSpherePos, ortho);
  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, ortho);
  49. float negT = mix(B - sqrtDet, sqrtDet - B, ortho);
  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 main2(void){
  71. gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
  72. }
  73. void main(void){
  74. bool flag = Impostor(cameraPos, cameraNormal);
  75. #ifdef NEAR_CLIP
  76. if(calcClip(cameraPos) > 0.0)
  77. discard;
  78. #endif
  79. // FIXME not compatible with custom clipping plane
  80. // Set the depth based on the new cameraPos.
  81. gl_FragDepthEXT = calcDepth(cameraPos);
  82. if(!flag){
  83. // clamp to near clipping plane and add a tiny value to
  84. // make spheres with a greater radius occlude smaller ones
  85. #ifdef NEAR_CLIP
  86. if( flag2 ){
  87. gl_FragDepthEXT = max(0.0, calcDepth(vec3(-(clipNear - 0.5))) + (0.0000001 / vRadius));
  88. }else if(gl_FragDepthEXT >= 0.0){
  89. gl_FragDepthEXT = 0.0 + (0.0000001 / vRadius);
  90. }
  91. #else
  92. if(gl_FragDepthEXT >= 0.0){
  93. gl_FragDepthEXT = 0.0 + (0.0000001 / vRadius);
  94. }
  95. #endif
  96. }
  97. // bugfix (mac only?)
  98. if (gl_FragDepthEXT < 0.0)
  99. discard;
  100. if (gl_FragDepthEXT > 1.0)
  101. discard;
  102. // material color
  103. #pragma glslify: import('./chunks/assign-material-color.glsl')
  104. #if defined(dColorType_objectPicking) || defined(dColorType_instancePicking) || defined(dColorType_groupPicking)
  105. if (uAlpha < uPickingAlphaThreshold)
  106. discard; // ignore so the element below can be picked
  107. gl_FragColor = material;
  108. #else
  109. vec3 normal = cameraNormal;
  110. vec3 vViewPosition = -cameraPos;
  111. #pragma glslify: import('./chunks/apply-light-color.glsl')
  112. if(interior){
  113. #ifdef USE_INTERIOR_COLOR
  114. gl_FragColor.rgb = interiorColor;
  115. #endif
  116. gl_FragColor.rgb *= 1.0 - interiorDarkening;
  117. }
  118. #pragma glslify: import('./chunks/apply-marker-color.glsl')
  119. #pragma glslify: import('./chunks/apply-fog.glsl')
  120. #endif
  121. }