Browse Source

Examples: Update examples to use WebGLPathTracer and three-gpu-pathter v0.0.21 (#28233)

* Update pathtracer example with v0.0.21

* Update demo
Garrett Johnson 1 year ago
parent
commit
d0440bb737
1 changed files with 61 additions and 131 deletions
  1. 61 131
      examples/webgl_renderer_pathtracer.html

+ 61 - 131
examples/webgl_renderer_pathtracer.html

@@ -44,8 +44,8 @@
 					"three": "../build/three.module.js",
 					"three": "../build/three.module.js",
 					"three/addons/": "./jsm/",
 					"three/addons/": "./jsm/",
 					"three/examples/": "./",
 					"three/examples/": "./",
-					"three-gpu-pathtracer": "https://cdn.jsdelivr.net/npm/[email protected]0/build/index.module.js",
-					"three-mesh-bvh": "https://cdn.jsdelivr.net/npm/[email protected].3/build/index.module.js"
+					"three-gpu-pathtracer": "https://cdn.jsdelivr.net/npm/[email protected]1/build/index.module.js",
+					"three-mesh-bvh": "https://cdn.jsdelivr.net/npm/[email protected].4/build/index.module.js"
 				}
 				}
 			}
 			}
 		</script>
 		</script>
@@ -60,14 +60,12 @@
 			import { RGBELoader } from 'three/addons/loaders/RGBELoader.js';
 			import { RGBELoader } from 'three/addons/loaders/RGBELoader.js';
 			import { LDrawLoader } from 'three/addons/loaders/LDrawLoader.js';
 			import { LDrawLoader } from 'three/addons/loaders/LDrawLoader.js';
 			import { LDrawUtils } from 'three/addons/utils/LDrawUtils.js';
 			import { LDrawUtils } from 'three/addons/utils/LDrawUtils.js';
-			import { FullScreenQuad } from 'three/addons/postprocessing/Pass.js';
 
 
-			import { PhysicalPathTracingMaterial, PathTracingRenderer, MaterialReducer, BlurredEnvMapGenerator, PathTracingSceneGenerator, GradientEquirectTexture } from 'three-gpu-pathtracer';
+			import { WebGLPathTracer, BlurredEnvMapGenerator, GradientEquirectTexture } from 'three-gpu-pathtracer';
 
 
 			let progressBarDiv, samplesEl;
 			let progressBarDiv, samplesEl;
 			let camera, scene, renderer, controls, gui;
 			let camera, scene, renderer, controls, gui;
-			let pathTracer, sceneInfo, fsQuad, floor;
-			let delaySamples = 0;
+			let pathTracer, floor, gradientMap;
 
 
 			const params = {
 			const params = {
 				enable: true,
 				enable: true,
@@ -89,7 +87,6 @@
 			};
 			};
 
 
 			init();
 			init();
