webgl_materials_physical_reflectivity.html 6.0 KB
Newer Older
M
r76  
Mr.doob 已提交
1 2 3
<!DOCTYPE html>
<html lang="en">
	<head>
M
r114  
Mr.doob 已提交
4
		<title>threejs webgl - materials - physical - reflectivity</title>
M
r76  
Mr.doob 已提交
5 6
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
M
r105  
Mr.doob 已提交
7
		<link type="text/css" rel="stylesheet" href="main.css">
M
r76  
Mr.doob 已提交
8 9 10 11
	</head>
	<body>

		<div id="container"></div>
M
r105  
Mr.doob 已提交
12
		<div id="info">
M
r114  
Mr.doob 已提交
13
			<a href="https://threejs.org" target="_blank" rel="noopener">threejs</a> - Physical Material Reflectivity (reflectance at F0)<br/>
M
r105  
Mr.doob 已提交
14 15
			example by <a href="http://clara.io/" target="_blank" rel="noopener">Ben Houston</a>.
		</div>
M
r76  
Mr.doob 已提交
16

M
r106  
Mr.doob 已提交
17
		<script type="module">
M
Mr.doob 已提交
18

M
r106  
Mr.doob 已提交
19
			import * as THREE from '../build/three.module.js';
M
r76  
Mr.doob 已提交
20

M
r106  
Mr.doob 已提交
21
			import Stats from './jsm/libs/stats.module.js';
M
r76  
Mr.doob 已提交
22

M
r106  
Mr.doob 已提交
23 24 25
			import { GUI } from './jsm/libs/dat.gui.module.js';
			import { OrbitControls } from './jsm/controls/OrbitControls.js';
			import { OBJLoader } from './jsm/loaders/OBJLoader.js';
M
r112  
Mr.doob 已提交
26
			import { RGBELoader } from './jsm/loaders/RGBELoader.js';
M
r76  
Mr.doob 已提交
27

M
r122  
Mr.doob 已提交
28 29
			let container, stats;
			const params = {
M
r76  
Mr.doob 已提交
30 31
				projection: 'normal',
				autoRotate: true,
M
r129  
Mr.doob 已提交
32
				reflectivity: 1,
M
r76  
Mr.doob 已提交
33
				background: false,
M
r129  
Mr.doob 已提交
34
				exposure: 1,
M
r76  
Mr.doob 已提交
35 36
				gemColor: 'Green'
			};
M
r122  
Mr.doob 已提交
37 38 39 40
			let camera, scene, renderer;
			let gemBackMaterial, gemFrontMaterial;

			const objects = [];
M
r76  
Mr.doob 已提交
41 42 43 44 45 46 47 48 49

			init();
			animate();

			function init() {

				container = document.createElement( 'div' );
				document.body.appendChild( container );

M
r116  
Mr.doob 已提交
50
				camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 1000 );
M
r98  
Mr.doob 已提交
51
				camera.position.set( 0.0, - 10, 20 * 3.5 );
M
r76  
Mr.doob 已提交
52 53

				scene = new THREE.Scene();
M
r87  
Mr.doob 已提交
54
				scene.background = new THREE.Color( 0x000000 );
M
r76  
Mr.doob 已提交
55 56 57 58 59 60

				renderer = new THREE.WebGLRenderer( { antialias: true } );

				gemBackMaterial = new THREE.MeshPhysicalMaterial( {
					map: null,
					color: 0x0000ff,
M
r112  
Mr.doob 已提交
61
					metalness: 1,
M
r76  
Mr.doob 已提交
62 63 64 65 66 67 68 69 70 71 72 73
					roughness: 0,
					opacity: 0.5,
					side: THREE.BackSide,
					transparent: true,
					envMapIntensity: 5,
					premultipliedAlpha: true
					// TODO: Add custom blend mode that modulates background color by this materials color.
				} );

				gemFrontMaterial = new THREE.MeshPhysicalMaterial( {
					map: null,
					color: 0x0000ff,
M
r112  
Mr.doob 已提交
74
					metalness: 0,
M
r76  
Mr.doob 已提交
75
					roughness: 0,
M
r112  
Mr.doob 已提交
76
					opacity: 0.25,
M
r76  
Mr.doob 已提交
77 78
					side: THREE.FrontSide,
					transparent: true,
M
r112  
Mr.doob 已提交
79
					envMapIntensity: 10,
M
r76  
Mr.doob 已提交
80 81 82
					premultipliedAlpha: true
				} );

