Browse Source

Examples: Simplified webgl_materials_car.

Mr.doob 5 years ago
parent
commit
dd703fa492

+ 116 - 0
examples/jsm/environments/RoomEnvironment.js

@@ -0,0 +1,116 @@
+/**
+ * @author mrdoob / http://mrdoob.com/
+ *
+ * https://github.com/google/model-viewer/blob/master/packages/model-viewer/src/three-components/EnvironmentScene.ts
+ */
+
+import * as THREE from '../../../build/three.module.js';
+
+function RoomEnvironment( renderer ) {
+
+	const scene = new THREE.Scene();
+
+	const geometry = new THREE.BoxBufferGeometry();
+	geometry.deleteAttribute( 'uv' );
+
+	const roomMaterial = new THREE.MeshStandardMaterial( { side: THREE.BackSide } );
+	const boxMaterial = new THREE.MeshStandardMaterial();
+
+	const mainLight = new THREE.PointLight( 0xffffff, 5.0, 28, 2 );
+	mainLight.position.set( 0.418, 16.199, 0.300 );
+	scene.add( mainLight );
+
+	const room = new THREE.Mesh( geometry, roomMaterial );
+	room.position.set( - 0.757, 13.219, 0.717 );
+	room.scale.set( 31.713, 28.305, 28.591 );
+	scene.add( room );
+
+	const box1 = new THREE.Mesh( geometry, boxMaterial );
+	box1.position.set( - 10.906, 2.009, 1.846 );
+	box1.rotation.set( 0, - 0.195, 0 );
+	box1.scale.set( 2.328, 7.905, 4.651 );
+	scene.add( box1 );
+
+	const box2 = new THREE.Mesh( geometry, boxMaterial );
+	box2.position.set( - 5.607, - 0.754, - 0.758 );
+	box2.rotation.set( 0, 0.994, 0 );
+	box2.scale.set( 1.970, 1.534, 3.955 );
+	scene.add( box2 );
+
+	const box3 = new THREE.Mesh( geometry, boxMaterial );
+	box3.position.set( 6.167, 0.857, 7.803 );
+	box3.rotation.set( 0, 0.561, 0 );
+	box3.scale.set( 3.927, 6.285, 3.687 );
+	scene.add( box3 );
+
+	const box4 = new THREE.Mesh( geometry, boxMaterial );
+	box4.position.set( - 2.017, 0.018, 6.124 );
+	box4.rotation.set( 0, 0.333, 0 );
+	box4.scale.set( 2.002, 4.566, 2.064 );
+	scene.add( box4 );
+
+	const box5 = new THREE.Mesh( geometry, boxMaterial );
+	box5.position.set( 2.291, - 0.756, - 2.621 );
+	box5.rotation.set( 0, - 0.286, 0 );
+	box5.scale.set( 1.546, 1.552, 1.496 );
+	scene.add( box5 );
+
+	const box6 = new THREE.Mesh( geometry, boxMaterial );
+	box6.position.set( - 2.193, - 0.369, - 5.547 );
+	box6.rotation.set( 0, 0.516, 0 );
+	box6.scale.set( 3.875, 3.487, 2.986 );
+	scene.add( box6 );
+
+
+	// -x right
+	const light1 = new THREE.Mesh( geometry, createAreaLightMaterial( 50 ) );
+	light1.position.set( - 16.116, 14.37, 8.208 );
+	light1.scale.set( 0.1, 2.428, 2.739 );
+	scene.add( light1 );
+
+	// -x left
+	const light2 = new THREE.Mesh( geometry, createAreaLightMaterial( 50 ) );
+	light2.position.set( - 16.109, 18.021, - 8.207 );
+	light2.scale.set( 0.1, 2.425, 2.751 );
+	scene.add( light2 );
+
+	// +x
+	const light3 = new THREE.Mesh( geometry, createAreaLightMaterial( 17 ) );
+	light3.position.set( 14.904, 12.198, - 1.832 );
+	light3.scale.set( 0.15, 4.265, 6.331 );
+	scene.add( light3 );
+
+	// +z
+	const light4 = new THREE.Mesh( geometry, createAreaLightMaterial( 43 ) );
+	light4.position.set( - 0.462, 8.89, 14.520 );
+	light4.scale.set( 4.38, 5.441, 0.088 );
+	scene.add( light4 );
+
+	// -z
+	const light5 = new THREE.Mesh( geometry, createAreaLightMaterial( 20 ) );
+	light5.position.set( 3.235, 11.486, - 12.541 );
+	light5.scale.set( 2.5, 2.0, 0.1 );
+	scene.add( light5 );
+
+	// +y
+	const light6 = new THREE.Mesh( geometry, createAreaLightMaterial( 100 ) );
+	light6.position.set( 0.0, 20.0, 0.0 );
+	light6.scale.set( 1.0, 0.1, 1.0 );
+	scene.add( light6 );
+
+	function createAreaLightMaterial( intensity ) {
+
+		const material = new THREE.MeshBasicMaterial();
+		material.color.setScalar( intensity );
+		return material;
+
+	}
+
+	let pmremGenerator = new THREE.PMREMGenerator( renderer );
+	let renderTarget = pmremGenerator.fromScene( scene );
+
+	return renderTarget.texture;
+
+}
+
+export { RoomEnvironment };

