webgl_lightningstrike.html 21.5 KB
Newer Older
1 2 3 4 5 6
<!DOCTYPE html>
<html lang="en">
	<head>
		<title>three.js webgl - lightning strike</title>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
M
Mr.doob 已提交
7
		<link type="text/css" rel="stylesheet" href="main.css">
8 9 10 11 12 13
	</head>
	<body>

		<div id="container"></div>
		<div id="info"><a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> webgl - lightning strike</div>

M
Mugen87 已提交
14
		<script type="module">
15

M
Mr.doob 已提交
16
			import * as THREE from '../build/three.module.js';
M
Mugen87 已提交
17 18 19 20 21 22 23 24 25 26

			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 { LightningStrike } from './jsm/geometries/LightningStrike.js';
			import { LightningStorm } from './jsm/objects/LightningStorm.js';
			import { EffectComposer } from './jsm/postprocessing/EffectComposer.js';
			import { RenderPass } from './jsm/postprocessing/RenderPass.js';
			import { OutlinePass } from './jsm/postprocessing/OutlinePass.js';
27 28 29

			var container, stats;

M
Mugen87 已提交
30
			var scene, renderer, composer, gui;
31 32 33 34 35 36 37 38 39 40 41

			var currentSceneIndex = 0;

			var currentTime = 0;

			var sceneCreators = [
				createConesScene,
				createPlasmaBallScene,
				createStormScene
			];

M
Mr.doob 已提交
42
			var clock = new THREE.Clock();
43

M
Mr.doob 已提交
44 45
			var raycaster = new THREE.Raycaster();
			var mouse = new THREE.Vector2();
