123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- import * as THREE from 'three';
- import { FullScreenQuad } from 'three/examples/jsm/postprocessing/Pass.js';
- import {
- PathTracingSceneGenerator,
- PathTracingRenderer,
- PhysicalPathTracingMaterial,
- ProceduralEquirectTexture,
- } from 'three-gpu-pathtracer';
- function buildColorTexture( color ) {
- const texture = new ProceduralEquirectTexture( 4, 4 );
- texture.generationCallback = ( polar, uv, coord, target ) => {
- target.copy( color );
- };
- texture.update();
- return texture;
- }
- function ViewportPathtracer( renderer ) {
- let generator = null;
- let pathtracer = null;
- let quad = null;
- let hdr = null;
- function init( scene, camera ) {
- if ( pathtracer === null ) {
- generator = new PathTracingSceneGenerator();
- pathtracer = new PathTracingRenderer( renderer );
- pathtracer.setSize( renderer.domElement.offsetWidth, renderer.domElement.offsetHeight );
- pathtracer.alpha = true;
- pathtracer.camera = camera;
- pathtracer.material = new PhysicalPathTracingMaterial();
- pathtracer.tiles.set( 3, 4 );
- quad = new FullScreenQuad( new THREE.MeshBasicMaterial( {
- map: pathtracer.target.texture,
- blending: THREE.CustomBlending
- } ) );
- }
- pathtracer.reset();
- const { bvh, textures, materials, lights } = generator.generate( scene );
- const ptGeometry = bvh.geometry;
- const ptMaterial = pathtracer.material;
- ptMaterial.bvh.updateFrom( bvh );
- ptMaterial.attributesArray.updateFrom(
- ptGeometry.attributes.normal,
- ptGeometry.attributes.tangent,
- ptGeometry.attributes.uv,
- ptGeometry.attributes.color,
- );
- ptMaterial.materialIndexAttribute.updateFrom( ptGeometry.attributes.materialIndex );
- ptMaterial.textures.setTextures( renderer, 2048, 2048, textures );
- ptMaterial.materials.updateFrom( materials, textures );
- ptMaterial.lights.updateFrom( lights );
- ptMaterial.filterGlossyFactor = 0.5;
- //
- setBackground( scene.background, scene.backgroundBlurriness );
- setEnvironment( scene.environment );
- }
- function setSize( width, height ) {
- if ( pathtracer === null ) return;
- pathtracer.setSize( width, height );
- pathtracer.reset();
- }
- function setBackground( background, blurriness ) {
- if ( pathtracer === null ) return;
- const ptMaterial = pathtracer.material;
- if ( background ) {
- if ( background.isTexture ) {
- ptMaterial.backgroundMap = background;
- ptMaterial.backgroundBlur = blurriness;
- } else if ( background.isColor ) {
- ptMaterial.backgroundMap = buildColorTexture( background );
- ptMaterial.backgroundBlur = 0;
- }
- } else {
- ptMaterial.backgroundMap = buildColorTexture( new THREE.Color( 0 ) );
- ptMaterial.backgroundBlur = 0;
- }
- pathtracer.reset();
- }
- function setEnvironment( environment ) {
- if ( pathtracer === null ) return;
- const ptMaterial = pathtracer.material;
- if ( environment && environment.isDataTexture === true ) {
- // Avoid calling envMapInfo() with the same hdr
- if ( environment !== hdr ) {
- ptMaterial.envMapInfo.updateFrom( environment );
- hdr = environment;
- }
- } else {
- ptMaterial.envMapInfo.updateFrom( buildColorTexture( new THREE.Color( 0 ) ) );
- }
- pathtracer.reset();
- }
- function update() {
- if ( pathtracer === null ) return;
- pathtracer.update();
- if ( pathtracer.samples >= 1 ) {
- renderer.autoClear = false;
- quad.render( renderer );
- renderer.autoClear = true;
- }
- }
- function reset() {
- if ( pathtracer === null ) return;
- pathtracer.reset();
- }
- return {
- init: init,
- setSize: setSize,
- setBackground: setBackground,
- setEnvironment: setEnvironment,
- update: update,
- reset: reset
- };
- }
- export { ViewportPathtracer };
|