outlines.frag.ts 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. /**
  2. * Copyright (c) 2019-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author Áron Samuel Kovács <aron.kovacs@mail.muni.cz>
  5. @author Alexander Rose <alexander.rose@weirdbyte.de>
  6. */
  7. export const outlines_frag = `
  8. precision highp float;
  9. precision highp int;
  10. precision highp sampler2D;
  11. uniform sampler2D tDepthOpaque;
  12. uniform sampler2D tDepthTransparent;
  13. uniform vec2 uTexSize;
  14. uniform float uNear;
  15. uniform float uFar;
  16. uniform float uMaxPossibleViewZDiff;
  17. #include common
  18. float getViewZ(const in float depth) {
  19. #if dOrthographic == 1
  20. return orthographicDepthToViewZ(depth, uNear, uFar);
  21. #else
  22. return perspectiveDepthToViewZ(depth, uNear, uFar);
  23. #endif
  24. }
  25. float getDepthOpaque(const in vec2 coords) {
  26. #ifdef depthTextureSupport
  27. return texture2D(tDepthOpaque, coords).r;
  28. #else
  29. return unpackRGBAToDepth(texture2D(tDepthOpaque, coords));
  30. #endif
  31. }
  32. float getDepthTransparent(const in vec2 coords) {
  33. #ifdef dTransparentOutline
  34. return unpackRGBAToDepth(texture2D(tDepthTransparent, coords));
  35. #else
  36. return 1.0;
  37. #endif
  38. }
  39. bool isBackground(const in float depth) {
  40. return depth == 1.0;
  41. }
  42. void main(void) {
  43. float backgroundViewZ = uFar + 3.0 * uMaxPossibleViewZDiff;
  44. vec2 coords = gl_FragCoord.xy / uTexSize;
  45. vec2 invTexSize = 1.0 / uTexSize;
  46. float selfDepthOpaque = getDepthOpaque(coords);
  47. float selfViewZOpaque = isBackground(selfDepthOpaque) ? backgroundViewZ : getViewZ(selfDepthOpaque);
  48. float selfDepthTransparent = getDepthTransparent(coords);
  49. float selfViewZTransparent = isBackground(selfDepthTransparent) ? backgroundViewZ : getViewZ(selfDepthTransparent);
  50. float outline = 1.0;
  51. float bestDepth = 1.0;
  52. for (int y = -1; y <= 1; y++) {
  53. for (int x = -1; x <= 1; x++) {
  54. vec2 sampleCoords = coords + vec2(float(x), float(y)) * invTexSize;
  55. float sampleDepthOpaque = getDepthOpaque(sampleCoords);
  56. float sampleDepthTransparent = getDepthTransparent(sampleCoords);
  57. float sampleViewZOpaque = isBackground(sampleDepthOpaque) ? backgroundViewZ : getViewZ(sampleDepthOpaque);
  58. if (abs(selfViewZOpaque - sampleViewZOpaque) > uMaxPossibleViewZDiff && selfDepthOpaque > sampleDepthOpaque && sampleDepthOpaque <= bestDepth) {
  59. outline = 0.0;
  60. bestDepth = sampleDepthOpaque;
  61. }
  62. if (sampleDepthTransparent < sampleDepthOpaque) {
  63. float sampleViewZTransparent = isBackground(sampleDepthTransparent) ? backgroundViewZ : getViewZ(sampleDepthTransparent);
  64. if (abs(selfViewZTransparent - sampleViewZTransparent) > uMaxPossibleViewZDiff && selfDepthTransparent > sampleDepthTransparent && sampleDepthTransparent <= bestDepth) {
  65. outline = 0.0;
  66. bestDepth = sampleDepthTransparent;
  67. }
  68. }
  69. }
  70. }
  71. gl_FragColor = vec4(outline, packUnitIntervalToRG(bestDepth), 0.0);
  72. }
  73. `;