webgl_lightshafts.html 5.5 KB
Newer Older
M
Mugen87 已提交
1 2 3 4 5 6
<!DOCTYPE html>
<html lang="en">
	<head>
		<title>three.js webgl - Light Shafts</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">
M
Mugen87 已提交
8 9 10 11
	</head>

	<body>
		<div id="info">
M
Mugen87 已提交
12
			<a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> - Light Shafts<br/>
M
Mugen87 已提交
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
			Model by <a href="https://skfb.ly/6ICER" target="_blank" rel="noopener">Splodeman</a><br />
		</div>

		<script type="x-shader/x-vertex" id="vertexShader">

		#include <common>

		uniform float speed;
		uniform float time;
		uniform float timeOffset;
		varying vec2 vUv;
		varying float vAlpha;

		void main() {

			vec3 pos = position;

			float l = ( time * speed * 0.01 ) + timeOffset;
			float f = fract( l ); // linear time factor [0,1)
			float a = f * f; // quadratic time factor [0,1)

			// slightly animate the vertices of light shaft if necessary

			// pos.x += cos( l * 20.0 ) * sin( l * 10.0 );

			vAlpha = saturate( 0.7 + min( 1.0, a * 10.0 ) * ( sin( a * 40.0 ) * 0.25 ) );

		  vUv = uv;

			gl_Position = projectionMatrix * modelViewMatrix * vec4( pos, 1.0 );

		}

		</script>

		<script type="x-shader/x-fragment" id="fragmentShader">

		uniform float attenuation;
		uniform vec3 color;
A
aardgoose 已提交
52
		uniform sampler2D colorTexture;
M
Mugen87 已提交
53 54 55 56 57 58

		varying vec2 vUv;
		varying float vAlpha;

		void main() {

A
aardgoose 已提交
59
			vec4 textureColor = texture2D( colorTexture, vUv );
M
Mugen87 已提交
60 61 62 63 64 65 66
			gl_FragColor = vec4( textureColor.rgb * color.rgb, textureColor.a * vAlpha );
			gl_FragColor.a *= pow( gl_FragCoord.z, attenuation );

		}

		</script>

M
Mugen87 已提交
67
		<script type="module">
68

M
Mr.doob 已提交
69
			import * as THREE from '../build/three.module.js';
M
Mugen87 已提交
70 71 72

			import { OrbitControls } from './jsm/controls/OrbitControls.js';
			import { GLTFLoader } from './jsm/loaders/GLTFLoader.js';
M
Mugen87 已提交
73 74 75 76 77 78 79 80 81 82 83 84

			var container, controls, clock;
			var camera, scene, renderer, uniforms;

			init();
			animate();

			function init() {

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

M
Mr.doob 已提交
85
				camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.1, 100 );
M
Mugen87 已提交
86 87
				camera.position.set( 3.2, 3, 3.7 );

M
Mr.doob 已提交
88
				clock = new THREE.Clock();
M
Mugen87 已提交
89

M
Mr.doob 已提交
90 91
				scene = new THREE.Scene();
				scene.background = new THREE.Color( 0xcf8b74 );
M
Mugen87 已提交
92

M
Mr.doob 已提交
93
				var	light = new THREE.HemisphereLight( 0xffffff, 0x444444 );
M
Mugen87 已提交
94 95 96
				light.position.set( 0, 20, 0 );
				scene.add( light );

M
Mr.doob 已提交
97
				light = new THREE.DirectionalLight( 0xffffff );
M
Mugen87 已提交
98 99 100
				light.position.set( 0, 20, 10 );
				scene.add( light );

101
			 	// light shafts definition
M
Mugen87 已提交
102

M
Mr.doob 已提交
103
				var textureLoader = new THREE.TextureLoader();
