ssao-blur.frag.ts 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. export default `
  2. precision highp float;
  3. precision highp int;
  4. precision highp sampler2D;
  5. uniform sampler2D tSsaoDepth;
  6. uniform vec2 uTexSize;
  7. uniform float uKernel[dOcclusionKernelSize];
  8. uniform float uBlurDirectionX;
  9. uniform float uBlurDirectionY;
  10. uniform float uMaxPossibleViewZDiff;
  11. uniform float uNear;
  12. uniform float uFar;
  13. #include common
  14. float perspectiveDepthToViewZ(const in float invClipZ, const in float near, const in float far) {
  15. return (near * far) / ((far - near) * invClipZ - far);
  16. }
  17. float orthographicDepthToViewZ(const in float linearClipZ, const in float near, const in float far) {
  18. return linearClipZ * (near - far) - near;
  19. }
  20. float getViewZ(const in float depth) {
  21. #if dOrthographic == 1
  22. return orthographicDepthToViewZ(depth, uNear, uFar);
  23. #else
  24. return perspectiveDepthToViewZ(depth, uNear, uFar);
  25. #endif
  26. }
  27. bool isBackground(const in float depth) {
  28. return depth >= 0.99;
  29. }
  30. void main(void) {
  31. vec2 coords = gl_FragCoord.xy / uTexSize;
  32. vec2 packedDepth = texture(tSsaoDepth, coords).zw;
  33. float selfDepth = unpackRGToUnitInterval(packedDepth);
  34. // if background and if second pass
  35. if (isBackground(selfDepth) && uBlurDirectionY != 0.0) {
  36. gl_FragColor = vec4(packUnitIntervalToRG(1.0), packedDepth);
  37. return;
  38. }
  39. float selfViewZ = getViewZ(selfDepth);
  40. vec2 offset = vec2(uBlurDirectionX, uBlurDirectionY) / uTexSize;
  41. float sum = 0.0;
  42. float kernelSum = 0.0;
  43. // only if kernelSize is odd
  44. for (int i = -dOcclusionKernelSize / 2; i <= dOcclusionKernelSize / 2; i++) {
  45. vec2 sampleCoords = coords + float(i) * offset;
  46. vec4 sampleSsaoDepth = texture(tSsaoDepth, sampleCoords);
  47. float sampleDepth = unpackRGToUnitInterval(sampleSsaoDepth.zw);
  48. if (isBackground(sampleDepth)) {
  49. continue;
  50. }
  51. if (abs(i) > 1) {
  52. float sampleViewZ = getViewZ(sampleDepth);
  53. if (abs(selfViewZ - sampleViewZ) > uMaxPossibleViewZDiff) {
  54. continue;
  55. }
  56. }
  57. float kernel = uKernel[abs(i)];
  58. float sampleValue = unpackRGToUnitInterval(sampleSsaoDepth.xy);
  59. sum += kernel * sampleValue;
  60. kernelSum += kernel;
  61. }
  62. gl_FragColor = vec4(packUnitIntervalToRG(sum / kernelSum), packedDepth);
  63. }
  64. `;