BIN
examples/screenshots/webgl_materials_car.jpg


+ 82 - 179
examples/webgl_materials_car.html

@@ -8,10 +8,15 @@
 		<style>
 			body {
 				color: #444;
+				background: #eee;
 			}
 			a {
 				color: #08f;
 			}
+			.colorPicker {
+				display: inline-block;
+				margin: 0 10px
+			}
 		</style>
 	</head>
 
@@ -20,9 +25,9 @@
 			<a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> car materials<br/>
 			Ferrari 458 Italia model by <a href="https://sketchfab.com/models/57bf6cc56931426e87494f554df1dab6" target="_blank" rel="noopener">vicent091036</a>
 			<br><br>
-			<span>Body: <select id="body-mat"></select></span>
-			<span>Details: <select id="rim-mat"></select></span>
-			<span>Glass: <select id="glass-mat"></select></span>
+			<span class="colorPicker"><input id="body-color" type="color" value="#660000"></input><br/>Body</span>
+			<span class="colorPicker"><input id="details-color" type="color" value="#ffffff"></input><br/>Details</span>
+			<span class="colorPicker"><input id="glass-color" type="color" value="#ffffff"></input><br/>Glass</span>
 		</div>
 
 		<div id="container"></div>
@@ -33,89 +38,91 @@
 
 			import Stats from './jsm/libs/stats.module.js';
 
+			import { OrbitControls } from './jsm/controls/OrbitControls.js';
+			import { RoomEnvironment } from './jsm/environments/RoomEnvironment.js';
+
 			import { GLTFLoader } from './jsm/loaders/GLTFLoader.js';
 			import { DRACOLoader } from './jsm/loaders/DRACOLoader.js';
 
-			import { RGBELoader } from './jsm/loaders/RGBELoader.js';
-
 			var camera, scene, renderer;
-			var stats, carModel, materialsLib;
-
-			var bodyMatSelect = document.getElementById( 'body-mat' );
-			var rimMatSelect = document.getElementById( 'rim-mat' );
-			var glassMatSelect = document.getElementById( 'glass-mat' );
-
-			var carParts = {
-				body: [],
-				rims: [],
-				glass: [],
-			};
+			var stats;
 
 			var grid, wheels = [];
+			var controls;
 
 			function init() {
 
 				var container = document.getElementById( 'container' );
 
-				camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 0.1, 200 );
-
-				scene = new THREE.Scene();
-				// scene.fog = new THREE.Fog( 0xd7cbb1, 1, 80 );
-
-				new RGBELoader()
-					.setDataType( THREE.UnsignedByteType )
-					.setPath( 'textures/equirectangular/' )
-					.load( 'quarry_01_1k.hdr', function ( texture ) {
+				renderer = new THREE.WebGLRenderer( { antialias: true } );
+				renderer.setPixelRatio( window.devicePixelRatio );
+				renderer.setSize( window.innerWidth, window.innerHeight );
+				renderer.setAnimationLoop( render );
+				renderer.outputEncoding = THREE.sRGBEncoding;
+				renderer.toneMapping = THREE.ACESFilmicToneMapping;
+				container.appendChild( renderer.domElement );
 
-						var envMap = pmremGenerator.fromEquirectangular( texture ).texture;
-						pmremGenerator.dispose();
+				window.addEventListener( 'resize', onWindowResize, false );
 
-						scene.background = envMap;
-						scene.environment = envMap;
+				stats = new Stats();
+				container.appendChild( stats.dom );
 
-						//
+				//
 
-						initCar();
-						initMaterials();
-						initMaterialSelectionMenus();
+				camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 0.1, 100 );
+				camera.position.set( 3, 1.75, - 4 );
 
-					} );
+				controls = new OrbitControls( camera, container );
+				controls.target.set( 0, 0.4, 0 );
+				controls.update();
 
