outlines.frag.ts 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  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. return unpackRGBAToDepth(texture2D(tDepthTransparent, coords));
  34. }
  35. bool isBackground(const in float depth) {
  36. return depth == 1.0;
  37. }
  38. void main(void) {
  39. float backgroundViewZ = uFar + 3.0 * uMaxPossibleViewZDiff;
  40. vec2 coords = gl_FragCoord.xy / uTexSize;
  41. vec2 invTexSize = 1.0 / uTexSize;
  42. float selfDepthOpaque = getDepthOpaque(coords);
  43. float selfViewZOpaque = isBackground(selfDepthOpaque) ? backgroundViewZ : getViewZ(selfDepthOpaque);
  44. float selfDepthTransparent = getDepthTransparent(coords);
  45. float selfViewZTransparent = isBackground(selfDepthTransparent) ? backgroundViewZ : getViewZ(selfDepthTransparent);
  46. float outline = 1.0;
  47. float bestDepth = 1.0;
  48. for (int y = -1; y <= 1; y++) {
  49. for (int x = -1; x <= 1; x++) {
  50. vec2 sampleCoords = coords + vec2(float(x), float(y)) * invTexSize;
  51. float sampleDepthOpaque = getDepthOpaque(sampleCoords);
  52. float sampleDepthTransparent = getDepthTransparent(sampleCoords);
  53. float sampleViewZOpaque = isBackground(sampleDepthOpaque) ? backgroundViewZ : getViewZ(sampleDepthOpaque);
  54. if (abs(selfViewZOpaque - sampleViewZOpaque) > uMaxPossibleViewZDiff && selfDepthOpaque > sampleDepthOpaque && sampleDepthOpaque <= bestDepth) {
  55. outline = 0.0;
  56. bestDepth = sampleDepthOpaque;
  57. }
  58. if (sampleDepthTransparent < sampleDepthOpaque) {
  59. float sampleViewZTransparent = isBackground(sampleDepthTransparent) ? backgroundViewZ : getViewZ(sampleDepthTransparent);
  60. if (abs(selfViewZTransparent - sampleViewZTransparent) > uMaxPossibleViewZDiff && selfDepthTransparent > sampleDepthTransparent && sampleDepthTransparent <= bestDepth) {
  61. outline = 0.0;
  62. bestDepth = sampleDepthTransparent;
  63. }
  64. }
  65. }
  66. }
  67. gl_FragColor = vec4(outline, packUnitIntervalToRG(bestDepth), 0.0);
  68. }
  69. `;