46 47 48 49 50 51 52 53

			init();
			animate();

			function init() {

				container = document.getElementById( 'container' );

M
Mr.doob 已提交
54
				renderer = new THREE.WebGLRenderer();
55 56 57 58 59 60 61 62
				renderer.setPixelRatio( window.devicePixelRatio );
				renderer.setSize( window.innerWidth, window.innerHeight );

				renderer.gammaInput = true;
				renderer.gammaOutput = true;

				container.appendChild( renderer.domElement );

M
Mugen87 已提交
63
				composer = new EffectComposer( renderer );
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87

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

				window.addEventListener( 'resize', onWindowResize, false );

				createScene();

			}

			function createScene() {

				scene = sceneCreators[ currentSceneIndex ]();

				createGUI();

			}

			function onWindowResize() {

				scene.userData.camera.aspect = window.innerWidth / window.innerHeight;
				scene.userData.camera.updateProjectionMatrix();

				renderer.setSize( window.innerWidth, window.innerHeight );
88

89 90 91 92 93 94 95 96 97
				composer.setSize( window.innerWidth, window.innerHeight );

			}

			//

			function createGUI() {

				if ( gui ) {
M
Mugen87 已提交
98

99
					gui.destroy();
M
Mugen87 已提交
100

101 102
				}

M
Mugen87 已提交
103
				gui = new GUI( { width: 350 } );
104 105 106 107 108 109 110 111 112 113 114 115

				var sceneFolder = gui.addFolder( "Scene" );

				scene.userData.sceneIndex = currentSceneIndex;

				sceneFolder.add( scene.userData, 'sceneIndex', { "Electric Cones": 0, "Plasma Ball": 1, "Storm": 2 } ).name( 'Scene' ).onChange( function ( value ) {

					currentSceneIndex = value;

					createScene();

				} );
116

117
				scene.userData.timeRate = 1;
M
Mugen87 已提交
118
				sceneFolder.add( scene.userData, 'timeRate', scene.userData.canGoBackwardsInTime ? - 1 : 0, 1 ).name( 'Time rate' );
119 120 121 122 123 124 125 126 127 128 129 130 131

				sceneFolder.open();

				var graphicsFolder = gui.addFolder( "Graphics" );

				graphicsFolder.add( scene.userData, "outlineEnabled" ).name( "Glow enabled" );

				scene.userData.lightningColorRGB = [
					scene.userData.lightningColor.r * 255,
					scene.userData.lightningColor.g * 255,
					scene.userData.lightningColor.b * 255
				];
				graphicsFolder.addColor( scene.userData, 'lightningColorRGB' ).name( 'Color' ).onChange( function ( value ) {
M
Mugen87 已提交
132

133
					scene.userData.lightningMaterial.color.setRGB( value[ 0 ], value[ 1 ], value[ 2 ] ).multiplyScalar( 1 / 255 );
M
Mugen87 已提交
134

135 136 137 138 139 140 141
				} );
				scene.userData.outlineColorRGB = [
					scene.userData.outlineColor.r * 255,
					scene.userData.outlineColor.g * 255,
					scene.userData.outlineColor.b * 255
				];
				graphicsFolder.addColor( scene.userData, 'outlineColorRGB' ).name( 'Glow color' ).onChange( function ( value ) {
M
Mugen87 已提交
142

143
					scene.userData.outlineColor.setRGB( value[ 0 ], value[ 1 ], value[ 2 ] ).multiplyScalar( 1 / 255 );
M
Mugen87 已提交
144

145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
				} );

				graphicsFolder.open();

				var rayFolder = gui.addFolder( "Ray parameters" );

				rayFolder.add( scene.userData.rayParams, 'straightness', 0, 1 ).name( 'Straightness' );
				rayFolder.add( scene.userData.rayParams, 'roughness', 0, 1 ).name( 'Roughness' );
				rayFolder.add( scene.userData.rayParams, 'radius0', 0.1, 10 ).name( 'Initial radius' );
				rayFolder.add( scene.userData.rayParams, 'radius1', 0.1, 10 ).name( 'Final radius' );
				rayFolder.add( scene.userData.rayParams, 'radius0Factor', 0, 1 ).name( 'Subray initial radius' );
				rayFolder.add( scene.userData.rayParams, 'radius1Factor', 0, 1 ).name( 'Subray final radius' );
				rayFolder.add( scene.userData.rayParams, 'timeScale', 0, 5 ).name( 'Ray time scale' );
				rayFolder.add( scene.userData.rayParams, 'subrayPeriod', 0.1, 10 ).name( 'Subray period (s)' );
				rayFolder.add( scene.userData.rayParams, 'subrayDutyCycle', 0, 1 ).name( 'Subray duty cycle' );

				if ( scene.userData.recreateRay ) {
162

163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 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 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219
					// Parameters which need to recreate the ray after modification

					var raySlowFolder = gui.addFolder( "Ray parameters (slow)" );

					raySlowFolder.add( scene.userData.rayParams, 'ramification', 0, 15 ).step( 1 ).name( 'Ramification' ).onFinishChange( function () {

						scene.userData.recreateRay();

					} );

					raySlowFolder.add( scene.userData.rayParams, 'maxSubrayRecursion', 0, 5 ).step( 1 ).name( 'Recursion' ).onFinishChange( function () {

						scene.userData.recreateRay();

					} );

					raySlowFolder.add( scene.userData.rayParams, 'recursionProbability', 0, 1 ).name( 'Rec. probability' ).onFinishChange( function () {

						scene.userData.recreateRay();

					} );

					raySlowFolder.open();

				}

				rayFolder.open();

			}

			//

			function animate() {

				requestAnimationFrame( animate );

				render();
				stats.update();

			}

			function render() {

				currentTime += scene.userData.timeRate * clock.getDelta();

				if ( currentTime < 0 ) {

					currentTime = 0;

				}

				scene.userData.render( currentTime );

			}

			function createOutline( scene, objectsArray, visibleColor ) {

M
Mr.doob 已提交
220
				var outlinePass = new OutlinePass( new THREE.Vector2( window.innerWidth, window.innerHeight ), scene, scene.userData.camera, objectsArray );
221 222 223 224 225 226 227 228
				outlinePass.edgeStrength = 2.5;
				outlinePass.edgeGlow = 0.7;
				outlinePass.edgeThickness = 2.8;
				outlinePass.visibleEdgeColor = visibleColor;
				outlinePass.hiddenEdgeColor.set( 0 );
				composer.addPass( outlinePass );

				scene.userData.outlineEnabled = true;
229

230 231 232 233 234 235 236 237
				return outlinePass;

			}

			//

			function createConesScene() {

M
Mr.doob 已提交
238 239
				var scene = new THREE.Scene();
				scene.background = new THREE.Color( 0x050505 );
240 241 242

				scene.userData.canGoBackwardsInTime = true;

M
Mr.doob 已提交
243
				scene.userData.camera = new THREE.PerspectiveCamera( 27, window.innerWidth / window.innerHeight, 200, 100000 );
244

245 246
				// Lights

M
Mr.doob 已提交
247 248
				scene.userData.lightningColor = new THREE.Color( 0xB0FFFF );
				scene.userData.outlineColor = new THREE.Color( 0x00FFFF );
249

M
Mr.doob 已提交
250
				var posLight = new THREE.PointLight( 0x00ffff, 1, 5000, 2 );
251 252 253 254
				scene.add( posLight );

				// Ground

M
Mr.doob 已提交
255
				var ground = new THREE.Mesh( new THREE.PlaneBufferGeometry( 200000, 200000 ), new THREE.MeshPhongMaterial( { color: 0xC0C0C0, shininess: 0 } ) );
256 257 258 259 260 261 262 263 264 265 266 267 268 269
				ground.rotation.x = - Math.PI * 0.5;
				scene.add( ground );

				// Cones

				var conesDistance = 1000;
				var coneHeight = 200;
				var coneHeightHalf = coneHeight * 0.5;

				posLight.position.set( 0, ( conesDistance + coneHeight ) * 0.5, 0 );
				posLight.color = scene.userData.outlineColor;

				scene.userData.camera.position.set( 5 * coneHeight, 4 * coneHeight, 18 * coneHeight );

M
Mr.doob 已提交
270
				var coneMesh1 = new THREE.Mesh( new THREE.ConeBufferGeometry( coneHeight, coneHeight, 30, 1, false ), new THREE.MeshPhongMaterial( { color: 0xFFFF00, emissive: 0x1F1F00 } ) );
271 272 273 274
				coneMesh1.rotation.x = Math.PI;
				coneMesh1.position.y = conesDistance + coneHeight;
				scene.add( coneMesh1 );

M
Mr.doob 已提交
275
				var coneMesh2 = new THREE.Mesh( coneMesh1.geometry.clone(), new THREE.MeshPhongMaterial( { color: 0xFF2020, emissive: 0x1F0202 } ) );
276 277 278 279 280
				coneMesh2.position.y = coneHeightHalf;
				scene.add( coneMesh2 );

				// Lightning strike

M
Mr.doob 已提交
281
				scene.userData.lightningMaterial = new THREE.MeshBasicMaterial( { color: scene.userData.lightningColor } );
282 283 284

				scene.userData.rayParams = {

M
Mr.doob 已提交
285 286
					sourceOffset: new THREE.Vector3(),
					destOffset: new THREE.Vector3(),
287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314
					radius0: 4,
					radius1: 4,
					minRadius: 2.5,
					maxIterations: 7,
					isEternal: true,

					timeScale: 0.7,

					propagationTimeFactor: 0.05,
					vanishingTimeFactor: 0.95,
					subrayPeriod: 3.5,
					subrayDutyCycle: 0.6,
					maxSubrayRecursion: 3,
					ramification: 7,
					recursionProbability: 0.6,

					roughness: 0.85,
					straightness: 0.6

				};

				var lightningStrike;
				var lightningStrikeMesh;
				var outlineMeshArray = [];

				scene.userData.recreateRay = function () {

					if ( lightningStrikeMesh ) {
M
Mugen87 已提交
315

316
						scene.remove( lightningStrikeMesh );
M
Mugen87 已提交
317

318 319
					}

M
Mugen87 已提交
320
					lightningStrike = new LightningStrike( scene.userData.rayParams );
M
Mr.doob 已提交
321
					lightningStrikeMesh = new THREE.Mesh( lightningStrike, scene.userData.lightningMaterial );
322 323 324 325 326 327

					outlineMeshArray.length = 0;
					outlineMeshArray.push( lightningStrikeMesh );

					scene.add( lightningStrikeMesh );

M
Mugen87 已提交
328
				};
329 330 331 332 333 334

				scene.userData.recreateRay();

				// Compose rendering

				composer.passes = [];
M
Mugen87 已提交
335
				composer.addPass( new RenderPass( scene, scene.userData.camera ) );
336 337 338 339
				createOutline( scene, outlineMeshArray, scene.userData.outlineColor );

				// Controls

M
Mugen87 已提交
340 341
				var controls = new OrbitControls( scene.userData.camera, renderer.domElement );
				controls.target.y = ( conesDistance + coneHeight ) * 0.5;
342
				controls.enableDamping = true;
W
WestLangley 已提交
343
				controls.dampingFactor = 0.05;
344 345 346 347

				scene.userData.render = function ( time ) {

					// Move cones and Update ray position
M
Mugen87 已提交
348
					coneMesh1.position.set( Math.sin( 0.5 * time ) * conesDistance * 0.6, conesDistance + coneHeight, Math.cos( 0.5 * time ) * conesDistance * 0.6 );
349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365
					coneMesh2.position.set( Math.sin( 0.9 * time ) * conesDistance, coneHeightHalf, 0 );
					lightningStrike.rayParameters.sourceOffset.copy( coneMesh1.position );
					lightningStrike.rayParameters.sourceOffset.y -= coneHeightHalf;
					lightningStrike.rayParameters.destOffset.copy( coneMesh2.position );
					lightningStrike.rayParameters.destOffset.y += coneHeightHalf;

					lightningStrike.update( time );

					controls.update();

					// Update point light position to the middle of the ray
					posLight.position.lerpVectors( lightningStrike.rayParameters.sourceOffset, lightningStrike.rayParameters.destOffset, 0.5 );

					if ( scene.userData.outlineEnabled ) {

						composer.render();

M
Mugen87 已提交
366
					}	else {
367 368 369 370 371 372 373 374 375 376 377 378 379 380 381

						renderer.render( scene, scene.userData.camera );

					}

				};

				return scene;

			}

			//

			function createPlasmaBallScene() {

M
Mr.doob 已提交
382
				var scene = new THREE.Scene();
383 384 385

				scene.userData.canGoBackwardsInTime = true;

M
Mr.doob 已提交
386
				scene.userData.camera = new THREE.PerspectiveCamera( 27, window.innerWidth / window.innerHeight, 100, 50000 );
387

M
Mr.doob 已提交
388 389
				var ballScene = new THREE.Scene();
				ballScene.background = new THREE.Color( 0x454545 );
390 391 392

				// Lights

M
Mr.doob 已提交
393
				var ambientLight = new THREE.AmbientLight( 0x444444 );
394 395 396
				ballScene.add( ambientLight );
				scene.add( ambientLight );

M
Mr.doob 已提交
397
				var light1 = new THREE.DirectionalLight( 0xffffff, 0.5 );
398 399 400 401
				light1.position.set( 1, 1, 1 );
				ballScene.add( light1 );
				scene.add( light1 );

M
Mr.doob 已提交
402
				var light2 = new THREE.DirectionalLight( 0xffffff, 1.5 );
M
Mugen87 已提交
403
				light2.position.set( - 0.5, 1, 0.2 );
404 405 406 407 408
				ballScene.add( light2 );
				scene.add( light2 );

				// Plasma ball

M
Mr.doob 已提交
409 410
				scene.userData.lightningColor = new THREE.Color( 0xFFB0FF );
				scene.userData.outlineColor = new THREE.Color( 0xFF00FF );
411

M
Mr.doob 已提交
412
				scene.userData.lightningMaterial = new THREE.MeshBasicMaterial( { color: scene.userData.lightningColor, side: THREE.DoubleSide } );
413 414 415 416 417 418

				var r = "textures/cube/Bridge2/";
				var urls = [ r + "posx.jpg", r + "negx.jpg",
							 r + "posy.jpg", r + "negy.jpg",
							 r + "posz.jpg", r + "negz.jpg" ];

M
Mr.doob 已提交
419 420 421
				var textureCube = new THREE.CubeTextureLoader().load( urls );
				textureCube.format = THREE.RGBFormat;
				textureCube.mapping = THREE.CubeReflectionMapping;
422

M
Mr.doob 已提交
423
				var sphereMaterial = new THREE.MeshPhysicalMaterial( {
424
					transparent: true,
425
					transparency: .96,
426
					depthWrite: false,
427 428
					color: 'white',
					metalness: 0,
429 430 431 432 433 434 435 436 437
					roughness: 0,
					envMap: textureCube
				} );

				var sphereHeight = 300;
				var sphereRadius = 200;

				scene.userData.camera.position.set( 5 * sphereRadius, 2 * sphereHeight, 6 * sphereRadius );

M
Mr.doob 已提交
438
				var sphereMesh = new THREE.Mesh( new THREE.SphereBufferGeometry( sphereRadius, 80, 40 ), sphereMaterial );
439 440 441
				sphereMesh.position.set( 0, sphereHeight, 0 );
				ballScene.add( sphereMesh );

M
Mr.doob 已提交
442
				var sphere = new THREE.Sphere( sphereMesh.position, sphereRadius );
443

M
Mr.doob 已提交
444
				var spherePlasma = new THREE.Mesh( new THREE.SphereBufferGeometry( sphereRadius * 0.05, 24, 12 ), scene.userData.lightningMaterial );
445 446 447 448
				spherePlasma.position.copy( sphereMesh.position );
				spherePlasma.scale.y = 0.6;
				scene.add( spherePlasma );

M
Mr.doob 已提交
449 450 451
				var post = new THREE.Mesh(
					new THREE.CylinderBufferGeometry( sphereRadius * 0.06, sphereRadius * 0.06, sphereHeight, 6, 1, true ),
					new THREE.MeshLambertMaterial( { color: 0x020202 } )
452 453 454 455
				);
				post.position.y = sphereHeight * 0.5 - sphereRadius * 0.05 * 1.2;
				scene.add( post );

M
Mr.doob 已提交
456
				var box = new THREE.Mesh( new THREE.BoxBufferGeometry( sphereHeight * 0.5, sphereHeight * 0.1, sphereHeight * 0.5 ), post.material );
457 458 459
				box.position.y = sphereHeight * 0.05 * 0.5;
				scene.add( box );

M
Mr.doob 已提交
460
				var rayDirection = new THREE.Vector3();
461
				var rayLength = 0;
M
Mr.doob 已提交
462 463
				var vec1 = new THREE.Vector3();
				var vec2 = new THREE.Vector3();
464 465 466 467

				scene.userData.rayParams = {

					sourceOffset: sphereMesh.position,
M
Mr.doob 已提交
468
					destOffset: new THREE.Vector3( sphereRadius, 0, 0 ).add( sphereMesh.position ),
469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488
					radius0: 4,
					radius1: 4,
					radius0Factor: 0.82,
					minRadius: 2.5,
					maxIterations: 6,
					isEternal: true,

					timeScale: 0.6,
					propagationTimeFactor: 0.15,
					vanishingTimeFactor: 0.87,
					subrayPeriod: 0.8,
					ramification: 5,
					recursionProbability: 0.8,

					roughness: 0.85,
					straightness: 0.7,

					onSubrayCreation: function ( segment, parentSubray, childSubray, lightningStrike ) {

						lightningStrike.subrayConePosition( segment, parentSubray, childSubray, 0.6, 0.9, 0.7 );
489

M
Mr.doob 已提交
490
						// THREE.Sphere projection
491 492 493 494

						vec1.subVectors( childSubray.pos1, lightningStrike.rayParameters.sourceOffset );
						vec2.set( 0, 0, 0 );
						if ( lightningStrike.randomGenerator.random() < 0.7 ) {
M
Mugen87 已提交
495

496
							vec2.copy( rayDirection ).multiplyScalar( rayLength * 1.0865 );
M
Mugen87 已提交
497

498 499 500 501 502 503 504 505 506 507 508
						}
						vec1.add( vec2 ).setLength( rayLength );
						childSubray.pos1.addVectors( vec1, lightningStrike.rayParameters.sourceOffset );

					}

				};

				var lightningStrike;
				var lightningStrikeMesh;
				var outlineMeshArray = [];
509

510 511 512
				scene.userData.recreateRay = function () {

					if ( lightningStrikeMesh ) {
M
Mugen87 已提交
513

514
						scene.remove( lightningStrikeMesh );
M
Mugen87 已提交
515

516 517
					}

M
Mugen87 已提交
518
					lightningStrike = new LightningStrike( scene.userData.rayParams );
M
Mr.doob 已提交
519
					lightningStrikeMesh = new THREE.Mesh( lightningStrike, scene.userData.lightningMaterial );
520 521 522 523 524 525 526

					outlineMeshArray.length = 0;
					outlineMeshArray.push( lightningStrikeMesh );
					outlineMeshArray.push( spherePlasma );

					scene.add( lightningStrikeMesh );

M
Mugen87 已提交
527
				};
528 529 530 531 532 533 534

				scene.userData.recreateRay();

				// Compose rendering

				composer.passes = [];

M
Mugen87 已提交
535
				composer.addPass( new RenderPass( ballScene, scene.userData.camera ) );
536

M
Mugen87 已提交
537
				var rayPass = new RenderPass( scene, scene.userData.camera );
538 539 540 541 542 543 544 545 546 547 548 549 550 551 552
				rayPass.clear = false;
				composer.addPass( rayPass );

				var outlinePass = createOutline( scene, outlineMeshArray, scene.userData.outlineColor );

				scene.userData.render = function ( time ) {

					rayDirection.subVectors( lightningStrike.rayParameters.destOffset, lightningStrike.rayParameters.sourceOffset );
					rayLength = rayDirection.length();
					rayDirection.normalize();

					lightningStrike.update( time );

					controls.update();

553
					outlinePass.enabled = scene.userData.outlineEnabled;
554 555 556 557 558 559 560

					composer.render();

				};

				// Controls

M
Mugen87 已提交
561
				var controls = new OrbitControls( scene.userData.camera, renderer.domElement );
562 563
				controls.target.copy( sphereMesh.position );
				controls.enableDamping = true;
W
WestLangley 已提交
564
				controls.dampingFactor = 0.05;
565

M
Mr.doob 已提交
566
				// THREE.Sphere mouse raycasting
567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593

				window.addEventListener( 'mousemove', onTouchMove );
				window.addEventListener( 'touchmove', onTouchMove );

				function onTouchMove( event ) {

					var x, y;

					if ( event.changedTouches ) {

						x = event.changedTouches[ 0 ].pageX;
						y = event.changedTouches[ 0 ].pageY;

					} else {

						x = event.clientX;
						y = event.clientY;

					}

					mouse.x = ( x / window.innerWidth ) * 2 - 1;
					mouse.y = - ( y / window.innerHeight ) * 2 + 1;

					checkIntersection();

				}

M
Mr.doob 已提交
594
				var intersection = new THREE.Vector3();
595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612

				function checkIntersection() {

					raycaster.setFromCamera( mouse, scene.userData.camera );

					var result = raycaster.ray.intersectSphere( sphere, intersection );

					if ( result !== null ) {

						lightningStrike.rayParameters.destOffset.copy( intersection );

					}

				}

				return scene;

			}
