SSRPass.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651
  1. import {
  2. AddEquation,
  3. Color,
  4. NormalBlending,
  5. DepthTexture,
  6. SrcAlphaFactor,
  7. OneMinusSrcAlphaFactor,
  8. MeshNormalMaterial,
  9. MeshBasicMaterial,
  10. NearestFilter,
  11. NoBlending,
  12. RGBAFormat,
  13. ShaderMaterial,
  14. UniformsUtils,
  15. UnsignedShortType,
  16. WebGLRenderTarget,
  17. HalfFloatType,
  18. } from '../../../build/three.module.js';
  19. import { Pass, FullScreenQuad } from './Pass.js';
  20. import { SSRShader } from '../shaders/SSRShader.js';
  21. import { SSRBlurShader } from '../shaders/SSRShader.js';
  22. import { SSRDepthShader } from '../shaders/SSRShader.js';
  23. import { CopyShader } from '../shaders/CopyShader.js';
  24. class SSRPass extends Pass {
  25. constructor( { renderer, scene, camera, width, height, selects, bouncing = false, groundReflector } ) {
  26. super();
  27. this.width = ( width !== undefined ) ? width : 512;
  28. this.height = ( height !== undefined ) ? height : 512;
  29. this.clear = true;
  30. this.renderer = renderer;
  31. this.scene = scene;
  32. this.camera = camera;
  33. this.groundReflector = groundReflector;
  34. this.opacity = SSRShader.uniforms.opacity.value;
  35. this.output = 0;
  36. this.maxDistance = SSRShader.uniforms.maxDistance.value;
  37. this.thickness = SSRShader.uniforms.thickness.value;
  38. this.tempColor = new Color();
  39. this._selects = selects;
  40. this.selective = Array.isArray( this._selects );
  41. Object.defineProperty( this, 'selects', {
  42. get() {
  43. return this._selects;
  44. },
  45. set( val ) {
  46. if ( this._selects === val ) return;
  47. this._selects = val;
  48. if ( Array.isArray( val ) ) {
  49. this.selective = true;
  50. this.ssrMaterial.defines.SELECTIVE = true;
  51. this.ssrMaterial.needsUpdate = true;
  52. } else {
  53. this.selective = false;
  54. this.ssrMaterial.defines.SELECTIVE = false;
  55. this.ssrMaterial.needsUpdate = true;
  56. }
  57. }
  58. } );
  59. this._bouncing = bouncing;
  60. Object.defineProperty( this, 'bouncing', {
  61. get() {
  62. return this._bouncing;
  63. },
  64. set( val ) {
  65. if ( this._bouncing === val ) return;
  66. this._bouncing = val;
  67. if ( val ) {
  68. this.ssrMaterial.uniforms[ 'tDiffuse' ].value = this.prevRenderTarget.texture;
  69. } else {
  70. this.ssrMaterial.uniforms[ 'tDiffuse' ].value = this.beautyRenderTarget.texture;
  71. }
  72. }
  73. } );
  74. this.blur = true;
  75. this._distanceAttenuation = SSRShader.defines.DISTANCE_ATTENUATION;
  76. Object.defineProperty( this, 'distanceAttenuation', {
  77. get() {
  78. return this._distanceAttenuation;
  79. },
  80. set( val ) {
  81. if ( this._distanceAttenuation === val ) return;
  82. this._distanceAttenuation = val;
  83. this.ssrMaterial.defines.DISTANCE_ATTENUATION = val;
  84. this.ssrMaterial.needsUpdate = true;
  85. }
  86. } );
  87. this._fresnel = SSRShader.defines.FRESNEL;
  88. Object.defineProperty( this, 'fresnel', {
  89. get() {
  90. return this._fresnel;
  91. },
  92. set( val ) {
  93. if ( this._fresnel === val ) return;
  94. this._fresnel = val;
  95. this.ssrMaterial.defines.FRESNEL = val;
  96. this.ssrMaterial.needsUpdate = true;
  97. }
  98. } );
  99. this._infiniteThick = SSRShader.defines.INFINITE_THICK;
  100. Object.defineProperty( this, 'infiniteThick', {
  101. get() {
  102. return this._infiniteThick;
  103. },
  104. set( val ) {
  105. if ( this._infiniteThick === val ) return;
  106. this._infiniteThick = val;
  107. this.ssrMaterial.defines.INFINITE_THICK = val;
  108. this.ssrMaterial.needsUpdate = true;
  109. }
  110. } );
  111. // beauty render target with depth buffer
  112. const depthTexture = new DepthTexture();
  113. depthTexture.type = UnsignedShortType;
  114. depthTexture.minFilter = NearestFilter;
  115. depthTexture.magFilter = NearestFilter;
  116. this.beautyRenderTarget = new WebGLRenderTarget( this.width, this.height, {
  117. minFilter: NearestFilter,
  118. magFilter: NearestFilter,
  119. format: RGBAFormat,
  120. depthTexture: depthTexture,
  121. depthBuffer: true
  122. } );
  123. //for bouncing
  124. this.prevRenderTarget = new WebGLRenderTarget( this.width, this.height, {
  125. minFilter: NearestFilter,
  126. magFilter: NearestFilter,
  127. format: RGBAFormat,
  128. } );
  129. // normal render target
  130. this.normalRenderTarget = new WebGLRenderTarget( this.width, this.height, {
  131. minFilter: NearestFilter,
  132. magFilter: NearestFilter,
  133. format: RGBAFormat,
  134. type: HalfFloatType,
  135. } );
  136. // metalness render target
  137. this.metalnessRenderTarget = new WebGLRenderTarget( this.width, this.height, {
  138. minFilter: NearestFilter,
  139. magFilter: NearestFilter,
  140. format: RGBAFormat
  141. } );
  142. // ssr render target
  143. this.ssrRenderTarget = new WebGLRenderTarget( this.width, this.height, {
  144. minFilter: NearestFilter,
  145. magFilter: NearestFilter,
  146. format: RGBAFormat
  147. } );
  148. this.blurRenderTarget = this.ssrRenderTarget.clone();
  149. this.blurRenderTarget2 = this.ssrRenderTarget.clone();
  150. // this.blurRenderTarget3 = this.ssrRenderTarget.clone();
  151. // ssr material
  152. if ( SSRShader === undefined ) {
  153. console.error( 'THREE.SSRPass: The pass relies on SSRShader.' );
  154. }
  155. this.ssrMaterial = new ShaderMaterial( {
  156. defines: Object.assign( {}, SSRShader.defines, {
  157. MAX_STEP: Math.sqrt( this.width * this.width + this.height * this.height )
  158. } ),
  159. uniforms: UniformsUtils.clone( SSRShader.uniforms ),
  160. vertexShader: SSRShader.vertexShader,
  161. fragmentShader: SSRShader.fragmentShader,
  162. blending: NoBlending
  163. } );
  164. this.ssrMaterial.uniforms[ 'tDiffuse' ].value = this.beautyRenderTarget.texture;
  165. this.ssrMaterial.uniforms[ 'tNormal' ].value = this.normalRenderTarget.texture;
  166. this.ssrMaterial.defines.SELECTIVE = this.selective;
  167. this.ssrMaterial.needsUpdate = true;
  168. this.ssrMaterial.uniforms[ 'tMetalness' ].value = this.metalnessRenderTarget.texture;
  169. this.ssrMaterial.uniforms[ 'tDepth' ].value = this.beautyRenderTarget.depthTexture;
  170. this.ssrMaterial.uniforms[ 'cameraNear' ].value = this.camera.near;
  171. this.ssrMaterial.uniforms[ 'cameraFar' ].value = this.camera.far;
  172. this.ssrMaterial.uniforms[ 'thickness' ].value = this.thickness;
  173. this.ssrMaterial.uniforms[ 'resolution' ].value.set( this.width, this.height );
  174. this.ssrMaterial.uniforms[ 'cameraProjectionMatrix' ].value.copy( this.camera.projectionMatrix );
  175. this.ssrMaterial.uniforms[ 'cameraInverseProjectionMatrix' ].value.copy( this.camera.projectionMatrixInverse );
  176. // normal material
  177. this.normalMaterial = new MeshNormalMaterial();
  178. this.normalMaterial.blending = NoBlending;
  179. // metalnessOn material
  180. this.metalnessOnMaterial = new MeshBasicMaterial( {
  181. color: 'white'
  182. } );
  183. // metalnessOff material
  184. this.metalnessOffMaterial = new MeshBasicMaterial( {
  185. color: 'black'
  186. } );
  187. // blur material
  188. this.blurMaterial = new ShaderMaterial( {
  189. defines: Object.assign( {}, SSRBlurShader.defines ),
  190. uniforms: UniformsUtils.clone( SSRBlurShader.uniforms ),
  191. vertexShader: SSRBlurShader.vertexShader,
  192. fragmentShader: SSRBlurShader.fragmentShader
  193. } );
  194. this.blurMaterial.uniforms[ 'tDiffuse' ].value = this.ssrRenderTarget.texture;
  195. this.blurMaterial.uniforms[ 'resolution' ].value.set( this.width, this.height );
  196. // blur material 2
  197. this.blurMaterial2 = new ShaderMaterial( {
  198. defines: Object.assign( {}, SSRBlurShader.defines ),
  199. uniforms: UniformsUtils.clone( SSRBlurShader.uniforms ),
  200. vertexShader: SSRBlurShader.vertexShader,
  201. fragmentShader: SSRBlurShader.fragmentShader
  202. } );
  203. this.blurMaterial2.uniforms[ 'tDiffuse' ].value = this.blurRenderTarget.texture;
  204. this.blurMaterial2.uniforms[ 'resolution' ].value.set( this.width, this.height );
  205. // // blur material 3
  206. // this.blurMaterial3 = new ShaderMaterial({
  207. // defines: Object.assign({}, SSRBlurShader.defines),
  208. // uniforms: UniformsUtils.clone(SSRBlurShader.uniforms),
  209. // vertexShader: SSRBlurShader.vertexShader,
  210. // fragmentShader: SSRBlurShader.fragmentShader
  211. // });
  212. // this.blurMaterial3.uniforms['tDiffuse'].value = this.blurRenderTarget2.texture;
  213. // this.blurMaterial3.uniforms['resolution'].value.set(this.width, this.height);
  214. // material for rendering the depth
  215. this.depthRenderMaterial = new ShaderMaterial( {
  216. defines: Object.assign( {}, SSRDepthShader.defines ),
  217. uniforms: UniformsUtils.clone( SSRDepthShader.uniforms ),
  218. vertexShader: SSRDepthShader.vertexShader,
  219. fragmentShader: SSRDepthShader.fragmentShader,
  220. blending: NoBlending
  221. } );
  222. this.depthRenderMaterial.uniforms[ 'tDepth' ].value = this.beautyRenderTarget.depthTexture;
  223. this.depthRenderMaterial.uniforms[ 'cameraNear' ].value = this.camera.near;
  224. this.depthRenderMaterial.uniforms[ 'cameraFar' ].value = this.camera.far;
  225. // material for rendering the content of a render target
  226. this.copyMaterial = new ShaderMaterial( {
  227. uniforms: UniformsUtils.clone( CopyShader.uniforms ),
  228. vertexShader: CopyShader.vertexShader,
  229. fragmentShader: CopyShader.fragmentShader,
  230. transparent: true,
  231. depthTest: false,
  232. depthWrite: false,
  233. blendSrc: SrcAlphaFactor,
  234. blendDst: OneMinusSrcAlphaFactor,
  235. blendEquation: AddEquation,
  236. blendSrcAlpha: SrcAlphaFactor,
  237. blendDstAlpha: OneMinusSrcAlphaFactor,
  238. blendEquationAlpha: AddEquation,
  239. // premultipliedAlpha:true,
  240. } );
  241. this.fsQuad = new FullScreenQuad( null );
  242. this.originalClearColor = new Color();
  243. }
  244. dispose() {
  245. // dispose render targets
  246. this.beautyRenderTarget.dispose();
  247. this.prevRenderTarget.dispose();
  248. this.normalRenderTarget.dispose();
  249. this.metalnessRenderTarget.dispose();
  250. this.ssrRenderTarget.dispose();
  251. this.blurRenderTarget.dispose();
  252. this.blurRenderTarget2.dispose();
  253. // this.blurRenderTarget3.dispose();
  254. // dispose materials
  255. this.normalMaterial.dispose();
  256. this.metalnessOnMaterial.dispose();
  257. this.metalnessOffMaterial.dispose();
  258. this.blurMaterial.dispose();
  259. this.blurMaterial2.dispose();
  260. this.copyMaterial.dispose();
  261. this.depthRenderMaterial.dispose();
  262. // dipsose full screen quad
  263. this.fsQuad.dispose();
  264. }
  265. render( renderer, writeBuffer /*, readBuffer, deltaTime, maskActive */ ) {
  266. // render beauty and depth
  267. renderer.setRenderTarget( this.beautyRenderTarget );
  268. renderer.clear();
  269. if ( this.groundReflector ) {
  270. this.groundReflector.visible = false;
  271. this.groundReflector.doRender( this.renderer, this.scene, this.camera );
  272. this.groundReflector.visible = true;
  273. }
  274. renderer.render( this.scene, this.camera );
  275. if ( this.groundReflector ) this.groundReflector.visible = false;
  276. // render normals
  277. this.renderOverride( renderer, this.normalMaterial, this.normalRenderTarget, 0, 0 );
  278. // render metalnesses
  279. if ( this.selective ) {
  280. this.renderMetalness( renderer, this.metalnessOnMaterial, this.metalnessRenderTarget, 0, 0 );
  281. }
  282. // render SSR
  283. this.ssrMaterial.uniforms[ 'opacity' ].value = this.opacity;
  284. this.ssrMaterial.uniforms[ 'maxDistance' ].value = this.maxDistance;
  285. this.ssrMaterial.uniforms[ 'thickness' ].value = this.thickness;
  286. this.renderPass( renderer, this.ssrMaterial, this.ssrRenderTarget );
  287. // render blur
  288. if ( this.blur ) {
  289. this.renderPass( renderer, this.blurMaterial, this.blurRenderTarget );
  290. this.renderPass( renderer, this.blurMaterial2, this.blurRenderTarget2 );
  291. // this.renderPass(renderer, this.blurMaterial3, this.blurRenderTarget3);
  292. }
  293. // output result to screen
  294. switch ( this.output ) {
  295. case SSRPass.OUTPUT.Default:
  296. if ( this.bouncing ) {
  297. this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.beautyRenderTarget.texture;
  298. this.copyMaterial.blending = NoBlending;
  299. this.renderPass( renderer, this.copyMaterial, this.prevRenderTarget );
  300. if ( this.blur )
  301. this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.blurRenderTarget2.texture;
  302. else
  303. this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.ssrRenderTarget.texture;
  304. this.copyMaterial.blending = NormalBlending;
  305. this.renderPass( renderer, this.copyMaterial, this.prevRenderTarget );
  306. this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.prevRenderTarget.texture;
  307. this.copyMaterial.blending = NoBlending;
  308. this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
  309. } else {
  310. this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.beautyRenderTarget.texture;
  311. this.copyMaterial.blending = NoBlending;
  312. this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
  313. if ( this.blur )
  314. this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.blurRenderTarget2.texture;
  315. else
  316. this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.ssrRenderTarget.texture;
  317. this.copyMaterial.blending = NormalBlending;
  318. this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
  319. }
  320. break;
  321. case SSRPass.OUTPUT.SSR:
  322. if ( this.blur )
  323. this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.blurRenderTarget2.texture;
  324. else
  325. this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.ssrRenderTarget.texture;
  326. this.copyMaterial.blending = NoBlending;
  327. this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
  328. if ( this.bouncing ) {
  329. if ( this.blur )
  330. this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.blurRenderTarget2.texture;
  331. else
  332. this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.beautyRenderTarget.texture;
  333. this.copyMaterial.blending = NoBlending;
  334. this.renderPass( renderer, this.copyMaterial, this.prevRenderTarget );
  335. this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.ssrRenderTarget.texture;
  336. this.copyMaterial.blending = NormalBlending;
  337. this.renderPass( renderer, this.copyMaterial, this.prevRenderTarget );
  338. }
  339. break;
  340. case SSRPass.OUTPUT.Beauty:
  341. this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.beautyRenderTarget.texture;
  342. this.copyMaterial.blending = NoBlending;
  343. this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
  344. break;
  345. case SSRPass.OUTPUT.Depth:
  346. this.renderPass( renderer, this.depthRenderMaterial, this.renderToScreen ? null : writeBuffer );
  347. break;
  348. case SSRPass.OUTPUT.Normal:
  349. this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.normalRenderTarget.texture;
  350. this.copyMaterial.blending = NoBlending;
  351. this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
  352. break;
  353. case SSRPass.OUTPUT.Metalness:
  354. this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.metalnessRenderTarget.texture;
  355. this.copyMaterial.blending = NoBlending;
  356. this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
  357. break;
  358. default:
  359. console.warn( 'THREE.SSRPass: Unknown output type.' );
  360. }
  361. }
  362. renderPass( renderer, passMaterial, renderTarget, clearColor, clearAlpha ) {
  363. // save original state
  364. this.originalClearColor.copy( renderer.getClearColor( this.tempColor ) );
  365. const originalClearAlpha = renderer.getClearAlpha( this.tempColor );
  366. const originalAutoClear = renderer.autoClear;
  367. renderer.setRenderTarget( renderTarget );
  368. // setup pass state
  369. renderer.autoClear = false;
  370. if ( ( clearColor !== undefined ) && ( clearColor !== null ) ) {
  371. renderer.setClearColor( clearColor );
  372. renderer.setClearAlpha( clearAlpha || 0.0 );
  373. renderer.clear();
  374. }
  375. this.fsQuad.material = passMaterial;
  376. this.fsQuad.render( renderer );
  377. // restore original state
  378. renderer.autoClear = originalAutoClear;
  379. renderer.setClearColor( this.originalClearColor );
  380. renderer.setClearAlpha( originalClearAlpha );
  381. }
  382. renderOverride( renderer, overrideMaterial, renderTarget, clearColor, clearAlpha ) {
  383. this.originalClearColor.copy( renderer.getClearColor( this.tempColor ) );
  384. const originalClearAlpha = renderer.getClearAlpha( this.tempColor );
  385. const originalAutoClear = renderer.autoClear;
  386. renderer.setRenderTarget( renderTarget );
  387. renderer.autoClear = false;
  388. clearColor = overrideMaterial.clearColor || clearColor;
  389. clearAlpha = overrideMaterial.clearAlpha || clearAlpha;
  390. if ( ( clearColor !== undefined ) && ( clearColor !== null ) ) {
  391. renderer.setClearColor( clearColor );
  392. renderer.setClearAlpha( clearAlpha || 0.0 );
  393. renderer.clear();
  394. }
  395. this.scene.overrideMaterial = overrideMaterial;
  396. renderer.render( this.scene, this.camera );
  397. this.scene.overrideMaterial = null;
  398. // restore original state
  399. renderer.autoClear = originalAutoClear;
  400. renderer.setClearColor( this.originalClearColor );
  401. renderer.setClearAlpha( originalClearAlpha );
  402. }
  403. renderMetalness( renderer, overrideMaterial, renderTarget, clearColor, clearAlpha ) {
  404. this.originalClearColor.copy( renderer.getClearColor( this.tempColor ) );
  405. const originalClearAlpha = renderer.getClearAlpha( this.tempColor );
  406. const originalAutoClear = renderer.autoClear;
  407. renderer.setRenderTarget( renderTarget );
  408. renderer.autoClear = false;
  409. clearColor = overrideMaterial.clearColor || clearColor;
  410. clearAlpha = overrideMaterial.clearAlpha || clearAlpha;
  411. if ( ( clearColor !== undefined ) && ( clearColor !== null ) ) {
  412. renderer.setClearColor( clearColor );
  413. renderer.setClearAlpha( clearAlpha || 0.0 );
  414. renderer.clear();
  415. }
  416. this.scene.traverseVisible( child => {
  417. child._SSRPassBackupMaterial = child.material;
  418. if ( this._selects.includes( child ) ) {
  419. child.material = this.metalnessOnMaterial;
  420. } else {
  421. child.material = this.metalnessOffMaterial;
  422. }
  423. } );
  424. renderer.render( this.scene, this.camera );
  425. this.scene.traverseVisible( child => {
  426. child.material = child._SSRPassBackupMaterial;
  427. } );
  428. // restore original state
  429. renderer.autoClear = originalAutoClear;
  430. renderer.setClearColor( this.originalClearColor );
  431. renderer.setClearAlpha( originalClearAlpha );
  432. }
  433. setSize( width, height ) {
  434. this.width = width;
  435. this.height = height;
  436. this.ssrMaterial.defines.MAX_STEP = Math.sqrt( width * width + height * height );
  437. this.ssrMaterial.needsUpdate = true;
  438. this.beautyRenderTarget.setSize( width, height );
  439. this.prevRenderTarget.setSize( width, height );
  440. this.ssrRenderTarget.setSize( width, height );
  441. this.normalRenderTarget.setSize( width, height );
  442. this.metalnessRenderTarget.setSize( width, height );
  443. this.blurRenderTarget.setSize( width, height );
  444. this.blurRenderTarget2.setSize( width, height );
  445. // this.blurRenderTarget3.setSize(width, height);
  446. this.ssrMaterial.uniforms[ 'resolution' ].value.set( width, height );
  447. this.ssrMaterial.uniforms[ 'cameraProjectionMatrix' ].value.copy( this.camera.projectionMatrix );
  448. this.ssrMaterial.uniforms[ 'cameraInverseProjectionMatrix' ].value.copy( this.camera.projectionMatrixInverse );
  449. this.blurMaterial.uniforms[ 'resolution' ].value.set( width, height );
  450. this.blurMaterial2.uniforms[ 'resolution' ].value.set( width, height );
  451. }
  452. }
  453. SSRPass.OUTPUT = {
  454. 'Default': 0,
  455. 'SSR': 1,
  456. 'Beauty': 3,
  457. 'Depth': 4,
  458. 'Normal': 5,
  459. 'Metalness': 7,
  460. };
  461. export { SSRPass };