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. };