-			render();
 
 
 			function init() {
 			function init() {
 
 
@@ -97,42 +94,32 @@
 				camera.position.set( 150, 200, 250 );
 				camera.position.set( 150, 200, 250 );
 
 
 				// initialize the renderer
 				// initialize the renderer
-				renderer = new THREE.WebGLRenderer( { antialias: true, preserveDrawingBuffer: true, premultipliedAlpha: false } );
+				renderer = new THREE.WebGLRenderer( { antialias: true, alpha: true, preserveDrawingBuffer: true, premultipliedAlpha: false } );
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				renderer.toneMapping = THREE.ACESFilmicToneMapping;
 				renderer.toneMapping = THREE.ACESFilmicToneMapping;
-				renderer.setClearColor( 0xdddddd );
 				document.body.appendChild( renderer.domElement );
 				document.body.appendChild( renderer.domElement );
 
 
-				const gradientMap = new GradientEquirectTexture();
+				gradientMap = new GradientEquirectTexture();
 				gradientMap.topColor.set( 0xeeeeee );
 				gradientMap.topColor.set( 0xeeeeee );
 				gradientMap.bottomColor.set( 0xeaeaea );
 				gradientMap.bottomColor.set( 0xeaeaea );
 				gradientMap.update();
 				gradientMap.update();
 
 
 				// initialize the pathtracer
 				// initialize the pathtracer
-				pathTracer = new PathTracingRenderer( renderer );
-				pathTracer.camera = camera;
-				pathTracer.alpha = true;
+				pathTracer = new WebGLPathTracer( renderer );
+				pathTracer.filterGlossyFactor = 1;
+				pathTracer.minSamples = 3;
+				pathTracer.renderScale = params.resolutionScale;
 				pathTracer.tiles.set( params.tiles, params.tiles );
 				pathTracer.tiles.set( params.tiles, params.tiles );
-				pathTracer.material = new PhysicalPathTracingMaterial( {
-					filterGlossyFactor: 0.5,
-					backgroundMap: gradientMap,
-				} );
-				pathTracer.material.setDefine( 'FEATURE_MIS', 1 );
-
-				fsQuad = new FullScreenQuad( new THREE.MeshBasicMaterial( {
-					map: pathTracer.target.texture,
-					blending: THREE.CustomBlending
-				} ) );
 
 
 				// scene
 				// scene
 				scene = new THREE.Scene();
 				scene = new THREE.Scene();
+				scene.background = gradientMap;
 
 
 				controls = new OrbitControls( camera, renderer.domElement );
 				controls = new OrbitControls( camera, renderer.domElement );
 				controls.addEventListener( 'change', () => {
 				controls.addEventListener( 'change', () => {
 
 
-					delaySamples = 5;
-					pathTracer.reset();
+					pathTracer.updateCamera();
 
 
 				} );
 				} );
 
 
@@ -161,7 +148,7 @@
 				progressBarDiv.innerText = 'Loading...';
 				progressBarDiv.innerText = 'Loading...';
 
 
 				let model = null;
 				let model = null;
-				let envMap = null;
+				let environment = null;
 
 
 				updateProgressBar( 0 );
 				updateProgressBar( 0 );
 				showProgressBar();
 				showProgressBar();
@@ -173,12 +160,22 @@
 						.loadAsync( 'models/7140-1-X-wingFighter.mpd_Packed.mpd', onProgress )
 						.loadAsync( 'models/7140-1-X-wingFighter.mpd_Packed.mpd', onProgress )
 						.then( function ( legoGroup ) {
 						.then( function ( legoGroup ) {
 
 
+							// Convert from LDraw coordinates: rotate 180 degrees around OX
 							legoGroup = LDrawUtils.mergeObject( legoGroup );
 							legoGroup = LDrawUtils.mergeObject( legoGroup );
 							legoGroup.rotation.x = Math.PI;
 							legoGroup.rotation.x = Math.PI;
+							legoGroup.updateMatrixWorld();
+							model = legoGroup;
 
 
-							// adjust the materials to use transmission, be a bit shinier
 							legoGroup.traverse( c => {
 							legoGroup.traverse( c => {
 
 
+								// hide the line segments
+								if ( c.isLineSegments ) {
+
+									c.visible = false;
+
+								}
+
+								// adjust the materials to use transmission, be a bit shinier
 								if ( c.material ) {
 								if ( c.material ) {
 
 
 									c.material.roughness *= 0.25;
 									c.material.roughness *= 0.25;
@@ -190,6 +187,7 @@
 
 
 										newMaterial.opacity = 1.0;
 										newMaterial.opacity = 1.0;
 										newMaterial.transmission = 1.0;
 										newMaterial.transmission = 1.0;
+										newMaterial.thickness = 1.0;
 										newMaterial.ior = 1.4;
 										newMaterial.ior = 1.4;
 										newMaterial.roughness = oldMaterial.roughness;
 										newMaterial.roughness = oldMaterial.roughness;
 										newMaterial.metalness = 0.0;
 										newMaterial.metalness = 0.0;
@@ -207,12 +205,6 @@
 
 
 							} );
 							} );
 
 
-							model = new THREE.Group();
-							model.add( legoGroup );
-
-							// Convert from LDraw coordinates: rotate 180 degrees around OX
-							model.updateMatrixWorld();
-
 						} )
 						} )
 						.catch( onError );
 						.catch( onError );
 
 
@@ -225,16 +217,19 @@
 							const envMapGenerator = new BlurredEnvMapGenerator( renderer );
 							const envMapGenerator = new BlurredEnvMapGenerator( renderer );
 							const blurredEnvMap = envMapGenerator.generate( tex, 0 );
 							const blurredEnvMap = envMapGenerator.generate( tex, 0 );
 
 
-							scene.environment = blurredEnvMap;
-							envMap = blurredEnvMap;
+							environment = blurredEnvMap;
 
 
-						} );
+						} )
+						.catch( onError );
 
 
 				await Promise.all( [ envMapPromise, ldrawPromise ] );
 				await Promise.all( [ envMapPromise, ldrawPromise ] );
 
 
 				hideProgressBar();
 				hideProgressBar();
 				document.body.classList.add( 'checkerboard' );
 				document.body.classList.add( 'checkerboard' );
 
 
