SAOShader.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. /**
  2. * TODO
  3. */
  4. import {
  5. Matrix4,
  6. Vector2
  7. } from "../../../build/three.module.js";
  8. var SAOShader = {
  9. defines: {
  10. "NUM_SAMPLES": 7,
  11. "NUM_RINGS": 4,
  12. "NORMAL_TEXTURE": 0,
  13. "DIFFUSE_TEXTURE": 0,
  14. "DEPTH_PACKING": 1,
  15. "PERSPECTIVE_CAMERA": 1
  16. },
  17. uniforms: {
  18. "tDepth": { value: null },
  19. "tDiffuse": { value: null },
  20. "tNormal": { value: null },
  21. "size": { value: new Vector2( 512, 512 ) },
  22. "cameraNear": { value: 1 },
  23. "cameraFar": { value: 100 },
  24. "cameraProjectionMatrix": { value: new Matrix4() },
  25. "cameraInverseProjectionMatrix": { value: new Matrix4() },
  26. "scale": { value: 1.0 },
  27. "intensity": { value: 0.1 },
  28. "bias": { value: 0.5 },
  29. "minResolution": { value: 0.0 },
  30. "kernelRadius": { value: 100.0 },
  31. "randomSeed": { value: 0.0 }
  32. },
  33. vertexShader: [
  34. "varying vec2 vUv;",
  35. "void main() {",
  36. " vUv = uv;",
  37. " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
  38. "}"
  39. ].join( "\n" ),
  40. fragmentShader: [
  41. "#include <common>",
  42. "varying vec2 vUv;",
  43. "#if DIFFUSE_TEXTURE == 1",
  44. "uniform sampler2D tDiffuse;",
  45. "#endif",
  46. "uniform sampler2D tDepth;",
  47. "#if NORMAL_TEXTURE == 1",
  48. "uniform sampler2D tNormal;",
  49. "#endif",
  50. "uniform float cameraNear;",
  51. "uniform float cameraFar;",
  52. "uniform mat4 cameraProjectionMatrix;",
  53. "uniform mat4 cameraInverseProjectionMatrix;",
  54. "uniform float scale;",
  55. "uniform float intensity;",
  56. "uniform float bias;",
  57. "uniform float kernelRadius;",
  58. "uniform float minResolution;",
  59. "uniform vec2 size;",
  60. "uniform float randomSeed;",
  61. "// RGBA depth",
  62. "#include <packing>",
  63. "vec4 getDefaultColor( const in vec2 screenPosition ) {",
  64. " #if DIFFUSE_TEXTURE == 1",
  65. " return texture2D( tDiffuse, vUv );",
  66. " #else",
  67. " return vec4( 1.0 );",
  68. " #endif",
  69. "}",
  70. "float getDepth( const in vec2 screenPosition ) {",
  71. " #if DEPTH_PACKING == 1",
  72. " return unpackRGBAToDepth( texture2D( tDepth, screenPosition ) );",
  73. " #else",
  74. " return texture2D( tDepth, screenPosition ).x;",
  75. " #endif",
  76. "}",
  77. "float getViewZ( const in float depth ) {",
  78. " #if PERSPECTIVE_CAMERA == 1",
  79. " return perspectiveDepthToViewZ( depth, cameraNear, cameraFar );",
  80. " #else",
  81. " return orthographicDepthToViewZ( depth, cameraNear, cameraFar );",
  82. " #endif",
  83. "}",
  84. "vec3 getViewPosition( const in vec2 screenPosition, const in float depth, const in float viewZ ) {",
  85. " float clipW = cameraProjectionMatrix[2][3] * viewZ + cameraProjectionMatrix[3][3];",
  86. " vec4 clipPosition = vec4( ( vec3( screenPosition, depth ) - 0.5 ) * 2.0, 1.0 );",
  87. " clipPosition *= clipW; // unprojection.",
  88. " return ( cameraInverseProjectionMatrix * clipPosition ).xyz;",
  89. "}",
  90. "vec3 getViewNormal( const in vec3 viewPosition, const in vec2 screenPosition ) {",
  91. " #if NORMAL_TEXTURE == 1",
  92. " return unpackRGBToNormal( texture2D( tNormal, screenPosition ).xyz );",
  93. " #else",
  94. " return normalize( cross( dFdx( viewPosition ), dFdy( viewPosition ) ) );",
  95. " #endif",
  96. "}",
  97. "float scaleDividedByCameraFar;",
  98. "float minResolutionMultipliedByCameraFar;",
  99. "float getOcclusion( const in vec3 centerViewPosition, const in vec3 centerViewNormal, const in vec3 sampleViewPosition ) {",
  100. " vec3 viewDelta = sampleViewPosition - centerViewPosition;",
  101. " float viewDistance = length( viewDelta );",
  102. " float scaledScreenDistance = scaleDividedByCameraFar * viewDistance;",
  103. " return max(0.0, (dot(centerViewNormal, viewDelta) - minResolutionMultipliedByCameraFar) / scaledScreenDistance - bias) / (1.0 + pow2( scaledScreenDistance ) );",
  104. "}",
  105. "// moving costly divides into consts",
  106. "const float ANGLE_STEP = PI2 * float( NUM_RINGS ) / float( NUM_SAMPLES );",
  107. "const float INV_NUM_SAMPLES = 1.0 / float( NUM_SAMPLES );",
  108. "float getAmbientOcclusion( const in vec3 centerViewPosition ) {",
  109. " // precompute some variables require in getOcclusion.",
  110. " scaleDividedByCameraFar = scale / cameraFar;",
  111. " minResolutionMultipliedByCameraFar = minResolution * cameraFar;",
  112. " vec3 centerViewNormal = getViewNormal( centerViewPosition, vUv );",
  113. " // jsfiddle that shows sample pattern: https://jsfiddle.net/a16ff1p7/",
  114. " float angle = rand( vUv + randomSeed ) * PI2;",
  115. " vec2 radius = vec2( kernelRadius * INV_NUM_SAMPLES ) / size;",
  116. " vec2 radiusStep = radius;",
  117. " float occlusionSum = 0.0;",
  118. " float weightSum = 0.0;",
  119. " for( int i = 0; i < NUM_SAMPLES; i ++ ) {",
  120. " vec2 sampleUv = vUv + vec2( cos( angle ), sin( angle ) ) * radius;",
  121. " radius += radiusStep;",
  122. " angle += ANGLE_STEP;",
  123. " float sampleDepth = getDepth( sampleUv );",
  124. " if( sampleDepth >= ( 1.0 - EPSILON ) ) {",
  125. " continue;",
  126. " }",
  127. " float sampleViewZ = getViewZ( sampleDepth );",
  128. " vec3 sampleViewPosition = getViewPosition( sampleUv, sampleDepth, sampleViewZ );",
  129. " occlusionSum += getOcclusion( centerViewPosition, centerViewNormal, sampleViewPosition );",
  130. " weightSum += 1.0;",
  131. " }",
  132. " if( weightSum == 0.0 ) discard;",
  133. " return occlusionSum * ( intensity / weightSum );",
  134. "}",
  135. "void main() {",
  136. " float centerDepth = getDepth( vUv );",
  137. " if( centerDepth >= ( 1.0 - EPSILON ) ) {",
  138. " discard;",
  139. " }",
  140. " float centerViewZ = getViewZ( centerDepth );",
  141. " vec3 viewPosition = getViewPosition( vUv, centerDepth, centerViewZ );",
  142. " float ambientOcclusion = getAmbientOcclusion( viewPosition );",
  143. " gl_FragColor = getDefaultColor( vUv );",
  144. " gl_FragColor.xyz *= 1.0 - ambientOcclusion;",
  145. "}"
  146. ].join( "\n" )
  147. };
  148. export { SAOShader };