Viewport.Pathtracer.js 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. import * as THREE from 'three';
  2. import { FullScreenQuad } from 'three/examples/jsm/postprocessing/Pass.js';
  3. import {
  4. PathTracingSceneGenerator,
  5. PathTracingRenderer,
  6. PhysicalPathTracingMaterial
  7. } from 'three-gpu-pathtracer';
  8. function buildColorTexture( color ) {
  9. const data = new Uint8Array( [ color.r * 255, color.g * 255, color.b * 255, 255 ] );
  10. const texture = new THREE.DataTexture( data, 1, 1, THREE.RGBAFormat );
  11. texture.needsUpdate = true;
  12. return texture;
  13. }
  14. function ViewportPathtracer( renderer ) {
  15. let pathtracer = null;
  16. let quad = null;
  17. function init( scene, camera ) {
  18. if ( pathtracer === null ) {
  19. pathtracer = new PathTracingRenderer( renderer );
  20. pathtracer.setSize( renderer.domElement.offsetWidth, renderer.domElement.offsetHeight );
  21. pathtracer.alpha = true;
  22. pathtracer.camera = camera;
  23. pathtracer.material = new PhysicalPathTracingMaterial();
  24. pathtracer.tiles.set( 3, 4 );
  25. quad = new FullScreenQuad( new THREE.MeshBasicMaterial( {
  26. map: pathtracer.target.texture,
  27. blending: THREE.CustomBlending
  28. } ) );
  29. }
  30. pathtracer.material.backgroundBlur = scene.backgroundBlurriness;
  31. pathtracer.reset();
  32. const generator = new PathTracingSceneGenerator();
  33. const { bvh, textures, materials, lights } = generator.generate( scene );
  34. const ptGeometry = bvh.geometry;
  35. const ptMaterial = pathtracer.material;
  36. ptMaterial.bvh.updateFrom( bvh );
  37. ptMaterial.attributesArray.updateFrom(
  38. ptGeometry.attributes.normal,
  39. ptGeometry.attributes.tangent,
  40. ptGeometry.attributes.uv,
  41. ptGeometry.attributes.color,
  42. );
  43. ptMaterial.materialIndexAttribute.updateFrom( ptGeometry.attributes.materialIndex );
  44. ptMaterial.textures.setTextures( renderer, 2048, 2048, textures );
  45. ptMaterial.materials.updateFrom( materials, textures );
  46. ptMaterial.lights.updateFrom( lights );
  47. const environment = scene.environment;
  48. if ( environment && environment.isTexture === true ) {
  49. ptMaterial.envMapInfo.updateFrom( scene.environment );
  50. } else {
  51. ptMaterial.envMapInfo.updateFrom( buildColorTexture( new THREE.Color( 0xffffff ) ) );
  52. }
  53. }
  54. function setSize( width, height ) {
  55. if ( pathtracer === null ) return;
  56. pathtracer.setSize( width, height );
  57. pathtracer.reset();
  58. }
  59. function update() {
  60. if ( pathtracer === null ) return;
  61. pathtracer.update();
  62. renderer.autoClear = false;
  63. quad.render( renderer );
  64. renderer.autoClear = true;
  65. }
  66. function reset() {
  67. if ( pathtracer === null ) return;
  68. pathtracer.reset();
  69. }
  70. return {
  71. init: init,
  72. setSize: setSize,
  73. update: update,
  74. reset: reset
  75. };
  76. }
  77. export { ViewportPathtracer };