|
@@ -0,0 +1,253 @@
|
|
|
+<!DOCTYPE html>
|
|
|
+<html lang="en">
|
|
|
+ <head>
|
|
|
+ <title>three.js webgl - buffer geometry custom attributes [particles]</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;
|
|
|
+ background-color: rgba( 0, 0, 0, 0.75 );
|
|
|
+ position: relative;
|
|
|
+ top: 0px; width: 100%;
|
|
|
+ padding: 5px;
|
|
|
+ z-index:100;
|
|
|
+ width:33em;
|
|
|
+ margin:0 auto -2em;
|
|
|
+ }
|
|
|
+ a { color: #ff0000 }
|
|
|
+ </style>
|
|
|
+ </head>
|
|
|
+
|
|
|
+ <body>
|
|
|
+ <div id="info"><a href="http://threejs.org" target="_blank">three.js</a> - buffergeometry custom attributes example - particles</div>
|
|
|
+ <div id="container"></div>
|
|
|
+
|
|
|
+ <script src="../build/three.min.js"></script>
|
|
|
+ <script src="../src/renderers/WebGLRenderer.js"></script>
|
|
|
+
|
|
|
+ <script src="js/Detector.js"></script>
|
|
|
+ <script src="js/libs/stats.min.js"></script>
|
|
|
+
|
|
|
+ <script type="x-shader/x-vertex" id="vertexshader">
|
|
|
+
|
|
|
+ uniform float amplitude;
|
|
|
+ attribute float size;
|
|
|
+ attribute vec3 customColor;
|
|
|
+
|
|
|
+ varying vec3 vColor;
|
|
|
+
|
|
|
+ void main() {
|
|
|
+
|
|
|
+ vColor = customColor;
|
|
|
+
|
|
|
+ vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
|
|
|
+
|
|
|
+ //gl_PointSize = size;
|
|
|
+ gl_PointSize = size * ( 300.0 / length( mvPosition.xyz ) );
|
|
|
+
|
|
|
+ gl_Position = projectionMatrix * mvPosition;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ </script>
|
|
|
+
|
|
|
+ <script type="x-shader/x-fragment" id="fragmentshader">
|
|
|
+
|
|
|
+ uniform vec3 color;
|
|
|
+ uniform sampler2D texture;
|
|
|
+
|
|
|
+ varying vec3 vColor;
|
|
|
+
|
|
|
+ void main() {
|
|
|
+
|
|
|
+ gl_FragColor = vec4( color * vColor, 1.0 );
|
|
|
+ gl_FragColor = gl_FragColor * texture2D( texture, gl_PointCoord );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ </script>
|
|
|
+
|
|
|
+
|
|
|
+ <script>
|
|
|
+
|
|
|
+ if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
|
|
|
+
|
|
|
+ var renderer, scene, camera, stats;
|
|
|
+
|
|
|
+ var sphere, uniforms, geometry;
|
|
|
+
|
|
|
+ var noise = [];
|
|
|
+ var values_size;
|
|
|
+ //500000
|
|
|
+ var particles = 100000;
|
|
|
+
|
|
|
+ var WIDTH = window.innerWidth;
|
|
|
+ var HEIGHT = window.innerHeight;
|
|
|
+
|
|
|
+ init();
|
|
|
+ animate();
|
|
|
+
|
|
|
+ function init() {
|
|
|
+
|
|
|
+ camera = new THREE.PerspectiveCamera( 40, WIDTH / HEIGHT, 1, 10000 );
|
|
|
+ camera.position.z = 300;
|
|
|
+
|
|
|
+ scene = new THREE.Scene();
|
|
|
+
|
|
|
+ var attributes = {
|
|
|
+
|
|
|
+ size: { type: 'f', value: null },
|
|
|
+ customColor: { type: 'c', value: null }
|
|
|
+
|
|
|
+ };
|
|
|
+
|
|
|
+ uniforms = {
|
|
|
+
|
|
|
+ amplitude: { type: "f", value: 1.0 },
|
|
|
+ color: { type: "c", value: new THREE.Color( 0xffffff ) },
|
|
|
+ texture: { type: "t", value: THREE.ImageUtils.loadTexture( "textures/sprites/spark1.png" ) },
|
|
|
+
|
|
|
+ };
|
|
|
+
|
|
|
+ var shaderMaterial = new THREE.ShaderMaterial( {
|
|
|
+
|
|
|
+ uniforms: uniforms,
|
|
|
+ attributes: attributes,
|
|
|
+ vertexShader: document.getElementById( 'vertexshader' ).textContent,
|
|
|
+ fragmentShader: document.getElementById( 'fragmentshader' ).textContent,
|
|
|
+
|
|
|
+ blending: THREE.AdditiveBlending,
|
|
|
+ depthTest: false,
|
|
|
+ transparent: true
|
|
|
+
|
|
|
+ });
|
|
|
+
|
|
|
+
|
|
|
+ var radius = 200;
|
|
|
+
|
|
|
+ geometry = new THREE.BufferGeometry();
|
|
|
+ geometry.dynamic = true;
|
|
|
+ geometry.attributes = {
|
|
|
+
|
|
|
+ position: {
|
|
|
+ itemSize: 3,
|
|
|
+ array: new Float32Array( particles * 3 ),
|
|
|
+ numItems: particles * 3
|
|
|
+ },
|
|
|
+ customColor: {
|
|
|
+ itemSize: 3,
|
|
|
+ array: new Float32Array( particles * 3 ),
|
|
|
+ numItems: particles * 3
|
|
|
+ },
|
|
|
+ size: {
|
|
|
+ itemSize: 1,
|
|
|
+ array: new Float32Array( particles ),
|
|
|
+ numItems: particles * 1
|
|
|
+ },
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ values_size = geometry.attributes.size.array;
|
|
|
+ var positions = geometry.attributes.position.array;
|
|
|
+ var values_color = geometry.attributes.customColor.array;
|
|
|
+
|
|
|
+ sphere = new THREE.ParticleSystem( geometry, shaderMaterial );
|
|
|
+
|
|
|
+ sphere.dynamic = true;
|
|
|
+ //sphere.sortParticles = true;
|
|
|
+
|
|
|
+ var color = new THREE.Color( 0xffaa00 );;
|
|
|
+
|
|
|
+ for( var v = 0; v < particles; v++ ) {
|
|
|
+
|
|
|
+ values_size[ v ] = 10;
|
|
|
+
|
|
|
+ positions[ v * 3 + 0 ] = (Math.random() * 2 - 1) * radius;
|
|
|
+ positions[ v * 3 + 1 ] = (Math.random() * 2 - 1) * radius;
|
|
|
+ positions[ v * 3 + 2 ] = (Math.random() * 2 - 1) * radius;
|
|
|
+
|
|
|
+ if ( positions[ v * 3 + 0 ] < 0 )
|
|
|
+ color.setHSL( 0.5 + 0.1 * ( v / particles ), 0.7, 0.1 );
|
|
|
+ else
|
|
|
+ color.setHSL( 0.0 + 0.1 * ( v / particles ), 0.9, 0.1 );
|
|
|
+
|
|
|
+ values_color[ v * 3 + 0 ] = color.r;
|
|
|
+ values_color[ v * 3 + 1 ] = color.g;
|
|
|
+ values_color[ v * 3 + 2 ] = color.b;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ scene.add( sphere );
|
|
|
+
|
|
|
+ renderer = new THREE.WebGLRenderer( { clearColor: 0x000000, clearAlpha: 1 } );
|
|
|
+ renderer.setSize( WIDTH, HEIGHT );
|
|
|
+
|
|
|
+ var container = document.getElementById( 'container' );
|
|
|
+ container.appendChild( renderer.domElement );
|
|
|
+
|
|
|
+ stats = new Stats();
|
|
|
+ stats.domElement.style.position = 'absolute';
|
|
|
+ stats.domElement.style.top = '0px';
|
|
|
+ container.appendChild( stats.domElement );
|
|
|
+
|
|
|
+ //
|
|
|
+
|
|
|
+ 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 );
|
|
|
+
|
|
|
+ render();
|
|
|
+ stats.update();
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ function render() {
|
|
|
+
|
|
|
+ var time = Date.now() * 0.005;
|
|
|
+
|
|
|
+ sphere.rotation.z = 0.01 * time;
|
|
|
+
|
|
|
+ for( var i = 0; i < particles; i++ ) {
|
|
|
+
|
|
|
+ values_size[ i ] = 14 + 13 * Math.sin( 0.1 * i + time );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ geometry.attributes.size.needsUpdate = true;
|
|
|
+
|
|
|
+ renderer.render( scene, camera );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ </script>
|
|
|
+
|
|
|
+</body>
|
|
|
+
|
|
|
+</html>
|