GTAOPass.js 19 KB

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