M
r122  
Mr.doob 已提交
83
				const manager = new THREE.LoadingManager();
M
r76  
Mr.doob 已提交
84 85 86 87 88 89
				manager.onProgress = function ( item, loaded, total ) {

					console.log( item, loaded, total );

				};

M
r122  
Mr.doob 已提交
90
				const loader = new OBJLoader( manager );
M
r76  
Mr.doob 已提交
91 92 93 94 95 96 97
				loader.load( 'models/obj/emerald.obj', function ( object ) {

					object.traverse( function ( child ) {

						if ( child instanceof THREE.Mesh ) {

							child.material = gemBackMaterial;
M
r122  
Mr.doob 已提交
98
							const second = child.clone();
M
r76  
Mr.doob 已提交
99 100
							second.material = gemFrontMaterial;

M
r122  
Mr.doob 已提交
101
							const parent = new THREE.Group();
M
r76  
Mr.doob 已提交
102 103 104 105 106 107 108 109 110 111 112 113 114
							parent.add( second );
							parent.add( child );
							scene.add( parent );

							objects.push( parent );

						}

					} );


				} );

M
r112  
Mr.doob 已提交
115 116
				new RGBELoader()
					.setPath( 'textures/equirectangular/' )
M
r131  
Mr.doob 已提交
117
					.load( 'royal_esplanade_1k.hdr', function ( texture ) {
M
r76  
Mr.doob 已提交
118

M
r131  
Mr.doob 已提交
119
						texture.mapping = THREE.EquirectangularReflectionMapping;
M
r77  
Mr.doob 已提交
120

M
r131  
Mr.doob 已提交
121
						gemFrontMaterial.envMap = gemBackMaterial.envMap = texture;
M
r106  
Mr.doob 已提交
122
						gemFrontMaterial.needsUpdate = gemBackMaterial.needsUpdate = true;
M
r96  
Mr.doob 已提交
123

M
r106  
Mr.doob 已提交
124
					} );
M
r76  
Mr.doob 已提交
125 126 127 128 129

				// Lights

				scene.add( new THREE.AmbientLight( 0x222222 ) );

M
r122  
Mr.doob 已提交
130
				const pointLight1 = new THREE.PointLight( 0xffffff );
M
r76  
Mr.doob 已提交
131 132 133 134
				pointLight1.position.set( 150, 10, 0 );
				pointLight1.castShadow = false;
				scene.add( pointLight1 );

M
r122  
Mr.doob 已提交
135
				const pointLight2 = new THREE.PointLight( 0xffffff );
M
r98  
Mr.doob 已提交
136
				pointLight2.position.set( - 150, 0, 0 );
M
r76  
Mr.doob 已提交
137 138
				scene.add( pointLight2 );

M
r122  
Mr.doob 已提交
139
				const pointLight3 = new THREE.PointLight( 0xffffff );
M
r98  
Mr.doob 已提交
140
				pointLight3.position.set( 0, - 10, - 150 );
M
r76  
Mr.doob 已提交
141 142
				scene.add( pointLight3 );

M
r122  
Mr.doob 已提交
143
				const pointLight4 = new THREE.PointLight( 0xffffff );
M
r76  
Mr.doob 已提交
144 145 146 147 148 149
				pointLight4.position.set( 0, 0, 150 );
				scene.add( pointLight4 );

				renderer.setPixelRatio( window.devicePixelRatio );
				renderer.setSize( window.innerWidth, window.innerHeight );
				renderer.shadowMap.enabled = true;
