postprocessing.frag.ts 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. /**
  2. * Copyright (c) 2019-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  5. * @author Áron Samuel Kovács <aron.kovacs@mail.muni.cz>
  6. */
  7. export const postprocessing_frag = `
  8. precision highp float;
  9. precision highp int;
  10. precision highp sampler2D;
  11. uniform sampler2D tSsaoDepth;
  12. uniform sampler2D tColor;
  13. uniform sampler2D tDepth;
  14. uniform sampler2D tOutlines;
  15. uniform vec2 uTexSize;
  16. uniform float uNear;
  17. uniform float uFar;
  18. uniform float uFogNear;
  19. uniform float uFogFar;
  20. uniform vec3 uFogColor;
  21. uniform vec3 uOutlineColor;
  22. uniform bool uTransparentBackground;
  23. uniform vec2 uOcclusionOffset;
  24. uniform float uMaxPossibleViewZDiff;
  25. const vec3 occlusionColor = vec3(0.0);
  26. #include common
  27. float getViewZ(const in float depth) {
  28. #if dOrthographic == 1
  29. return orthographicDepthToViewZ(depth, uNear, uFar);
  30. #else
  31. return perspectiveDepthToViewZ(depth, uNear, uFar);
  32. #endif
  33. }
  34. float getDepth(const in vec2 coords) {
  35. return unpackRGBAToDepth(texture2D(tDepth, coords));
  36. }
  37. bool isBackground(const in float depth) {
  38. return depth == 1.0;
  39. }
  40. float getOutline(const in vec2 coords, out float closestTexel) {
  41. float backgroundViewZ = uFar + 3.0 * uMaxPossibleViewZDiff;
  42. vec2 invTexSize = 1.0 / uTexSize;
  43. float selfDepth = getDepth(coords);
  44. float selfViewZ = isBackground(selfDepth) ? backgroundViewZ : getViewZ(selfDepth);
  45. float outline = 1.0;
  46. closestTexel = 1.0;
  47. for (int y = -dOutlineScale; y <= dOutlineScale; y++) {
  48. for (int x = -dOutlineScale; x <= dOutlineScale; x++) {
  49. if (x * x + y * y > dOutlineScale * dOutlineScale) {
  50. continue;
  51. }
  52. vec2 sampleCoords = coords + vec2(float(x), float(y)) * invTexSize;
  53. vec4 sampleOutlineCombined = texture2D(tOutlines, sampleCoords);
  54. float sampleOutline = sampleOutlineCombined.r;
  55. float sampleOutlineDepth = unpackRGToUnitInterval(sampleOutlineCombined.gb);
  56. if (sampleOutline == 0.0 && sampleOutlineDepth < closestTexel && abs(selfViewZ - sampleOutlineDepth) > uMaxPossibleViewZDiff) {
  57. outline = 0.0;
  58. closestTexel = sampleOutlineDepth;
  59. }
  60. }
  61. }
  62. return outline;
  63. }
  64. float getSsao(vec2 coords) {
  65. float rawSsao = unpackRGToUnitInterval(texture2D(tSsaoDepth, coords).xy);
  66. if (rawSsao > 0.999) {
  67. return 1.0;
  68. } else if (rawSsao > 0.001) {
  69. return rawSsao;
  70. }
  71. // treat values close to 0.0 as errors and return no occlusion
  72. return 1.0;
  73. }
  74. void main(void) {
  75. vec2 coords = gl_FragCoord.xy / uTexSize;
  76. vec4 color = texture2D(tColor, coords);
  77. float viewDist;
  78. float fogFactor;
  79. #ifdef dOcclusionEnable
  80. float depth = getDepth(coords);
  81. if (!isBackground(depth)) {
  82. viewDist = abs(getViewZ(depth));
  83. fogFactor = smoothstep(uFogNear, uFogFar, viewDist);
  84. float occlusionFactor = getSsao(coords + uOcclusionOffset);
  85. if (!uTransparentBackground) {
  86. color.rgb = mix(mix(occlusionColor, uFogColor, fogFactor), color.rgb, occlusionFactor);
  87. } else {
  88. color.rgb = mix(occlusionColor * (1.0 - fogFactor), color.rgb, occlusionFactor);
  89. }
  90. }
  91. #endif
  92. // outline needs to be handled after occlusion to keep them clean
  93. #ifdef dOutlineEnable
  94. float closestTexel;
  95. float outline = getOutline(coords, closestTexel);
  96. if (outline == 0.0) {
  97. color.rgb = mix(uOutlineColor, color.rgb, outline);
  98. viewDist = abs(getViewZ(closestTexel));
  99. fogFactor = smoothstep(uFogNear, uFogFar, viewDist);
  100. if (!uTransparentBackground) {
  101. color.rgb = mix(color.rgb, uFogColor, fogFactor);
  102. } else {
  103. color.a = 1.0 - fogFactor;
  104. }
  105. }
  106. #endif
  107. gl_FragColor = color;
  108. }
  109. `;