613

614
			//
615

616 617
			function createStormScene() {

M
Mr.doob 已提交
618 619
				var scene = new THREE.Scene();
				scene.background = new THREE.Color( 0x050505 );
620 621 622

				scene.userData.canGoBackwardsInTime = false;

M
Mr.doob 已提交
623
				scene.userData.camera = new THREE.PerspectiveCamera( 27, window.innerWidth / window.innerHeight, 20, 10000 );
624 625 626

				// Lights

M
Mr.doob 已提交
627
				scene.add( new THREE.AmbientLight( 0x444444 ) );
628

M
Mr.doob 已提交
629
				var light1 = new THREE.DirectionalLight( 0xffffff, 0.5 );
630 631 632
				light1.position.set( 1, 1, 1 );
				scene.add( light1 );

M
Mr.doob 已提交
633
				var posLight = new THREE.PointLight( 0x00ffff );
634 635 636 637 638 639 640 641 642
				posLight.position.set( 0, 100, 0 );
				scene.add( posLight );

				// Ground

				var GROUND_SIZE = 1000;

				scene.userData.camera.position.set( 0, 0.2, 1.6 ).multiplyScalar( GROUND_SIZE * 0.5 );

M
Mr.doob 已提交
643
				var ground = new THREE.Mesh( new THREE.PlaneBufferGeometry( GROUND_SIZE, GROUND_SIZE ), new THREE.MeshLambertMaterial( { color: 0x072302 } ) );
644 645 646 647 648
				ground.rotation.x = - Math.PI * 0.5;
				scene.add( ground );

				// Storm

M
Mr.doob 已提交
649 650
				scene.userData.lightningColor = new THREE.Color( 0xB0FFFF );
				scene.userData.outlineColor = new THREE.Color( 0x00FFFF );
651

M
Mr.doob 已提交
652
				scene.userData.lightningMaterial = new THREE.MeshBasicMaterial( { color: scene.userData.lightningColor } );
653

M
Mr.doob 已提交
654
				var rayDirection = new THREE.Vector3( 0, - 1, 0 );
655
				var rayLength = 0;
M
Mr.doob 已提交
656 657
				var vec1 = new THREE.Vector3();
				var vec2 = new THREE.Vector3();
658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683

				scene.userData.rayParams = {

					radius0: 1,
					radius1: 0.5,
					minRadius: 0.3,
					maxIterations: 7,

					timeScale: 0.15,
					propagationTimeFactor: 0.2,
					vanishingTimeFactor: 0.9,
					subrayPeriod: 4,
					subrayDutyCycle: 0.6,

					maxSubrayRecursion: 3,
					ramification: 3,
					recursionProbability: 0.4,

					roughness: 0.85,
					straightness: 0.65,

					onSubrayCreation: function ( segment, parentSubray, childSubray, lightningStrike ) {

						lightningStrike.subrayConePosition( segment, parentSubray, childSubray, 0.6, 0.6, 0.5 );

						// Plane projection
684

685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700
						rayLength = lightningStrike.rayParameters.sourceOffset.y;
						vec1.subVectors( childSubray.pos1, lightningStrike.rayParameters.sourceOffset );
						var proj = rayDirection.dot( vec1 );
						vec2.copy( rayDirection ).multiplyScalar( proj );
						vec1.sub( vec2 );
						var scale = proj / rayLength > 0.5 ? rayLength / proj : 1;
						vec2.multiplyScalar( scale );
						vec1.add( vec2 );
						childSubray.pos1.addVectors( vec1, lightningStrike.rayParameters.sourceOffset );

					}

				};

				// Black star mark
				var starVertices = [];
M
Mr.doob 已提交
701 702
				var prevPoint = new THREE.Vector3( 0, 0, 1 );
				var currPoint = new THREE.Vector3();
M
Mugen87 已提交
703
				for ( var i = 1; i <= 16; i ++ ) {
704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720

					currPoint.set( Math.sin( 2 * Math.PI * i / 16 ), 0, Math.cos( 2 * Math.PI * i / 16 ) );

					if ( i % 2 === 1 ) {

						currPoint.multiplyScalar( 0.3 );

					}

					starVertices.push( 0, 0, 0 );
					starVertices.push( prevPoint.x, prevPoint.y, prevPoint.z );
					starVertices.push( currPoint.x, currPoint.y, currPoint.z );

					prevPoint.copy( currPoint );

				}

M
Mr.doob 已提交
721 722 723
				var starGeometry = new THREE.BufferGeometry();
				starGeometry.addAttribute( 'position', new THREE.Float32BufferAttribute( starVertices, 3 ) );
				var starMesh = new THREE.Mesh( starGeometry, new THREE.MeshBasicMaterial( { color: 0x020900 } ) );
724
				starMesh.scale.multiplyScalar( 6 );
725

726 727
				//

M
Mugen87 已提交
728
				var storm = new LightningStorm( {
729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757

					size: GROUND_SIZE,
					minHeight: 90,
					maxHeight: 200,
					maxSlope: 0.6,
					maxLightnings: 8,

					lightningParameters: scene.userData.rayParams,

					lightningMaterial: scene.userData.lightningMaterial,

					onLightningDown: function ( lightning ) {

						// Add black star mark at ray strike
						var star1 = starMesh.clone();
						star1.position.copy( lightning.rayParameters.destOffset );
						star1.position.y = 0.05;
						star1.rotation.y = 2 * Math.PI * Math.random();
						scene.add( star1 );

					}

				} );

				scene.add( storm );

				// Compose rendering

				composer.passes = [];
M
Mugen87 已提交
758
				composer.addPass( new RenderPass( scene, scene.userData.camera ) );
759 760 761 762
				createOutline( scene, storm.lightningsMeshes, scene.userData.outlineColor );

				// Controls

M
Mugen87 已提交
763
				var controls = new OrbitControls( scene.userData.camera, renderer.domElement );
764 765
				controls.target.y = GROUND_SIZE * 0.05;
				controls.enableDamping = true;
W
WestLangley 已提交
766
				controls.dampingFactor = 0.05;
767 768 769 770 771 772 773 774 775 776 777

				scene.userData.render = function ( time ) {

					storm.update( time );

					controls.update();

					if ( scene.userData.outlineEnabled ) {

						composer.render();

M
Mugen87 已提交
778
					}	else {
779 780 781 782 783 784 785 786 787 788 789 790 791 792 793

						renderer.render( scene, scene.userData.camera );

					}

				};

				return scene;

			}

		</script>

	</body>
</html>