M
r129  
Mr.doob 已提交
150
				renderer.toneMapping = THREE.ACESFilmicToneMapping;
M
r76  
Mr.doob 已提交
151 152
				container.appendChild( renderer.domElement );

M
r112  
Mr.doob 已提交
153
				renderer.outputEncoding = THREE.sRGBEncoding;
M
r76  
Mr.doob 已提交
154 155 156 157

				stats = new Stats();
				container.appendChild( stats.dom );

M
r122  
Mr.doob 已提交
158
				const controls = new OrbitControls( camera, renderer.domElement );
M
r116  
Mr.doob 已提交
159 160
				controls.minDistance = 20;
				controls.maxDistance = 200;
M
r76  
Mr.doob 已提交
161

M
r125  
Mr.doob 已提交
162
				window.addEventListener( 'resize', onWindowResize );
M
r76  
Mr.doob 已提交
163

M
r122  
Mr.doob 已提交
164
				const gui = new GUI();
M
r76  
Mr.doob 已提交
165 166

				gui.add( params, 'reflectivity', 0, 1 );
M
r129  
Mr.doob 已提交
167
				gui.add( params, 'exposure', 0, 2 );
M
r76  
Mr.doob 已提交
168 169 170 171 172 173 174 175
				gui.add( params, 'autoRotate' );
				gui.add( params, 'gemColor', [ 'Blue', 'Green', 'Red', 'White', 'Black' ] );
				gui.open();

			}

			function onWindowResize() {

M
r122  
Mr.doob 已提交
176 177
				const width = window.innerWidth;
				const height = window.innerHeight;
M
r76  
Mr.doob 已提交
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203

				camera.aspect = width / height;
				camera.updateProjectionMatrix();

				renderer.setSize( width, height );

			}

			//

			function animate() {

				requestAnimationFrame( animate );

				stats.begin();
				render();
				stats.end();

			}

			function render() {

				if ( gemBackMaterial !== undefined && gemFrontMaterial !== undefined ) {

					gemFrontMaterial.reflectivity = gemBackMaterial.reflectivity = params.reflectivity;

M
r122  
Mr.doob 已提交
204
					let newColor = gemBackMaterial.color;
M
r98  
Mr.doob 已提交
205 206
					switch ( params.gemColor ) {

M
r76  
Mr.doob 已提交
207 208 209
						case 'Blue': newColor = new THREE.Color( 0x000088 ); break;
						case 'Red': newColor = new THREE.Color( 0x880000 ); break;
						case 'Green': newColor = new THREE.Color( 0x008800 ); break;
M
r98  
Mr.doob 已提交
210 211 212
						case 'White': newColor = new THREE.Color( 0x888888 ); break;
						case 'Black': newColor = new THREE.Color( 0x0f0f0f ); break;

M
r122  
Mr.doob 已提交
213
					}
M
r76  
Mr.doob 已提交
214

M
r122  
Mr.doob 已提交
215
					gemBackMaterial.color = gemFrontMaterial.color = newColor;
M
r76  
Mr.doob 已提交
216 217 218 219 220 221 222

				}

				renderer.toneMappingExposure = params.exposure;

				camera.lookAt( scene.position );

M
r98  
Mr.doob 已提交
223 224
				if ( params.autoRotate ) {

M
r122  
Mr.doob 已提交
225
					for ( let i = 0, l = objects.length; i < l; i ++ ) {
M
r76  
Mr.doob 已提交
226

M
r122  
Mr.doob 已提交
227
						const object = objects[ i ];
M
r76  
Mr.doob 已提交
228 229 230
						object.rotation.y += 0.005;

					}
M
r98  
Mr.doob 已提交
231

M
r122  
Mr.doob 已提交
232
				}
M
r76  
Mr.doob 已提交
233 234 235 236 237 238 239 240 241

				renderer.render( scene, camera );

			}

		</script>

	</body>
</html>