+				// set environment map
+				scene.environment = environment;
+
 				// Adjust camera
 				// Adjust camera
 				const bbox = new THREE.Box3().setFromObject( model );
 				const bbox = new THREE.Box3().setFromObject( model );
 				const size = bbox.getSize( new THREE.Vector3() );
 				const size = bbox.getSize( new THREE.Vector3() );
@@ -244,13 +239,16 @@
 				controls.position0.set( 2.3, 1, 2 ).multiplyScalar( radius ).add( controls.target0 );
 				controls.position0.set( 2.3, 1, 2 ).multiplyScalar( radius ).add( controls.target0 );
 				controls.reset();
 				controls.reset();
 
 
+				// add the model
+				scene.add( model );
+
 				// add floor
 				// add floor
 				floor = new THREE.Mesh(
 				floor = new THREE.Mesh(
 					new THREE.PlaneGeometry(),
 					new THREE.PlaneGeometry(),
 					new THREE.MeshStandardMaterial( {
 					new THREE.MeshStandardMaterial( {
 						side: THREE.DoubleSide,
 						side: THREE.DoubleSide,
-						roughness: 0.01,
-						metalness: 1,
+						roughness: params.roughness,
+						metalness: params.metalness,
 						map: generateRadialFloorTexture( 1024 ),
 						map: generateRadialFloorTexture( 1024 ),
 						transparent: true,
 						transparent: true,
 					} ),
 					} ),
@@ -258,50 +256,14 @@
 				floor.scale.setScalar( 2500 );
 				floor.scale.setScalar( 2500 );
 				floor.rotation.x = - Math.PI / 2;
 				floor.rotation.x = - Math.PI / 2;
 				floor.position.y = bbox.min.y;
 				floor.position.y = bbox.min.y;
-				model.add( floor );
-				model.updateMatrixWorld();
-
-				// de-duplicate and reduce the number of materials used in place
-				const reducer = new MaterialReducer();
-				reducer.process( model );
+				scene.add( floor );
 
 
 				// reset the progress bar to display bvh generation
 				// reset the progress bar to display bvh generation
 				progressBarDiv.innerText = 'Generating BVH...';
 				progressBarDiv.innerText = 'Generating BVH...';
 				updateProgressBar( 0 );
 				updateProgressBar( 0 );
 
 
-				const generator = new PathTracingSceneGenerator();
-				const result = generator.generate( model );
-
-				// add the model to the scene
-				sceneInfo = result;
-				model.traverse( c => {
-
-					if ( c.isLineSegments ) {
-
-						c.visible = false;
-
-					}
-
-				} );
-				scene.add( model );
-
-				// update the material
-				const { bvh, textures, materials } = result;
-				const geometry = bvh.geometry;
-				const material = pathTracer.material;
-
-				material.bvh.updateFrom( bvh );
-				material.attributesArray.updateFrom(
-					geometry.attributes.normal,
-					geometry.attributes.tangent,
-					geometry.attributes.uv,
-					geometry.attributes.color,
-				);
-				material.materialIndexAttribute.updateFrom( geometry.attributes.materialIndex );
-				material.textures.setTextures( renderer, 2048, 2048, textures );
-				material.materials.updateFrom( materials, textures );
-				pathTracer.material.envMapInfo.updateFrom( envMap );
-				pathTracer.reset();
+				pathTracer.setScene( scene, camera );
+				render();
 
 
 			}
 			}
 
 
@@ -309,19 +271,17 @@
 
 
 				const w = window.innerWidth;
 				const w = window.innerWidth;
 				const h = window.innerHeight;
 				const h = window.innerHeight;
-				const scale = params.resolutionScale;
 				const dpr = window.devicePixelRatio;
 				const dpr = window.devicePixelRatio;
 
 
-				pathTracer.setSize( w * scale * dpr, h * scale * dpr );
-				pathTracer.reset();
-
 				renderer.setSize( w, h );
 				renderer.setSize( w, h );
-				renderer.setPixelRatio( window.devicePixelRatio * scale );
+				renderer.setPixelRatio( dpr );
 
 
 				const aspect = w / h;
 				const aspect = w / h;
 				camera.aspect = aspect;
 				camera.aspect = aspect;
 				camera.updateProjectionMatrix();
 				camera.updateProjectionMatrix();
 
 
