Browse Source

Merge pull request #18407 from WestLangley/dev_tonemapping_example2

Added new tone mapping example
WestLangley 5 years ago
parent
commit
1fde8b8556
1 changed files with 109 additions and 162 deletions
  1. 109 162
      examples/webgl_tonemapping.html

+ 109 - 162
examples/webgl_tonemapping.html

@@ -1,40 +1,38 @@
 <!DOCTYPE html>
 <html lang="en">
 	<head>
-		<title>three.js webgl - inline tone mapping</title>
+		<title>three.js webgl - tone mapping</title>
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
 		<link type="text/css" rel="stylesheet" href="main.css">
 	</head>
-	<body>
 
-		<div id="container"></div>
-		<div id="info"><a href="https://threejs.org" target="_blank" rel="noopener">threejs</a> - Inline Tone Mapping (within a Material's fragment shader) without<br/>using a pre-processing step or float/half buffers by <a href="http://clara.io/" target="_blank" rel="noopener">Ben Houston</a>.</div>
+	<body>
+		<div id="info">
+			<a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> - Tone Mapping<br />
+			Battle Damaged Sci-fi Helmet by
+			<a href="https://sketchfab.com/theblueturtle_" target="_blank" rel="noopener">theblueturtle_</a><br />
+			<a href="https://hdrihaven.com/hdri/?h=royal_esplanade" target="_blank" rel="noopener">Royal Esplanade</a> by <a href="https://hdrihaven.com/" target="_blank" rel="noopener">HDRI Haven</a>
+		</div>
 
 		<script type="module">
 
 			import * as THREE from '../build/three.module.js';
 
-			import Stats from './jsm/libs/stats.module.js';
-
 			import { GUI } from './jsm/libs/dat.gui.module.js';
 			import { OrbitControls } from './jsm/controls/OrbitControls.js';
+			import { GLTFLoader } from './jsm/loaders/GLTFLoader.js';
 			import { RGBELoader } from './jsm/loaders/RGBELoader.js';
 
-			import { EffectComposer } from './jsm/postprocessing/EffectComposer.js';
-			import { RenderPass } from './jsm/postprocessing/RenderPass.js';
-			import { ShaderPass } from './jsm/postprocessing/ShaderPass.js';
-			import { CopyShader } from './jsm/shaders/CopyShader.js';
+			var mesh, renderer, scene, camera, controls;
+			var gui,
+				guiWhitePoint = null,
+				guiExposure = null;
 
-			var container, stats;
 			var params = {
-				opacity: 1.0,
-				roughness: 1.0,
-				bumpScale: 1.0,
-				exposure: 2.0,
-				whitePoint: 5.0,
-				toneMapping: "Uncharted2",
-				renderMode: "Renderer"
+				exposure: 0.8,
+				whitePoint: 1.0, // applies to Uncharted2 only
+				toneMapping: 'ACESFilmic'
 			};
 
 			var toneMappingOptions = {
@@ -46,206 +44,155 @@
 				ACESFilmic: THREE.ACESFilmicToneMapping
 			};
 
-			var camera, scene, renderer, mesh;
-			var composer;
-			var standardMaterial, floorMaterial;
-
 			init();
-			animate();
+			render();
 
 			function init() {
 
-				container = document.createElement( 'div' );
-				document.body.appendChild( container );
+				renderer = new THREE.WebGLRenderer( { antialias: true } );
+				renderer.setPixelRatio( window.devicePixelRatio );
+				renderer.setSize( window.innerWidth, window.innerHeight );
+				document.body.appendChild( renderer.domElement );
+
+				renderer.toneMapping = toneMappingOptions[ params.toneMapping ];
+				renderer.toneMappingWhitePoint = params.whitePoint;
+				renderer.toneMappingExposure = params.exposure;
 
-				camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 2000 );
-				camera.position.set( 0.0, 40, 40 * 3.5 );
+				renderer.outputEncoding = THREE.sRGBEncoding;
 
 				scene = new THREE.Scene();
 
-				renderer = new THREE.WebGLRenderer();
-
-				standardMaterial = new THREE.MeshStandardMaterial( {
-					bumpScale: - 0.05,
-					color: 0xffffff,
-					metalness: 0.9,
-					roughness: 0.8,
-					premultipliedAlpha: true,
-					transparent: true
-				} );
-
-				var textureLoader = new THREE.TextureLoader();
-				textureLoader.load( "textures/brick_diffuse.jpg", function ( map ) {
-
-					map.wrapS = THREE.RepeatWrapping;
-					map.wrapT = THREE.RepeatWrapping;
-					map.encoding = THREE.sRGBEncoding;
-					map.anisotropy = 4;
-					map.repeat.set( 9, 0.5 );
-					standardMaterial.map = map;
-					standardMaterial.needsUpdate = true;
-
-				} );
-
-				textureLoader.load( "textures/brick_bump.jpg", function ( map ) {
-
-					map.wrapS = THREE.RepeatWrapping;
-					map.wrapT = THREE.RepeatWrapping;
-					map.anisotropy = 4;
-					map.repeat.set( 9, 0.5 );
-					standardMaterial.bumpMap = map;
-					standardMaterial.needsUpdate = true;
-
-				} );
-
-				textureLoader.load( "textures/brick_roughness.jpg", function ( map ) {
-
-					map.wrapS = THREE.RepeatWrapping;
-					map.wrapT = THREE.RepeatWrapping;
-					map.anisotropy = 4;
-					map.repeat.set( 9, 0.5 );
-					standardMaterial.roughnessMap = map;
-					standardMaterial.needsUpdate = true;
-
-				} );
-
-				var geometry = new THREE.TorusKnotBufferGeometry( 18, 8, 150, 20 );
-				mesh = new THREE.Mesh( geometry, standardMaterial );
-				mesh.castShadow = true;
-				mesh.receiveShadow = true;
-				scene.add( mesh );
-
-				floorMaterial = new THREE.MeshStandardMaterial( {
-					map: null,
-					roughnessMap: null,
-					color: 0x888888,
-					metalness: 0.0,
-					roughness: 1.0,
-					side: THREE.BackSide
-				} );
-
-				var geometry = new THREE.BoxBufferGeometry( 200, 200, 200 );
-				var floor = new THREE.Mesh( geometry, floorMaterial );
-				floor.position.y = 50;
-				floor.rotation.x = - Math.PI * 0.5;
-				floor.receiveShadow = true;
-				scene.add( floor );
+				camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.25, 20 );
+				camera.position.set( - 1.8, 0.6, 2.7 );
+
+				controls = new OrbitControls( camera, renderer.domElement );
+				controls.addEventListener( 'change', render ); // use if there is no animation loop
+				controls.enableZoom = false;
+				controls.enablePan = false;
+				controls.target.set( 0, 0, - 0.2 );
+				controls.update();
+
+				var pmremGenerator = new THREE.PMREMGenerator( renderer );
+				pmremGenerator.compileEquirectangularShader();
 
 				new RGBELoader()
 					.setDataType( THREE.UnsignedByteType )
 					.setPath( 'textures/equirectangular/' )
