SAOShader.js 5.5 KB

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