+				pathTracer.updateCamera();
+
 			}
 			}
 
 
 			function createGUI() {
 			function createGUI() {
@@ -338,25 +298,31 @@
 				gui.add( params, 'toneMapping' );
 				gui.add( params, 'toneMapping' );
 				gui.add( params, 'transparentBackground' ).onChange( v => {
 				gui.add( params, 'transparentBackground' ).onChange( v => {
 
 
-					pathTracer.material.backgroundAlpha = v ? 0 : 1;
-					renderer.setClearAlpha( v ? 0 : 1 );
+					scene.background = v ? null : gradientMap;
+					pathTracer.updateEnvironment();
+
+				} );
+				gui.add( params, 'resolutionScale', 0.1, 1.0, 0.1 ).onChange( v => {
+
+					pathTracer.renderScale = v;
 					pathTracer.reset();
 					pathTracer.reset();
 
 
 				} );
 				} );
-				gui.add( params, 'resolutionScale', 0.1, 1.0, 0.1 ).onChange( onWindowResize );
-				gui.add( params, 'tiles', 1, 3, 1 ).onChange( v => {
+				gui.add( params, 'tiles', 1, 6, 1 ).onChange( v => {
 
 
 					pathTracer.tiles.set( v, v );
 					pathTracer.tiles.set( v, v );
 
 
 				} );
 				} );
-				gui.add( params, 'roughness', 0, 1 ).name( 'floor roughness' ).onChange( () => {
+				gui.add( params, 'roughness', 0, 1 ).name( 'floor roughness' ).onChange( v => {
 
 
-					pathTracer.reset();
+					floor.material.roughness = v;
+					pathTracer.updateMaterials();
 
 
 				} );
 				} );
-				gui.add( params, 'metalness', 0, 1 ).name( 'floor metalness' ).onChange( () => {
+				gui.add( params, 'metalness', 0, 1 ).name( 'floor metalness' ).onChange( v => {
 
 
-					pathTracer.reset();
+					floor.material.metalness = v;
+					pathTracer.updateMaterials();
 
 
 				} );
 				} );
 				gui.add( params, 'download' ).name( 'download image' );
 				gui.add( params, 'download' ).name( 'download image' );
@@ -370,7 +336,6 @@
 				renderFolder.$children.appendChild( samplesEl );
 				renderFolder.$children.appendChild( samplesEl );
 				renderFolder.open();
 				renderFolder.open();
 
 
-
 			}
 			}
 
 
 			//
 			//
@@ -379,49 +344,14 @@
 
 
 				requestAnimationFrame( render );
 				requestAnimationFrame( render );
 
 
-				if ( ! sceneInfo ) {
-
-					return;
-
-				}
-
 				renderer.toneMapping = params.toneMapping ? THREE.ACESFilmicToneMapping : THREE.NoToneMapping;
 				renderer.toneMapping = params.toneMapping ? THREE.ACESFilmicToneMapping : THREE.NoToneMapping;
 
 
-				if ( pathTracer.samples < 1.0 || ! params.enable ) {
-
-					renderer.render( scene, camera );
-
-				}
+				const samples = Math.floor( pathTracer.samples );
+				samplesEl.innerText = `samples: ${ samples }`;
 
 
-				if ( params.enable && delaySamples === 0 ) {
-
-					const samples = Math.floor( pathTracer.samples );
-					samplesEl.innerText = `samples: ${ samples }`;
-
-					floor.material.roughness = params.roughness;
-					floor.material.metalness = params.metalness;
-
-					pathTracer.material.materials.updateFrom( sceneInfo.materials, sceneInfo.textures );
-					pathTracer.material.filterGlossyFactor = 1;
-					pathTracer.material.physicalCamera.updateFrom( camera );
-
-					camera.updateMatrixWorld();
-
-					if ( ! params.pause || pathTracer.samples < 1 ) {
-
-						pathTracer.update();
-
-					}
-
-					renderer.autoClear = false;
-					fsQuad.render( renderer );
-					renderer.autoClear = true;
-
-				} else if ( delaySamples > 0 ) {
-
-					delaySamples --;
-
-				}
+				pathTracer.enablePathTracing = params.enable;
+				pathTracer.pausePathTracing = params.pause;
+				pathTracer.renderSample();
 
 
 				samplesEl.innerText = `samples: ${ Math.floor( pathTracer.samples ) }`;
 				samplesEl.innerText = `samples: ${ Math.floor( pathTracer.samples ) }`;