M
Mugen87 已提交
104 105 106 107 108 109 110 111 112 113 114 115 116
				var texture = textureLoader.load( 'textures/lightShaft.png' );

				uniforms = {
					// controls how fast the ray attenuates when the camera comes closer
					attenuation: {
						value: 10
					},
					// controls the speed of the animation
					speed: {
						value: 2
					},
					// the color of the ray
					color: {
M
Mr.doob 已提交
117
						value: new THREE.Color( 0xdadc9f )
M
Mugen87 已提交
118 119
					},
					// the visual representation of the ray highly depends on the used texture
A
aardgoose 已提交
120
					colorTexture: {
M
Mugen87 已提交
121 122 123 124 125 126 127 128 129 130 131 132
						value: texture
					},
					// global time value for animation
					time: {
						value: 0
					},
					// individual time offset so rays are animated differently if necessary
					timeOffset: {
						value: 0
					}
				};

M
Mr.doob 已提交
133
				var lightShaftMaterial = new THREE.ShaderMaterial( {
M
Mugen87 已提交
134 135 136
					uniforms: uniforms,
					vertexShader: document.getElementById( 'vertexShader' ).textContent,
					fragmentShader: document.getElementById( 'fragmentShader' ).textContent,
M
Mr.doob 已提交
137
					blending: THREE.AdditiveBlending,
M
Mugen87 已提交
138 139
					depthWrite: false,
					transparent: true,
M
Mr.doob 已提交
140
					side: THREE.DoubleSide
M
Mugen87 已提交
141 142
				} );

M
Mr.doob 已提交
143
				var lightShaftGeometry = new THREE.PlaneBufferGeometry( 0.5, 5 );
M
Mugen87 已提交
144

145
				// model
M
Mugen87 已提交
146

M
Mugen87 已提交
147
				var loader = new GLTFLoader().setPath( 'models/gltf/Tree/' );
148
				loader.load( 'tree.glb', function ( gltf ) {
M
Mugen87 已提交
149

150 151 152 153 154 155
					gltf.scene.traverse( function ( child ) {

						if ( child.isMesh )	{

							child.material.transparent = false;
							child.material.alphaTest = 0.5;
156
							child.material.depthWrite = true;
157 158 159 160 161 162 163 164 165 166 167

						}

					} );

					scene.add( gltf.scene );

					// when the model is loaded, add light shafts

					for ( var i = 0; i < 5; i ++ ) {

M
Mr.doob 已提交
168
						var lightShaft = new THREE.Mesh( lightShaftGeometry, lightShaftMaterial );
169 170 171 172 173 174 175 176 177 178
						lightShaft.position.x = - 1 + 1.5 * Math.sign( ( i % 2 ) );
						lightShaft.position.y = 2;
						lightShaft.position.z = - 1.5 + ( i * 0.5 );
						lightShaft.rotation.y = Math.PI * 0.2;
						lightShaft.rotation.z = Math.PI * - ( 0.15 + 0.1 * Math.random() );
						scene.add( lightShaft );

					}

				} );
M
Mugen87 已提交
179 180 181

				//

M
Mr.doob 已提交
182
				renderer = new THREE.WebGLRenderer( { antialias: true } );
M
Mugen87 已提交
183 184
				renderer.setPixelRatio( window.devicePixelRatio );
				renderer.setSize( window.innerWidth, window.innerHeight );
185
				renderer.outputEncoding = THREE.sRGBEncoding;
M
Mugen87 已提交
186 187
				container.appendChild( renderer.domElement );

M
Mugen87 已提交
188
				controls = new OrbitControls( camera, renderer.domElement );
189 190 191 192 193
				controls.target.set( 0.5, 1.5, 0 );
				controls.minDistance = 2;
				controls.maxDistance = 20;
				controls.update();

M
Mugen87 已提交
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 220 221 222 223 224
				window.addEventListener( 'resize', onWindowResize, false );

			}

			function onWindowResize() {

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

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

			}

			//

			function animate() {

				requestAnimationFrame( animate );

				const delta = clock.getDelta();

				uniforms.time.value += delta;

				renderer.render( scene, camera );

			}

		</script>

	</body>
</html>