-					.load( 'venice_sunset_1k.hdr', function ( hdrEquirect ) {
+					.load( 'royal_esplanade_1k.hdr', function ( texture ) {
 
-						scene.environment = pmremGenerator.fromEquirectangular( hdrEquirect ).texture;
+						var envMap = pmremGenerator.fromEquirectangular( texture ).texture;
 
-						hdrEquirect.dispose();
+						scene.background = envMap;
+						scene.environment = envMap;
+
+						texture.dispose();
 						pmremGenerator.dispose();
 
-					} );
+						render();
 
-				var pmremGenerator = new THREE.PMREMGenerator( renderer );
-				pmremGenerator.compileEquirectangularShader();
+						// model
 
-				// Lights
+						var loader = new GLTFLoader().setPath( 'models/gltf/DamagedHelmet/glTF/' );
+						loader.load( 'DamagedHelmet.gltf', function ( gltf ) {
 
-				scene.add( new THREE.HemisphereLight( 0x111111, 0x000000 ) );
+							gltf.scene.traverse( function ( child ) {
 
-				var spotLight = new THREE.SpotLight( 0xffffff );
-				spotLight.position.set( 50, 100, 50 );
-				spotLight.angle = Math.PI / 7;
-				spotLight.decay = 2;
-				spotLight.distance = 300;
-				spotLight.penumbra = 0.8;
-				spotLight.castShadow = true;
-				scene.add( spotLight );
-
-				renderer.setPixelRatio( window.devicePixelRatio );
-				renderer.setSize( window.innerWidth, window.innerHeight );
-				renderer.shadowMap.enabled = true;
-				container.appendChild( renderer.domElement );
+								if ( child.isMesh ) {
 
-				renderer.outputEncoding = THREE.sRGBEncoding;
+									mesh = child;
+									scene.add( mesh );
 
-				composer = new EffectComposer( renderer );
-				composer.setSize( window.innerWidth, window.innerHeight );
+								}
 
-				var renderScene = new RenderPass( scene, camera );
-				composer.addPass( renderScene );
+							} );
 
-				var copyPass = new ShaderPass( CopyShader );
-				composer.addPass( copyPass );
+							render();
 
-				stats = new Stats();
-				container.appendChild( stats.dom );
+						} );
 
-				new OrbitControls( camera, renderer.domElement );
+					} );
 
 				window.addEventListener( 'resize', onWindowResize, false );
 
