webgl_custom_attributes_points2.html 6.0 KB
Newer Older
M
Mr.doob 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
<!DOCTYPE html>
<html lang="en">
	<head>
		<title>three.js webgl - custom attributes [particles][billboards]</title>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
		<style>
			body {
				color: #ffffff;
				font-family:Monospace;
				font-size:13px;
				text-align:center;
				font-weight: bold;

				background-color: #000000;
				margin: 0px;
				overflow: hidden;
			}
			#info {
				color: #fff;
				position: absolute;
				top: 0px; width: 100%;
				padding: 5px;
				z-index:100;
			}

		</style>
	</head>

	<body>
		<div id="info"><a href="http://threejs.org" target="_blank">three.js</a> - custom attributes example - particles - billboards</div>
		<div id="container"></div>

M
r76  
Mr.doob 已提交
34
		<script src="../build/three.js"></script>
M
Mr.doob 已提交
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51

		<script src="js/Detector.js"></script>
		<script src="js/libs/stats.min.js"></script>

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

			attribute float size;
			attribute vec3 ca;

			varying vec3 vColor;

			void main() {

				vColor = ca;

				vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );

M
r74  
Mr.doob 已提交
52
				gl_PointSize = size * ( 300.0 / -mvPosition.z );
M
Mr.doob 已提交
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68

				gl_Position = projectionMatrix * mvPosition;

			}

		</script>

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

			uniform vec3 color;
			uniform sampler2D texture;

			varying vec3 vColor;

			void main() {

M
r70  
Mr.doob 已提交
69 70 71
				vec4 color = vec4( color * vColor, 1.0 ) * texture2D( texture, gl_PointCoord );

				gl_FragColor = color;
M
Mr.doob 已提交
72 73 74 75 76 77 78 79 80 81

			}

		</script>

		<script>

		if ( ! Detector.webgl ) Detector.addGetWebGLMessage();

		var renderer, scene, camera, stats;
M
r72  
Mr.doob 已提交
82
		var sphere, vertices1;
M
Mr.doob 已提交
83 84 85 86 87 88 89 90 91 92 93 94 95 96

		var WIDTH = window.innerWidth;
		var HEIGHT = window.innerHeight;

		init();
		animate();

		function init() {

			camera = new THREE.PerspectiveCamera( 45, WIDTH / HEIGHT, 1, 10000 );
			camera.position.z = 300;

			scene = new THREE.Scene();

M
r72  
Mr.doob 已提交
97
			var radius = 100, segments = 68, rings = 38;
M
Mr.doob 已提交
98

M
r72  
Mr.doob 已提交
99 100
			var geometry1 = new THREE.SphereGeometry( radius, segments, rings );
			var geometry2 = new THREE.BoxGeometry( 0.8 * radius, 0.8 * radius, 0.8 * radius, 10, 10, 10 );
M
Mr.doob 已提交
101

M
r72  
Mr.doob 已提交
102
			vertices1 = geometry1.vertices.length;
M
Mr.doob 已提交
103

M
r72  
Mr.doob 已提交
104
			var vertices = geometry1.vertices.concat( geometry2.vertices );
M
Mr.doob 已提交
105

M
r72  
Mr.doob 已提交
106 107 108
			var positions = new Float32Array( vertices.length * 3 );
			var colors = new Float32Array( vertices.length * 3 );
			var sizes = new Float32Array( vertices.length );
M
Mr.doob 已提交
109

M
r72  
Mr.doob 已提交
110 111
			var vertex;
			var color = new THREE.Color();
M
Mr.doob 已提交
112

M
r72  
Mr.doob 已提交
113
			for ( var i = 0, l = vertices.length; i < l; i ++ ) {
M
Mr.doob 已提交
114

M
r72  
Mr.doob 已提交
115 116
				vertex = vertices[ i ];
				vertex.toArray( positions, i * 3 );
M
Mr.doob 已提交
117

M
r72  
Mr.doob 已提交
118
				if ( i < vertices1 ) {
M
Mr.doob 已提交
119

M
r72  
Mr.doob 已提交
120
					color.setHSL( 0.01 + 0.1 * ( i / vertices1 ), 0.99, ( vertex.y + radius ) / ( 4 * radius ) );
M
Mr.doob 已提交
121

M
r72  
Mr.doob 已提交
122
				} else {
M
Mr.doob 已提交
123

M
r72  
Mr.doob 已提交
124
					color.setHSL( 0.6, 0.75, 0.25 + vertex.y / ( 2 * radius ) );
M
Mr.doob 已提交
125

M
r72  
Mr.doob 已提交
126
				}
M
Mr.doob 已提交
127

M
r72  
Mr.doob 已提交
128
				color.toArray( colors, i * 3 );
M
Mr.doob 已提交
129

M
r72  
Mr.doob 已提交
130
				sizes[ i ] = i < vertices1 ? 10 : 40;
M
Mr.doob 已提交
131

M
r72  
Mr.doob 已提交
132
			}
M
Mr.doob 已提交
133

M
r72  
Mr.doob 已提交
134 135 136 137
			var geometry = new THREE.BufferGeometry();
			geometry.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );
			geometry.addAttribute( 'size', new THREE.BufferAttribute( sizes, 1 ) );
			geometry.addAttribute( 'ca', new THREE.BufferAttribute( colors, 3 ) );
