GTAOPass.js 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726
  1. import {
  2. AddEquation,
  3. Color,
  4. CustomBlending,
  5. DataTexture,
  6. DepthTexture,
  7. DepthStencilFormat,
  8. DstAlphaFactor,
  9. DstColorFactor,
  10. HalfFloatType,
  11. MeshNormalMaterial,
  12. NearestFilter,
  13. NoBlending,
  14. RepeatWrapping,
  15. RGBAFormat,
  16. ShaderMaterial,
  17. UniformsUtils,
  18. UnsignedByteType,
  19. UnsignedInt248Type,
  20. WebGLRenderTarget,
  21. ZeroFactor
  22. } from 'three';
  23. import { Pass, FullScreenQuad } from './Pass.js';
  24. import { generateMagicSquareNoise, GTAOShader, GTAODepthShader, GTAOBlendShader } from '../shaders/GTAOShader.js';
  25. import { generatePdSamplePointInitializer, PoissonDenoiseShader } from '../shaders/PoissonDenoiseShader.js';
  26. import { CopyShader } from '../shaders/CopyShader.js';
  27. import { SimplexNoise } from '../math/SimplexNoise.js';
  28. /**
  29. * A pass for an GTAO effect.
  30. *
  31. * `GTAOPass` provides better quality than {@link SSAOPass} but is also more expensive.
  32. *
  33. * ```js
  34. * const gtaoPass = new GTAOPass( scene, camera, width, height );
  35. * gtaoPass.output = GTAOPass.OUTPUT.Denoise;
  36. * composer.addPass( gtaoPass );
  37. * ```
  38. *
  39. * @augments Pass
  40. * @three_import import { GTAOPass } from 'three/addons/postprocessing/GTAOPass.js';
  41. */
  42. class GTAOPass extends Pass {
  43. /**
  44. * Constructs a new GTAO pass.
  45. *
  46. * @param {Scene} scene - The scene to compute the AO for.
  47. * @param {Camera} camera - The camera.
  48. * @param {number} [width=512] - The width of the effect.
  49. * @param {number} [height=512] - The height of the effect.
  50. * @param {Object} [parameters] - The pass parameters.
  51. * @param {Object} [aoParameters] - The AO parameters.
  52. * @param {Object} [pdParameters] - The denoise parameters.
  53. */
  54. constructor( scene, camera, width = 512, height = 512, parameters, aoParameters, pdParameters ) {
  55. super();
  56. /**
  57. * The width of the effect.
  58. *
  59. * @type {number}
  60. * @default 512
  61. */
  62. this.width = width;
  63. /**
  64. * The height of the effect.
  65. *
  66. * @type {number}
  67. * @default 512
  68. */
  69. this.height = height;
  70. /**
  71. * Overwritten to perform a clear operation by default.
  72. *
  73. * @type {boolean}
  74. * @default true
  75. */
  76. this.clear = true;
  77. /**
  78. * The camera.
  79. *
  80. * @type {Camera}
  81. */
  82. this.camera = camera;
  83. /**
  84. * The scene to render the AO for.
  85. *
  86. * @type {Scene}
  87. */
  88. this.scene = scene;
  89. /**
  90. * The output configuration.
  91. *
  92. * @type {number}
  93. * @default 0
  94. */
  95. this.output = 0;
  96. this._renderGBuffer = true;
  97. this._visibilityCache = new Map();
  98. /**
  99. * The AO blend intensity.
  100. *
  101. * @type {number}
  102. * @default 1
  103. */
  104. this.blendIntensity = 1.;
  105. /**
  106. * The number of Poisson Denoise rings.
  107. *
  108. * @type {number}
  109. * @default 2
  110. */
  111. this.pdRings = 2.;
  112. /**
  113. * The Poisson Denoise radius exponent.
  114. *
  115. * @type {number}
  116. * @default 2
  117. */
  118. this.pdRadiusExponent = 2.;
  119. /**
  120. * The Poisson Denoise sample count.
  121. *
  122. * @type {number}
  123. * @default 16
  124. */
  125. this.pdSamples = 16;
  126. this.gtaoNoiseTexture = generateMagicSquareNoise();
  127. this.pdNoiseTexture = this._generateNoise();
  128. this.gtaoRenderTarget = new WebGLRenderTarget( this.width, this.height, { type: HalfFloatType } );
  129. this.pdRenderTarget = this.gtaoRenderTarget.clone();
  130. this.gtaoMaterial = new ShaderMaterial( {
  131. defines: Object.assign( {}, GTAOShader.defines ),
  132. uniforms: UniformsUtils.clone( GTAOShader.uniforms ),
  133. vertexShader: GTAOShader.vertexShader,
  134. fragmentShader: GTAOShader.fragmentShader,
  135. blending: NoBlending,
  136. depthTest: false,
  137. depthWrite: false,
  138. } );
  139. this.gtaoMaterial.defines.PERSPECTIVE_CAMERA = this.camera.isPerspectiveCamera ? 1 : 0;
  140. this.gtaoMaterial.uniforms.tNoise.value = this.gtaoNoiseTexture;
  141. this.gtaoMaterial.uniforms.resolution.value.set( this.width, this.height );
  142. this.gtaoMaterial.uniforms.cameraNear.value = this.camera.near;
  143. this.gtaoMaterial.uniforms.cameraFar.value = this.camera.far;
  144. this.normalMaterial = new MeshNormalMaterial();
  145. this.normalMaterial.blending = NoBlending;
  146. this.pdMaterial = new ShaderMaterial( {
  147. defines: Object.assign( {}, PoissonDenoiseShader.defines ),
  148. uniforms: UniformsUtils.clone( PoissonDenoiseShader.uniforms ),
  149. vertexShader: PoissonDenoiseShader.vertexShader,
  150. fragmentShader: PoissonDenoiseShader.fragmentShader,
  151. depthTest: false,
  152. depthWrite: false,
  153. } );
  154. this.pdMaterial.uniforms.tDiffuse.value = this.gtaoRenderTarget.texture;
  155. this.pdMaterial.uniforms.tNoise.value = this.pdNoiseTexture;
  156. this.pdMaterial.uniforms.resolution.value.set( this.width, this.height );
  157. this.pdMaterial.uniforms.lumaPhi.value = 10;
  158. this.pdMaterial.uniforms.depthPhi.value = 2;
  159. this.pdMaterial.uniforms.normalPhi.value = 3;
  160. this.pdMaterial.uniforms.radius.value = 8;
  161. this.depthRenderMaterial = new ShaderMaterial( {
  162. defines: Object.assign( {}, GTAODepthShader.defines ),
  163. uniforms: UniformsUtils.clone( GTAODepthShader.uniforms ),
  164. vertexShader: GTAODepthShader.vertexShader,
  165. fragmentShader: GTAODepthShader.fragmentShader,
  166. blending: NoBlending
  167. } );
  168. this.depthRenderMaterial.uniforms.cameraNear.value = this.camera.near;
  169. this.depthRenderMaterial.uniforms.cameraFar.value = this.camera.far;
  170. this.copyMaterial = new ShaderMaterial( {
  171. uniforms: UniformsUtils.clone( CopyShader.uniforms ),
  172. vertexShader: CopyShader.vertexShader,
  173. fragmentShader: CopyShader.fragmentShader,
  174. transparent: true,
  175. depthTest: false,
  176. depthWrite: false,
  177. blendSrc: DstColorFactor,
  178. blendDst: ZeroFactor,
  179. blendEquation: AddEquation,
  180. blendSrcAlpha: DstAlphaFactor,
  181. blendDstAlpha: ZeroFactor,
  182. blendEquationAlpha: AddEquation
  183. } );
  184. this.blendMaterial = new ShaderMaterial( {
  185. uniforms: UniformsUtils.clone( GTAOBlendShader.uniforms ),
  186. vertexShader: GTAOBlendShader.vertexShader,
  187. fragmentShader: GTAOBlendShader.fragmentShader,
  188. transparent: true,
  189. depthTest: false,
  190. depthWrite: false,
  191. blending: CustomBlending,
  192. blendSrc: DstColorFactor,
  193. blendDst: ZeroFactor,
  194. blendEquation: AddEquation,
  195. blendSrcAlpha: DstAlphaFactor,
  196. blendDstAlpha: ZeroFactor,
  197. blendEquationAlpha: AddEquation
  198. } );
  199. this._fsQuad = new FullScreenQuad( null );
  200. this._originalClearColor = new Color();
  201. this.setGBuffer( parameters ? parameters.depthTexture : undefined, parameters ? parameters.normalTexture : undefined );
  202. if ( aoParameters !== undefined ) {
  203. this.updateGtaoMaterial( aoParameters );
  204. }
  205. if ( pdParameters !== undefined ) {
  206. this.updatePdMaterial( pdParameters );
  207. }
  208. }
  209. /**
  210. * Sets the size of the pass.
  211. *
  212. * @param {number} width - The width to set.
  213. * @param {number} height - The width to set.
  214. */
  215. setSize( width, height ) {
  216. this.width = width;
  217. this.height = height;
  218. this.gtaoRenderTarget.setSize( width, height );
  219. this.normalRenderTarget.setSize( width, height );
  220. this.pdRenderTarget.setSize( width, height );
  221. this.gtaoMaterial.uniforms.resolution.value.set( width, height );
  222. this.gtaoMaterial.uniforms.cameraProjectionMatrix.value.copy( this.camera.projectionMatrix );
  223. this.gtaoMaterial.uniforms.cameraProjectionMatrixInverse.value.copy( this.camera.projectionMatrixInverse );
  224. this.pdMaterial.uniforms.resolution.value.set( width, height );
  225. this.pdMaterial.uniforms.cameraProjectionMatrixInverse.value.copy( this.camera.projectionMatrixInverse );
  226. }
  227. /**
  228. * Frees the GPU-related resources allocated by this instance. Call this
  229. * method whenever the pass is no longer used in your app.
  230. */
  231. dispose() {
  232. this.gtaoNoiseTexture.dispose();
  233. this.pdNoiseTexture.dispose();
  234. this.normalRenderTarget.dispose();
  235. this.gtaoRenderTarget.dispose();
  236. this.pdRenderTarget.dispose();
  237. this.normalMaterial.dispose();
  238. this.pdMaterial.dispose();
  239. this.copyMaterial.dispose();
  240. this.depthRenderMaterial.dispose();
  241. this._fsQuad.dispose();
  242. }
  243. /**
  244. * A texture holding the computed AO.
  245. *
  246. * @type {Texture}
  247. * @readonly
  248. */
  249. get gtaoMap() {
  250. return this.pdRenderTarget.texture;
  251. }
  252. /**
  253. * Configures the GBuffer of this pass. If no arguments are passed,
  254. * the pass creates an internal render target for holding depth
  255. * and normal data.
  256. *
  257. * @param {DepthTexture} [depthTexture] - The depth texture.
  258. * @param {DepthTexture} [normalTexture] - The normal texture.
  259. */
  260. setGBuffer( depthTexture, normalTexture ) {
  261. if ( depthTexture !== undefined ) {
  262. this.depthTexture = depthTexture;
  263. this.normalTexture = normalTexture;
  264. this._renderGBuffer = false;
  265. } else {
  266. this.depthTexture = new DepthTexture();
  267. this.depthTexture.format = DepthStencilFormat;
  268. this.depthTexture.type = UnsignedInt248Type;
  269. this.normalRenderTarget = new WebGLRenderTarget( this.width, this.height, {
  270. minFilter: NearestFilter,
  271. magFilter: NearestFilter,
  272. type: HalfFloatType,
  273. depthTexture: this.depthTexture
  274. } );
  275. this.normalTexture = this.normalRenderTarget.texture;
  276. this._renderGBuffer = true;
  277. }
  278. const normalVectorType = ( this.normalTexture ) ? 1 : 0;
  279. const depthValueSource = ( this.depthTexture === this.normalTexture ) ? 'w' : 'x';
  280. this.gtaoMaterial.defines.NORMAL_VECTOR_TYPE = normalVectorType;
  281. this.gtaoMaterial.defines.DEPTH_SWIZZLING = depthValueSource;
  282. this.gtaoMaterial.uniforms.tNormal.value = this.normalTexture;
  283. this.gtaoMaterial.uniforms.tDepth.value = this.depthTexture;
  284. this.pdMaterial.defines.NORMAL_VECTOR_TYPE = normalVectorType;
  285. this.pdMaterial.defines.DEPTH_SWIZZLING = depthValueSource;
  286. this.pdMaterial.uniforms.tNormal.value = this.normalTexture;
  287. this.pdMaterial.uniforms.tDepth.value = this.depthTexture;
  288. this.depthRenderMaterial.uniforms.tDepth.value = this.normalRenderTarget.depthTexture;
  289. }
  290. /**
  291. * Configures the clip box of the GTAO shader with the given AABB.
  292. *
  293. * @param {?Box3} box - The AABB enclosing the scene that should receive AO. When passing
  294. * `null`, to clip box is used.
  295. */
  296. setSceneClipBox( box ) {
  297. if ( box ) {
  298. this.gtaoMaterial.needsUpdate = this.gtaoMaterial.defines.SCENE_CLIP_BOX !== 1;
  299. this.gtaoMaterial.defines.SCENE_CLIP_BOX = 1;
  300. this.gtaoMaterial.uniforms.sceneBoxMin.value.copy( box.min );
  301. this.gtaoMaterial.uniforms.sceneBoxMax.value.copy( box.max );
  302. } else {
  303. this.gtaoMaterial.needsUpdate = this.gtaoMaterial.defines.SCENE_CLIP_BOX === 0;
  304. this.gtaoMaterial.defines.SCENE_CLIP_BOX = 0;
  305. }
  306. }
  307. /**
  308. * Updates the GTAO material from the given parameter object.
  309. *
  310. * @param {Object} parameters - The GTAO material parameters.
  311. */
  312. updateGtaoMaterial( parameters ) {
  313. if ( parameters.radius !== undefined ) {
  314. this.gtaoMaterial.uniforms.radius.value = parameters.radius;
  315. }
  316. if ( parameters.distanceExponent !== undefined ) {
  317. this.gtaoMaterial.uniforms.distanceExponent.value = parameters.distanceExponent;
  318. }
  319. if ( parameters.thickness !== undefined ) {
  320. this.gtaoMaterial.uniforms.thickness.value = parameters.thickness;
  321. }
  322. if ( parameters.distanceFallOff !== undefined ) {
  323. this.gtaoMaterial.uniforms.distanceFallOff.value = parameters.distanceFallOff;
  324. this.gtaoMaterial.needsUpdate = true;
  325. }
  326. if ( parameters.scale !== undefined ) {
  327. this.gtaoMaterial.uniforms.scale.value = parameters.scale;
  328. }
  329. if ( parameters.samples !== undefined && parameters.samples !== this.gtaoMaterial.defines.SAMPLES ) {
  330. this.gtaoMaterial.defines.SAMPLES = parameters.samples;
  331. this.gtaoMaterial.needsUpdate = true;
  332. }
  333. if ( parameters.screenSpaceRadius !== undefined && ( parameters.screenSpaceRadius ? 1 : 0 ) !== this.gtaoMaterial.defines.SCREEN_SPACE_RADIUS ) {
  334. this.gtaoMaterial.defines.SCREEN_SPACE_RADIUS = parameters.screenSpaceRadius ? 1 : 0;
  335. this.gtaoMaterial.needsUpdate = true;
  336. }
  337. }
  338. /**
  339. * Updates the Denoise material from the given parameter object.
  340. *
  341. * @param {Object} parameters - The denoise parameters.
  342. */
  343. updatePdMaterial( parameters ) {
  344. let updateShader = false;
  345. if ( parameters.lumaPhi !== undefined ) {
  346. this.pdMaterial.uniforms.lumaPhi.value = parameters.lumaPhi;
  347. }
  348. if ( parameters.depthPhi !== undefined ) {
  349. this.pdMaterial.uniforms.depthPhi.value = parameters.depthPhi;
  350. }
  351. if ( parameters.normalPhi !== undefined ) {
  352. this.pdMaterial.uniforms.normalPhi.value = parameters.normalPhi;
  353. }
  354. if ( parameters.radius !== undefined && parameters.radius !== this.radius ) {
  355. this.pdMaterial.uniforms.radius.value = parameters.radius;
  356. }
  357. if ( parameters.radiusExponent !== undefined && parameters.radiusExponent !== this.pdRadiusExponent ) {
  358. this.pdRadiusExponent = parameters.radiusExponent;
  359. updateShader = true;
  360. }
  361. if ( parameters.rings !== undefined && parameters.rings !== this.pdRings ) {
  362. this.pdRings = parameters.rings;
  363. updateShader = true;
  364. }
  365. if ( parameters.samples !== undefined && parameters.samples !== this.pdSamples ) {
  366. this.pdSamples = parameters.samples;
  367. updateShader = true;
  368. }
  369. if ( updateShader ) {
  370. this.pdMaterial.defines.SAMPLES = this.pdSamples;
  371. this.pdMaterial.defines.SAMPLE_VECTORS = generatePdSamplePointInitializer( this.pdSamples, this.pdRings, this.pdRadiusExponent );
  372. this.pdMaterial.needsUpdate = true;
  373. }
  374. }
  375. /**
  376. * Performs the GTAO pass.
  377. *
  378. * @param {WebGLRenderer} renderer - The renderer.
  379. * @param {WebGLRenderTarget} writeBuffer - The write buffer. This buffer is intended as the rendering
  380. * destination for the pass.
  381. * @param {WebGLRenderTarget} readBuffer - The read buffer. The pass can access the result from the
  382. * previous pass from this buffer.
  383. * @param {number} deltaTime - The delta time in seconds.
  384. * @param {boolean} maskActive - Whether masking is active or not.
  385. */
  386. render( renderer, writeBuffer, readBuffer /*, deltaTime, maskActive */ ) {
  387. // render normals and depth (honor only meshes, points and lines do not contribute to AO)
  388. if ( this._renderGBuffer ) {
  389. this._overrideVisibility();
  390. this._renderOverride( renderer, this.normalMaterial, this.normalRenderTarget, 0x7777ff, 1.0 );
  391. this._restoreVisibility();
  392. }
  393. // render AO
  394. this.gtaoMaterial.uniforms.cameraNear.value = this.camera.near;
  395. this.gtaoMaterial.uniforms.cameraFar.value = this.camera.far;
  396. this.gtaoMaterial.uniforms.cameraProjectionMatrix.value.copy( this.camera.projectionMatrix );
  397. this.gtaoMaterial.uniforms.cameraProjectionMatrixInverse.value.copy( this.camera.projectionMatrixInverse );
  398. this.gtaoMaterial.uniforms.cameraWorldMatrix.value.copy( this.camera.matrixWorld );
  399. this._renderPass( renderer, this.gtaoMaterial, this.gtaoRenderTarget, 0xffffff, 1.0 );
  400. // render poisson denoise
  401. this.pdMaterial.uniforms.cameraProjectionMatrixInverse.value.copy( this.camera.projectionMatrixInverse );
  402. this._renderPass( renderer, this.pdMaterial, this.pdRenderTarget, 0xffffff, 1.0 );
  403. // output result to screen
  404. switch ( this.output ) {
  405. case GTAOPass.OUTPUT.Off:
  406. break;
  407. case GTAOPass.OUTPUT.Diffuse:
  408. this.copyMaterial.uniforms.tDiffuse.value = readBuffer.texture;
  409. this.copyMaterial.blending = NoBlending;
  410. this._renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
  411. break;
  412. case GTAOPass.OUTPUT.AO:
  413. this.copyMaterial.uniforms.tDiffuse.value = this.gtaoRenderTarget.texture;
  414. this.copyMaterial.blending = NoBlending;
  415. this._renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
  416. break;
  417. case GTAOPass.OUTPUT.Denoise:
  418. this.copyMaterial.uniforms.tDiffuse.value = this.pdRenderTarget.texture;
  419. this.copyMaterial.blending = NoBlending;
  420. this._renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
  421. break;
  422. case GTAOPass.OUTPUT.Depth:
  423. this.depthRenderMaterial.uniforms.cameraNear.value = this.camera.near;
  424. this.depthRenderMaterial.uniforms.cameraFar.value = this.camera.far;
  425. this._renderPass( renderer, this.depthRenderMaterial, this.renderToScreen ? null : writeBuffer );
  426. break;
  427. case GTAOPass.OUTPUT.Normal:
  428. this.copyMaterial.uniforms.tDiffuse.value = this.normalRenderTarget.texture;
  429. this.copyMaterial.blending = NoBlending;
  430. this._renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
  431. break;
  432. case GTAOPass.OUTPUT.Default:
  433. this.copyMaterial.uniforms.tDiffuse.value = readBuffer.texture;
  434. this.copyMaterial.blending = NoBlending;
  435. this._renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
  436. this.blendMaterial.uniforms.intensity.value = this.blendIntensity;
  437. this.blendMaterial.uniforms.tDiffuse.value = this.pdRenderTarget.texture;
  438. this._renderPass( renderer, this.blendMaterial, this.renderToScreen ? null : writeBuffer );
  439. break;
  440. default:
  441. console.warn( 'THREE.GTAOPass: Unknown output type.' );
  442. }
  443. }
  444. // internals
  445. _renderPass( renderer, passMaterial, renderTarget, clearColor, clearAlpha ) {
  446. // save original state
  447. renderer.getClearColor( this._originalClearColor );
  448. const originalClearAlpha = renderer.getClearAlpha();
  449. const originalAutoClear = renderer.autoClear;
  450. renderer.setRenderTarget( renderTarget );
  451. // setup pass state
  452. renderer.autoClear = false;
  453. if ( ( clearColor !== undefined ) && ( clearColor !== null ) ) {
  454. renderer.setClearColor( clearColor );
  455. renderer.setClearAlpha( clearAlpha || 0.0 );
  456. renderer.clear();
  457. }
  458. this._fsQuad.material = passMaterial;
  459. this._fsQuad.render( renderer );
  460. // restore original state
  461. renderer.autoClear = originalAutoClear;
  462. renderer.setClearColor( this._originalClearColor );
  463. renderer.setClearAlpha( originalClearAlpha );
  464. }
  465. _renderOverride( renderer, overrideMaterial, renderTarget, clearColor, clearAlpha ) {
  466. renderer.getClearColor( this._originalClearColor );
  467. const originalClearAlpha = renderer.getClearAlpha();
  468. const originalAutoClear = renderer.autoClear;
  469. renderer.setRenderTarget( renderTarget );
  470. renderer.autoClear = false;
  471. clearColor = overrideMaterial.clearColor || clearColor;
  472. clearAlpha = overrideMaterial.clearAlpha || clearAlpha;
  473. if ( ( clearColor !== undefined ) && ( clearColor !== null ) ) {
  474. renderer.setClearColor( clearColor );
  475. renderer.setClearAlpha( clearAlpha || 0.0 );
  476. renderer.clear();
  477. }
  478. this.scene.overrideMaterial = overrideMaterial;
  479. renderer.render( this.scene, this.camera );
  480. this.scene.overrideMaterial = null;
  481. renderer.autoClear = originalAutoClear;
  482. renderer.setClearColor( this._originalClearColor );
  483. renderer.setClearAlpha( originalClearAlpha );
  484. }
  485. _overrideVisibility() {
  486. const scene = this.scene;
  487. const cache = this._visibilityCache;
  488. scene.traverse( function ( object ) {
  489. cache.set( object, object.visible );
  490. if ( object.isPoints || object.isLine ) object.visible = false;
  491. } );
  492. }
  493. _restoreVisibility() {
  494. const scene = this.scene;
  495. const cache = this._visibilityCache;
  496. scene.traverse( function ( object ) {
  497. const visible = cache.get( object );
  498. object.visible = visible;
  499. } );
  500. cache.clear();
  501. }
  502. _generateNoise( size = 64 ) {
  503. const simplex = new SimplexNoise();
  504. const arraySize = size * size * 4;
  505. const data = new Uint8Array( arraySize );
  506. for ( let i = 0; i < size; i ++ ) {
  507. for ( let j = 0; j < size; j ++ ) {
  508. const x = i;
  509. const y = j;
  510. data[ ( i * size + j ) * 4 ] = ( simplex.noise( x, y ) * 0.5 + 0.5 ) * 255;
  511. data[ ( i * size + j ) * 4 + 1 ] = ( simplex.noise( x + size, y ) * 0.5 + 0.5 ) * 255;
  512. data[ ( i * size + j ) * 4 + 2 ] = ( simplex.noise( x, y + size ) * 0.5 + 0.5 ) * 255;
  513. data[ ( i * size + j ) * 4 + 3 ] = ( simplex.noise( x + size, y + size ) * 0.5 + 0.5 ) * 255;
  514. }
  515. }
  516. const noiseTexture = new DataTexture( data, size, size, RGBAFormat, UnsignedByteType );
  517. noiseTexture.wrapS = RepeatWrapping;
  518. noiseTexture.wrapT = RepeatWrapping;
  519. noiseTexture.needsUpdate = true;
  520. return noiseTexture;
  521. }
  522. }
  523. GTAOPass.OUTPUT = {
  524. 'Off': - 1,
  525. 'Default': 0,
  526. 'Diffuse': 1,
  527. 'Depth': 2,
  528. 'Normal': 3,
  529. 'AO': 4,
  530. 'Denoise': 5,
  531. };
  532. export { GTAOPass };