SAOShader.js 5.6 KB

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