|
40 | 40 |
|
41 | 41 | import { CarControls } from './jsm/misc/CarControls.js'; |
42 | 42 |
|
| 43 | + import { RGBELoader } from './jsm/loaders/RGBELoader.js'; |
| 44 | + |
43 | 45 | import { PMREMGenerator } from './jsm/pmrem/PMREMGenerator.js'; |
44 | 46 | import { PMREMCubeUVPacker } from './jsm/pmrem/PMREMCubeUVPacker.js'; |
45 | 47 |
|
46 | | - var camera, scene, renderer, stats, carModel, materialsLib, envMap; |
| 48 | + var camera, scene, renderer; |
| 49 | + var stats, carModel, materialsLib, envMap; |
47 | 50 |
|
48 | 51 | var bodyMatSelect = document.getElementById( 'body-mat' ); |
49 | 52 | var rimMatSelect = document.getElementById( 'rim-mat' ); |
|
61 | 64 | glass: [], |
62 | 65 | }; |
63 | 66 |
|
64 | | - var damping = 5.0; |
65 | | - var distance = 5; |
| 67 | + var damping = 3.0; |
| 68 | + |
| 69 | + var cameraBack = new THREE.Object3D(); |
| 70 | + cameraBack.position.set( 0, 2.5, 5 ); |
| 71 | + |
66 | 72 | var cameraTarget = new THREE.Vector3(); |
67 | 73 |
|
68 | 74 | function init() { |
69 | 75 |
|
70 | 76 | var container = document.getElementById( 'container' ); |
71 | 77 |
|
72 | | - camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 0.1, 200 ); |
| 78 | + camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 0.1, 200 ); |
73 | 79 | camera.position.set( 3.25, 2.0, - 5 ); |
74 | | - camera.lookAt( 0, 0.5, 0 ); |
| 80 | + camera.lookAt( 0, 0.25, 0 ); |
75 | 81 |
|
76 | 82 | scene = new THREE.Scene(); |
77 | | - scene.fog = new THREE.Fog( 0xd7cbb1, 1, 80 ); |
| 83 | + // scene.fog = new THREE.Fog( 0xd7cbb1, 1, 80 ); |
78 | 84 |
|
79 | | - var urls = [ 'px.jpg', 'nx.jpg', 'py.jpg', 'ny.jpg', 'pz.jpg', 'nz.jpg' ]; |
80 | | - var loader = new THREE.CubeTextureLoader().setPath( 'textures/cube/skyboxsun25deg/' ); |
81 | | - loader.load( urls, function ( texture ) { |
| 85 | + new RGBELoader() |
| 86 | + .setDataType( THREE.UnsignedByteType ) |
| 87 | + .setPath( 'textures/hdr/' ) |
| 88 | + .load( 'quarry_01_1k.hdr', function ( texture ) { |
82 | 89 |
|
83 | | - scene.background = texture; |
| 90 | + var options = { |
| 91 | + minFilter: texture.minFilter, |
| 92 | + magFilter: texture.magFilter |
| 93 | + }; |
84 | 94 |
|
85 | | - var pmremGenerator = new PMREMGenerator( texture ); |
86 | | - pmremGenerator.update( renderer ); |
| 95 | + scene.background = new THREE.WebGLRenderTargetCube( 1024, 1024, options ).fromEquirectangularTexture( renderer, texture ); |
87 | 96 |
|
88 | | - var pmremCubeUVPacker = new PMREMCubeUVPacker( pmremGenerator.cubeLods ); |
89 | | - pmremCubeUVPacker.update( renderer ); |
| 97 | + envMap = scene.background; |
90 | 98 |
|
91 | | - envMap = pmremCubeUVPacker.CubeUVRenderTarget.texture; |
| 99 | + var pmremGenerator = new PMREMGenerator( scene.background.texture ); |
| 100 | + pmremGenerator.update( renderer ); |
92 | 101 |
|
93 | | - pmremGenerator.dispose(); |
94 | | - pmremCubeUVPacker.dispose(); |
| 102 | + var pmremCubeUVPacker = new PMREMCubeUVPacker( pmremGenerator.cubeLods ); |
| 103 | + pmremCubeUVPacker.update( renderer ); |
95 | 104 |
|
96 | | - // |
| 105 | + envMap = pmremCubeUVPacker.CubeUVRenderTarget.texture; |
97 | 106 |
|
98 | | - initCar(); |
99 | | - initMaterials(); |
100 | | - initMaterialSelectionMenus(); |
| 107 | + pmremGenerator.dispose(); |
| 108 | + pmremCubeUVPacker.dispose(); |
101 | 109 |
|
102 | | - } ); |
| 110 | + // |
| 111 | + |
| 112 | + initCar(); |
| 113 | + initMaterials(); |
| 114 | + initMaterialSelectionMenus(); |
| 115 | + |
| 116 | + } ); |
103 | 117 |
|
104 | 118 | var ground = new THREE.Mesh( |
105 | | - new THREE.PlaneBufferGeometry( 2400, 2400 ), |
106 | | - new THREE.ShadowMaterial( { color: 0x000000, opacity: 0.15, depthWrite: false } |
107 | | - ) ); |
| 119 | + new THREE.PlaneBufferGeometry( 400, 400 ), |
| 120 | + new THREE.MeshBasicMaterial( { color: 0x6e6a62, depthWrite: false } ) |
| 121 | + ); |
108 | 122 | ground.rotation.x = - Math.PI / 2; |
109 | | - ground.receiveShadow = true; |
110 | 123 | ground.renderOrder = 1; |
111 | 124 | scene.add( ground ); |
112 | 125 |
|
113 | | - var grid = new THREE.GridHelper( 400, 40, 0x000000, 0x000000 ); |
| 126 | + var grid = new THREE.GridHelper( 400, 80, 0x000000, 0x000000 ); |
114 | 127 | grid.material.opacity = 0.2; |
115 | 128 | grid.material.depthWrite = false; |
116 | 129 | grid.material.transparent = true; |
117 | 130 | scene.add( grid ); |
118 | 131 |
|
119 | 132 | renderer = new THREE.WebGLRenderer( { antialias: true } ); |
120 | | - renderer.gammaOutput = true; |
121 | 133 | renderer.setPixelRatio( window.devicePixelRatio ); |
122 | 134 | renderer.setSize( window.innerWidth, window.innerHeight ); |
123 | | - |
124 | 135 | container.appendChild( renderer.domElement ); |
125 | 136 |
|
| 137 | + renderer.gammaOutput = true; |
| 138 | + renderer.toneMapping = THREE.ACESFilmicToneMapping; |
| 139 | + renderer.toneMappingExposure = 1; |
| 140 | + |
126 | 141 | stats = new Stats(); |
127 | 142 | container.appendChild( stats.dom ); |
128 | 143 |
|
129 | 144 | window.addEventListener( 'resize', onWindowResize, false ); |
130 | 145 |
|
131 | | - renderer.setAnimationLoop( function () { |
132 | | - |
133 | | - update(); |
134 | | - |
135 | | - renderer.render( scene, camera ); |
136 | | - |
137 | | - } ); |
| 146 | + renderer.setAnimationLoop( render ); |
138 | 147 |
|
139 | 148 | } |
140 | 149 |
|
|
152 | 161 |
|
153 | 162 | carControls.setModel( carModel ); |
154 | 163 |
|
| 164 | + carModel.add( cameraBack ); |
| 165 | + |
155 | 166 | carModel.traverse( function ( child ) { |
156 | 167 |
|
157 | 168 | if ( child.isMesh ) { |
|
165 | 176 | // shadow |
166 | 177 | var texture = new THREE.TextureLoader().load( 'models/gltf/ferrari_ao.png' ); |
167 | 178 | var shadow = new THREE.Mesh( |
168 | | - new THREE.PlaneBufferGeometry( 0.655 * 4, 1.3 * 4 ).rotateX( - Math.PI / 2 ), |
169 | | - new THREE.MeshBasicMaterial( { map: texture, opacity: 0.8, transparent: true } ) |
| 179 | + new THREE.PlaneBufferGeometry( 0.655 * 4, 1.3 * 4 ), |
| 180 | + new THREE.MeshBasicMaterial( { |
| 181 | + map: texture, opacity: 0.7, transparent: true |
| 182 | + } ) |
170 | 183 | ); |
| 184 | + shadow.rotation.x = - Math.PI / 2; |
171 | 185 | shadow.renderOrder = 2; |
172 | 186 | carModel.add( shadow ); |
173 | 187 |
|
|
200 | 214 |
|
201 | 215 | main: [ |
202 | 216 |
|
203 | | - new THREE.MeshStandardMaterial( { color: 0xff4400, envMap: envMap, metalness: 0.9, roughness: 0.2, name: 'orange' } ), |
204 | | - new THREE.MeshStandardMaterial( { color: 0x001166, envMap: envMap, metalness: 0.9, roughness: 0.2, name: 'blue' } ), |
205 | | - new THREE.MeshStandardMaterial( { color: 0x990000, envMap: envMap, metalness: 0.9, roughness: 0.2, name: 'red' } ), |
206 | | - new THREE.MeshStandardMaterial( { color: 0x000000, envMap: envMap, metalness: 0.9, roughness: 0.5, name: 'black' } ), |
207 | | - new THREE.MeshStandardMaterial( { color: 0xffffff, envMap: envMap, metalness: 0.9, roughness: 0.5, name: 'white' } ), |
208 | | - new THREE.MeshStandardMaterial( { color: 0x555555, envMap: envMap, envMapIntensity: 2.0, metalness: 1.0, roughness: 0.2, name: 'metallic' } ), |
| 217 | + new THREE.MeshStandardMaterial( { |
| 218 | + color: 0xff4400, envMap: envMap, metalness: 1.0, roughness: 0.2, name: 'orange' |
| 219 | + } ), |
| 220 | + new THREE.MeshStandardMaterial( { |
| 221 | + color: 0x001166, envMap: envMap, metalness: 1.0, roughness: 0.2, name: 'blue' |
| 222 | + } ), |
| 223 | + new THREE.MeshStandardMaterial( { |
| 224 | + color: 0x990000, envMap: envMap, metalness: 1.0, roughness: 0.2, name: 'red' |
| 225 | + } ), |
| 226 | + new THREE.MeshStandardMaterial( { |
| 227 | + color: 0x000000, envMap: envMap, metalness: 1.0, roughness: 0.2, name: 'black' |
| 228 | + } ), |
| 229 | + new THREE.MeshStandardMaterial( { |
| 230 | + color: 0xffffff, envMap: envMap, metalness: 0.3, roughness: 0.2, name: 'white' |
| 231 | + } ), |
| 232 | + new THREE.MeshStandardMaterial( { |
| 233 | + color: 0xffffff, envMap: envMap, metalness: 1.0, roughness: 0.2, name: 'metallic' |
| 234 | + } ), |
209 | 235 |
|
210 | 236 | ], |
211 | 237 |
|
212 | 238 | glass: [ |
213 | 239 |
|
214 | | - new THREE.MeshStandardMaterial( { color: 0xffffff, envMap: envMap, metalness: 1, roughness: 0, opacity: 0.2, transparent: true, premultipliedAlpha: true, name: 'clear' } ), |
215 | | - new THREE.MeshStandardMaterial( { color: 0x000000, envMap: envMap, metalness: 1, roughness: 0, opacity: 0.2, transparent: true, premultipliedAlpha: true, name: 'smoked' } ), |
216 | | - new THREE.MeshStandardMaterial( { color: 0x001133, envMap: envMap, metalness: 1, roughness: 0, opacity: 0.2, transparent: true, premultipliedAlpha: true, name: 'blue' } ), |
| 240 | + new THREE.MeshPhysicalMaterial( { |
| 241 | + color: 0xffffff, envMap: envMap, metalness: 1, roughness: 0, transparency: 1.0, transparent: true, name: 'clear' |
| 242 | + } ), |
| 243 | + new THREE.MeshPhysicalMaterial( { |
| 244 | + color: 0x000000, envMap: envMap, metalness: 1, roughness: 0, transparency: 0.7, transparent: true, name: 'smoked' |
| 245 | + } ), |
| 246 | + new THREE.MeshPhysicalMaterial( { |
| 247 | + color: 0x001133, envMap: envMap, metalness: 1, roughness: 0, transparency: 0.7, transparent: true, name: 'blue' |
| 248 | + } ), |
217 | 249 |
|
218 | 250 | ], |
219 | 251 |
|
|
277 | 309 |
|
278 | 310 | } |
279 | 311 |
|
280 | | - function update() { |
| 312 | + function render() { |
281 | 313 |
|
282 | 314 | var delta = clock.getDelta(); |
283 | 315 |
|
|
294 | 326 |
|
295 | 327 | if ( followCamera.checked ) { |
296 | 328 |
|
297 | | - carModel.getWorldPosition( cameraTarget ); |
298 | | - cameraTarget.y = 2.5; |
299 | | - cameraTarget.z += distance; |
300 | | - |
301 | | - camera.position.lerp( cameraTarget, delta * damping ); |
| 329 | + cameraBack.getWorldPosition( cameraTarget ); |
302 | 330 |
|
303 | 331 | } else { |
304 | 332 |
|
305 | | - carModel.getWorldPosition( cameraTarget ); |
306 | | - cameraTarget.y += 0.5; |
307 | | - |
308 | | - camera.position.set( 3.25, 2.0, - 5 ); |
| 333 | + cameraTarget.set( 3.25, 2.0, - 5 ); |
309 | 334 |
|
310 | 335 | } |
311 | 336 |
|
312 | | - camera.lookAt( carModel.position ); |
| 337 | + camera.position.lerp( cameraTarget, delta * damping ); |
| 338 | + |
| 339 | + var position = carModel.position; |
| 340 | + |
| 341 | + camera.lookAt( position.x, position.y + 0.25, position.z ); |
313 | 342 |
|
314 | 343 | } |
315 | 344 |
|
| 345 | + renderer.render( scene, camera ); |
| 346 | + |
316 | 347 | stats.update(); |
317 | 348 |
|
318 | 349 | } |
|
0 commit comments