SAOShader.js 5.3 KB

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