提交 99de0ac3 编写于 作者: A alteredq

Added handling of BufferGeometry for ParticleSystems plus corresponding example.

See #2349

Particles are rendered using drawArrays, so there is no need for indices or offsets.

Particle sorting not implemented for BufferGeometry, will need to check if this is possible to do efficiently.
上级 af9fb1d1
因为 它太大了无法显示 source diff 。你可以改为 查看blob
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - buffergeometry [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: #cccccc;
font-family:Monospace;
font-size:13px;
text-align:center;
background-color: #050505;
margin: 0px;
overflow: hidden;
}
#info {
position: absolute;
top: 0px; width: 100%;
padding: 5px;
}
a {
color: #0080ff;
}
</style>
</head>
<body>
<div id="container"></div>
<div id="info"><a href="http://github.com/mrdoob/three.js" target="_blank">three.js</a> webgl - buffergeometry - particles</div>
<script src="../build/three.min.js"></script>
<script src="js/Detector.js"></script>
<script src="js/Stats.js"></script>
<script>
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var container, stats;
var camera, scene, renderer;
var mesh;
init();
animate();
function init() {
container = document.getElementById( 'container' );
//
camera = new THREE.PerspectiveCamera( 27, window.innerWidth / window.innerHeight, 5, 3500 );
camera.position.z = 2750;
scene = new THREE.Scene();
scene.fog = new THREE.Fog( 0x050505, 2000, 3500 );
//
var particles = 1000000;
var geometry = new THREE.BufferGeometry();
geometry.attributes = {
position: {
itemSize: 3,
array: new Float32Array( particles * 3 ),
numItems: particles * 3
},
color: {
itemSize: 3,
array: new Float32Array( particles * 3 ),
numItems: particles * 3
}
}
var positions = geometry.attributes.position.array;
var colors = geometry.attributes.color.array;
var color = new THREE.Color();
var n = 1000, n2 = n/2; // particles spread in the cube
for ( var i = 0; i < positions.length; i += 3 ) {
// positions
var x = Math.random() * n - n2;
var y = Math.random() * n - n2;
var z = Math.random() * n - n2;
positions[ i ] = x;
positions[ i + 1 ] = y;
positions[ i + 2 ] = z;
// colors
var vx = ( x / n ) + 0.5;
var vy = ( y / n ) + 0.5;
var vz = ( z / n ) + 0.5;
//color.setHSV( 0.5 + 0.5 * vx, 0.25 + 0.75 * vy, 0.25 + 0.75 * vz );
color.setRGB( vx, vy, vz );
colors[ i ] = color.r;
colors[ i + 1 ] = color.g;
colors[ i + 2 ] = color.b;
}
geometry.computeBoundingSphere();
//
var material = new THREE.ParticleBasicMaterial( { size: 15, vertexColors: true } );
particleSystem = new THREE.ParticleSystem( geometry, material );
scene.add( particleSystem );
//
renderer = new THREE.WebGLRenderer( { antialias: false, clearColor: 0x333333, clearAlpha: 1, alpha: false } );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setClearColor( scene.fog.color, 1 );
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() {
windowHalfX = window.innerWidth / 2;
windowHalfY = window.innerHeight / 2;
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.001;
particleSystem.rotation.x = time * 0.25;
particleSystem.rotation.y = time * 0.5;
renderer.render( scene, camera );
}
</script>
</body>
</html>
...@@ -3216,6 +3216,42 @@ THREE.WebGLRenderer = function ( parameters ) { ...@@ -3216,6 +3216,42 @@ THREE.WebGLRenderer = function ( parameters ) {
} }
// render particles
} else if ( object instanceof THREE.ParticleSystem ) {
if ( updateBuffers ) {
// vertices
var position = geometry.attributes[ "position" ];
var positionSize = position.itemSize;
_gl.bindBuffer( _gl.ARRAY_BUFFER, position.buffer );
_gl.vertexAttribPointer( attributes.position, positionSize, _gl.FLOAT, false, 0, 0 );
// colors
var color = geometry.attributes[ "color" ];
if ( attributes.color >= 0 && color ) {
var colorSize = color.itemSize;
_gl.bindBuffer( _gl.ARRAY_BUFFER, color.buffer );
_gl.vertexAttribPointer( attributes.color, colorSize, _gl.FLOAT, false, 0, 0 );
}
// render particles
_gl.drawArrays( _gl.POINTS, 0, position.numItems / 3 );
_this.info.render.calls ++;
_this.info.render.points += position.numItems / 3;
}
} }
}; };
...@@ -4197,11 +4233,20 @@ THREE.WebGLRenderer = function ( parameters ) { ...@@ -4197,11 +4233,20 @@ THREE.WebGLRenderer = function ( parameters ) {
if ( ! geometry.__webglVertexBuffer ) { if ( ! geometry.__webglVertexBuffer ) {
createParticleBuffers( geometry ); if ( geometry instanceof THREE.Geometry ) {
initParticleBuffers( geometry, object );
createParticleBuffers( geometry );
initParticleBuffers( geometry, object );
geometry.verticesNeedUpdate = true;
geometry.colorsNeedUpdate = true;
} else if ( geometry instanceof THREE.BufferGeometry ) {
initDirectBuffers( geometry );
}
geometry.verticesNeedUpdate = true;
geometry.colorsNeedUpdate = true;
} }
...@@ -4373,20 +4418,35 @@ THREE.WebGLRenderer = function ( parameters ) { ...@@ -4373,20 +4418,35 @@ THREE.WebGLRenderer = function ( parameters ) {
} else if ( object instanceof THREE.ParticleSystem ) { } else if ( object instanceof THREE.ParticleSystem ) {
material = getBufferMaterial( object, geometryGroup ); if ( geometry instanceof THREE.BufferGeometry ) {
customAttributesDirty = material.attributes && areCustomAttributesDirty( material ); if ( geometry.verticesNeedUpdate || geometry.colorsNeedUpdate ) {
if ( geometry.verticesNeedUpdate || geometry.colorsNeedUpdate || object.sortParticles || customAttributesDirty ) { setDirectBuffers( geometry, _gl.DYNAMIC_DRAW, !geometry.dynamic );
setParticleBuffers( geometry, _gl.DYNAMIC_DRAW, object ); }
} geometry.verticesNeedUpdate = false;
geometry.colorsNeedUpdate = false;
geometry.verticesNeedUpdate = false; } else {
geometry.colorsNeedUpdate = false;
material.attributes && clearCustomAttributes( material ); material = getBufferMaterial( object, geometryGroup );
customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
if ( geometry.verticesNeedUpdate || geometry.colorsNeedUpdate || object.sortParticles || customAttributesDirty ) {
setParticleBuffers( geometry, _gl.DYNAMIC_DRAW, object );
}
geometry.verticesNeedUpdate = false;
geometry.colorsNeedUpdate = false;
material.attributes && clearCustomAttributes( material );
}
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册