-				var gui = new GUI();
+				gui = new GUI();
+
+				gui.add( params, 'toneMapping', Object.keys( toneMappingOptions ) )
+
+					.onChange( function () {
+
+						updateGUI();
+
+						renderer.toneMapping = toneMappingOptions[ params.toneMapping ];
+						mesh.material.needsUpdate = true;
+						render();
+
+					} );
+
+				updateGUI();
 
-				gui.add( params, 'toneMapping', Object.keys( toneMappingOptions ) );
-				gui.add( params, 'exposure', 0, 10 );
-				gui.add( params, 'whitePoint', 0, 10 );
-				gui.add( params, 'opacity', 0, 1 );
-				gui.add( params, 'renderMode', [ 'Renderer', 'Composer' ] );
 				gui.open();
 
 			}
 
-			function onWindowResize() {
+			function updateGUI() {
 
-				var width = window.innerWidth;
-				var height = window.innerHeight;
+				if ( guiWhitePoint !== null ) {
 
-				camera.aspect = width / height;
-				camera.updateProjectionMatrix();
+					gui.remove( guiWhitePoint );
+					guiWhitePoint = null;
 
-				renderer.setSize( width, height );
-				composer.setSize( width, height );
+				}
 
-			}
+				if ( guiExposure !== null ) {
+
+					gui.remove( guiExposure );
+					guiExposure = null;
 
-			//
+				}
 
-			function animate() {
+				if ( params.toneMapping !== 'None' ) {
 
-				requestAnimationFrame( animate );
+					guiExposure = gui.add( params, 'exposure', 0, 2 )
 
-				stats.begin();
-				render();
-				stats.end();
+						.onChange( function () {
 
-			}
+							renderer.toneMappingExposure = params.exposure;
+							render();
 
-			function render() {
+						} );
+
+				}
+
+				if ( params.toneMapping === 'Uncharted2' ) {
 
-				standardMaterial.roughness = params.roughness;
-				standardMaterial.bumpScale = - 0.05 * params.bumpScale;
-				standardMaterial.opacity = params.opacity;
+					guiWhitePoint = gui.add( params, 'whitePoint', 0, 2 )
 
-				if ( renderer.toneMapping !== toneMappingOptions[ params.toneMapping ] ) {
+						.onChange( function () {
 
-					renderer.toneMapping = toneMappingOptions[ params.toneMapping ];
-					standardMaterial.needsUpdate = true;
-					floorMaterial.needsUpdate = true;
+							renderer.toneMappingWhitePoint = params.whitePoint;
+							render();
+
+						} );
 
 				}
 
-				renderer.toneMappingExposure = params.exposure;
-				renderer.toneMappingWhitePoint = params.whitePoint;
+			}
 
-				mesh.rotation.y += 0.005;
+			function onWindowResize() {
 
-				if ( params.renderMode === "Composer" ) {
+				camera.aspect = window.innerWidth / window.innerHeight;
 
-					composer.render();
+				camera.updateProjectionMatrix();
 
-				} else {
+				renderer.setSize( window.innerWidth, window.innerHeight );
 
-					renderer.render( scene, camera );
+				render();
 
-				}
+			}
+
+			function render() {
+
+				renderer.render( scene, camera );
 
 			}