-				var ground = new THREE.Mesh(
-					new THREE.PlaneBufferGeometry( 400, 400 ),
-					new THREE.MeshBasicMaterial( { color: 0x6e6a62, depthWrite: false } )
-				);
-				ground.rotation.x = - Math.PI / 2;
-				ground.renderOrder = 1;
-				scene.add( ground );
+				scene = new THREE.Scene();
+				scene.background = new THREE.Color( 0xeeeeee );
+				scene.environment = new RoomEnvironment( renderer );
+				scene.fog = new THREE.Fog( 0xeeeeee, 10, 50 );
 
-				grid = new THREE.GridHelper( 400, 80, 0x000000, 0x000000 );
+				grid = new THREE.GridHelper( 100, 40, 0x000000, 0x000000 );
 				grid.material.opacity = 0.1;
 				grid.material.depthWrite = false;
 				grid.material.transparent = true;
 				scene.add( grid );
 
-				renderer = new THREE.WebGLRenderer( { antialias: true } );
-				renderer.setPixelRatio( window.devicePixelRatio );
-				renderer.setSize( window.innerWidth, window.innerHeight );
-				container.appendChild( renderer.domElement );
+				// materials
 
-				renderer.outputEncoding = THREE.sRGBEncoding;
-				renderer.toneMapping = THREE.ACESFilmicToneMapping;
+				var bodyMaterial = new THREE.MeshPhysicalMaterial( {
+					color: 0x660000, metalness: 1.0, roughness: 0.5, clearcoat: 0.02, clearcoatRoughness: 0.01
+				} );
 
-				var pmremGenerator = new THREE.PMREMGenerator( renderer );
-				pmremGenerator.compileEquirectangularShader();
+				var detailsMaterial = new THREE.MeshStandardMaterial( {
+					color: 0xffffff, metalness: 1.0, roughness: 0
+				} );
 
-				stats = new Stats();
-				container.appendChild( stats.dom );
+				var glassMaterial = new THREE.MeshPhysicalMaterial( {
+					color: 0xffffff, metalness: 0, roughness: 0, transparency: 0.8, transparent: true
+				} );
 
-				window.addEventListener( 'resize', onWindowResize, false );
+				var bodyColorInput = document.getElementById( 'body-color' );
+				bodyColorInput.addEventListener( 'input', function () {
 
-				renderer.setAnimationLoop( render );
+					bodyMaterial.color.set( this.value );
 
-			}
+				} );
+
+				var detailsColorInput = document.getElementById( 'details-color' );
+				detailsColorInput.addEventListener( 'input', function () {
+
+					detailsMaterial.color.set( this.value );
+
+				} );
 
-			function initCar() {
+				var glassColorInput = document.getElementById( 'glass-color' );
+				glassColorInput.addEventListener( 'input', function () {
+
+					glassMaterial.color.set( this.value );
+
+				} );
+
+				// Car
 
 				var dracoLoader = new DRACOLoader();
 				dracoLoader.setDecoderPath( 'js/libs/draco/gltf/' );
@@ -125,14 +132,31 @@
 
 				loader.load( 'models/gltf/ferrari.glb', function ( gltf ) {
 
-					carModel = gltf.scene.children[ 0 ];
+					var carModel = gltf.scene.children[ 0 ];
+
+					carModel.getObjectByName( 'body' ).material = bodyMaterial;
+
+					carModel.getObjectByName( 'rim_fl' ).material = detailsMaterial;
+					carModel.getObjectByName( 'rim_fr' ).material = detailsMaterial;
+					carModel.getObjectByName( 'rim_rr' ).material = detailsMaterial;
+					carModel.getObjectByName( 'rim_rl' ).material = detailsMaterial;
+					carModel.getObjectByName( 'trim' ).material = detailsMaterial;
+
+					carModel.getObjectByName( 'glass' ).material = glassMaterial;
+
+					wheels.push(
+						carModel.getObjectByName( 'wheel_fl' ),
+						carModel.getObjectByName( 'wheel_fr' ),
+						carModel.getObjectByName( 'wheel_rl' ),
+						carModel.getObjectByName( 'wheel_rr' )
+					);
 
 					// shadow
 					var texture = new THREE.TextureLoader().load( 'models/gltf/ferrari_ao.png' );
 					var shadow = new THREE.Mesh(
 						new THREE.PlaneBufferGeometry( 0.655 * 4, 1.3 * 4 ),
 						new THREE.MeshBasicMaterial( {
-							map: texture, opacity: 0.7, transparent: true
+							map: texture, opacity: 0.4, transparent: true
 						} )
 					);
 					shadow.rotation.x = - Math.PI / 2;
@@ -141,126 +165,10 @@
 
 					scene.add( carModel );
 
-					// car parts for material selection
-					carParts.body.push( carModel.getObjectByName( 'body' ) );
-
-					carParts.rims.push(
-						carModel.getObjectByName( 'rim_fl' ),
-						carModel.getObjectByName( 'rim_fr' ),
-						carModel.getObjectByName( 'rim_rr' ),
-						carModel.getObjectByName( 'rim_rl' ),
-						carModel.getObjectByName( 'trim' ),
-					);
-
-					carParts.glass.push(
-						carModel.getObjectByName( 'glass' ),
-					 );
-
-					 wheels.push(
-						 carModel.getObjectByName( 'wheel_fl' ),
-						 carModel.getObjectByName( 'wheel_fr' ),
-						 carModel.getObjectByName( 'wheel_rl' ),
-						 carModel.getObjectByName( 'wheel_rr' )
-					 );
-
-					updateMaterials();
-
 				} );
 
 			}
 