M
Mr.doob 已提交
138

M
r72  
Mr.doob 已提交
139
			//
M
Mr.doob 已提交
140

M
r74  
Mr.doob 已提交
141
			var texture = new THREE.TextureLoader().load( "textures/sprites/disc.png" );
M
r72  
Mr.doob 已提交
142 143
			texture.wrapS = THREE.RepeatWrapping;
			texture.wrapT = THREE.RepeatWrapping;
M
Mr.doob 已提交
144

M
r72  
Mr.doob 已提交
145
			var material = new THREE.ShaderMaterial( {
M
Mr.doob 已提交
146

M
r72  
Mr.doob 已提交
147
				uniforms: {
M
r78  
Mr.doob 已提交
148 149 150
					amplitude: { value: 1.0 },
					color:     { value: new THREE.Color( 0xffffff ) },
					texture:   { value: texture }
M
r72  
Mr.doob 已提交
151 152 153 154
				},
				vertexShader:   document.getElementById( 'vertexshader' ).textContent,
				fragmentShader: document.getElementById( 'fragmentshader' ).textContent,
				transparent:    true
M
Mr.doob 已提交
155

M
r72  
Mr.doob 已提交
156
			});
M
Mr.doob 已提交
157

M
r72  
Mr.doob 已提交
158
			//
M
Mr.doob 已提交
159

M
r72  
Mr.doob 已提交
160
			sphere = new THREE.Points( geometry, material );
M
Mr.doob 已提交
161 162
			scene.add( sphere );

M
r72  
Mr.doob 已提交
163 164
			//

M
r65  
Mr.doob 已提交
165
			renderer = new THREE.WebGLRenderer();
M
r70  
Mr.doob 已提交
166
			renderer.setPixelRatio( window.devicePixelRatio );
M
Mr.doob 已提交
167 168 169 170 171 172
			renderer.setSize( WIDTH, HEIGHT );

			var container = document.getElementById( 'container' );
			container.appendChild( renderer.domElement );

			stats = new Stats();
M
r76  
Mr.doob 已提交
173
			container.appendChild( stats.dom );
M
Mr.doob 已提交
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189

			//

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

		}

		function onWindowResize() {

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

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

		}

M
r72  
Mr.doob 已提交
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 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254
		function sortPoints() {

			var vector = new THREE.Vector3();

			// Model View Projection matrix

			var matrix = new THREE.Matrix4();
			matrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
			matrix.multiply( sphere.matrixWorld );

			//

			var geometry = sphere.geometry;

			var index = geometry.getIndex();
			var positions = geometry.getAttribute( 'position' ).array;
			var length = positions.length / 3;

			if ( index === null ) {

				var array = new Uint16Array( length );

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

					array[ i ] = i;

				}

				index = new THREE.BufferAttribute( array, 1 );

				geometry.setIndex( index );

			}

			var sortArray = [];

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

				vector.fromArray( positions, i * 3 );
				vector.applyProjection( matrix );

				sortArray.push( [ vector.z, i ] );

			}

			function numericalSort( a, b ) {

				return b[ 0 ] - a[ 0 ];

			}

			sortArray.sort( numericalSort );

			var indices = index.array;

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

				indices[ i ] = sortArray[ i ][ 1 ];

			}

			geometry.index.needsUpdate = true;

		}

M
Mr.doob 已提交
255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270
		function animate() {

			requestAnimationFrame( animate );

			render();
			stats.update();

		}

		function render() {

			var time = Date.now() * 0.005;

			sphere.rotation.y = 0.02 * time;
			sphere.rotation.z = 0.02 * time;

M
r72  
Mr.doob 已提交
271 272 273 274
			var geometry = sphere.geometry;
			var attributes = geometry.attributes;

			for ( var i = 0; i < attributes.size.array.length; i ++ ) {
M
Mr.doob 已提交
275

M
r72  
Mr.doob 已提交
276
				if ( i < vertices1 ) {
M
Mr.doob 已提交
277

M
r72  
Mr.doob 已提交
278 279 280
					attributes.size.array[ i ] = 16 + 12 * Math.sin( 0.1 * i + time );

				}
M
Mr.doob 已提交
281 282 283 284 285

			}

			attributes.size.needsUpdate = true;

M
r72  
Mr.doob 已提交
286 287
			sortPoints();

M
Mr.doob 已提交
288 289 290 291 292 293 294 295 296
			renderer.render( scene, camera );

		}

	</script>

</body>

</html>