-			function initMaterials() {
-
-				materialsLib = {
-
-					main: [
-
-						new THREE.MeshStandardMaterial( {
-							color: 0xff4400, metalness: 1.0, roughness: 0.2, name: 'orange'
-						} ),
-						new THREE.MeshStandardMaterial( {
-							color: 0x001166, metalness: 1.0, roughness: 0.2, name: 'blue'
-						} ),
-						new THREE.MeshStandardMaterial( {
-							color: 0x990000, metalness: 1.0, roughness: 0.2, name: 'red'
-						} ),
-						new THREE.MeshStandardMaterial( {
-							color: 0x000000, metalness: 1.0, roughness: 0.4, name: 'black'
-						} ),
-						new THREE.MeshStandardMaterial( {
-							color: 0xffffff, metalness: 0.1, roughness: 0.2, name: 'white'
-						} ),
-						new THREE.MeshStandardMaterial( {
-							color: 0xffffff, metalness: 1.0, roughness: 0.2, name: 'metallic'
-						} )
-
-					],
-
-					glass: [
-
-						new THREE.MeshPhysicalMaterial( {
-							color: 0xffffff, metalness: 0, roughness: 0, transparency: 1.0, transparent: true, name: 'clear'
-						} ),
-						new THREE.MeshPhysicalMaterial( {
-							color: 0x000000, metalness: 0, roughness: 0, transparency: 0.7, transparent: true, name: 'smoked'
-						} ),
-						new THREE.MeshPhysicalMaterial( {
-							color: 0x001133, metalness: 0, roughness: 0, transparency: 0.7, transparent: true, name: 'blue'
-						} )
-
-					],
-
-				};
-
-			}
-
-			function initMaterialSelectionMenus() {
-
-				function addOption( name, menu ) {
-
-					var option = document.createElement( 'option' );
-					option.text = name;
-					option.value = name;
-					menu.add( option );
-
-				}
-
-				materialsLib.main.forEach( function ( material ) {
-
-					addOption( material.name, bodyMatSelect );
-					addOption( material.name, rimMatSelect );
-
-				} );
-
-				materialsLib.glass.forEach( function ( material ) {
-
-					addOption( material.name, glassMatSelect );
-
-				} );
-
-				bodyMatSelect.selectedIndex = 2;
-				rimMatSelect.selectedIndex = 5;
-				glassMatSelect.selectedIndex = 0;
-
-				bodyMatSelect.addEventListener( 'change', updateMaterials );
-				rimMatSelect.addEventListener( 'change', updateMaterials );
-				glassMatSelect.addEventListener( 'change', updateMaterials );
-
-			}
-
-			// set materials to the current values of the selection menus
-			function updateMaterials() {
-
-				var bodyMat = materialsLib.main[ bodyMatSelect.selectedIndex ];
-				var rimMat = materialsLib.main[ rimMatSelect.selectedIndex ];
-				var glassMat = materialsLib.glass[ glassMatSelect.selectedIndex ];
-
-				carParts.body.forEach( part => part.material = bodyMat );
-				carParts.rims.forEach( part => part.material = rimMat );
-				carParts.glass.forEach( part => part.material = glassMat );
-
-			}
-
 			function onWindowResize() {
 
 				camera.aspect = window.innerWidth / window.innerHeight;
@@ -274,11 +182,6 @@
 
 				var time = - performance.now() / 1000;
 
-				camera.position.x = Math.cos( time / 10 ) * 6;
-				camera.position.y = 1.5;
-				camera.position.z = Math.sin( time / 10 ) * 6;
-				camera.lookAt( 0, 0.5, 0 );
-
 				for ( var i = 0; i < wheels.length; i ++ ) {
 
 					wheels[ i ].rotation.x = time * Math.PI;