首页 > 解决方案 > 将 THREE.js 几何转换为 BufferGeometry?

问题描述

我对 THREE.js 比较陌生,我得到了这段代码,但我想将这个 Geometry 重构为 BufferGeometry 以获得效率优势。我看到这个 (var bufferGeometry = new THREE.BufferGeometry().fromGeometry(geometry);) 作为一种可能的解决方案,但我无法实现它我确定这很简单我只是缺乏使用 THREE.js 的经验来识别这一点。

let rainGeo = new THREE.Geometry()

for (let i = 0; i < rainCount; i++) {
rainDrop = new THREE.Vector3(
    Math.random() * 120 - 60,
    Math.random() * 180 - 80,
    Math.random() * 130 - 60,
)

    rainDrop.velocity = {}
    rainDrop.velocity = 0
bufferGeometry.vertices.push(rainDrop)
}

rainMaterial = new THREE.PointsMaterial({
    color: '#ffffff',
    size: .3,
    transparent: true,
    map: THREE.ImageUtils.loadTexture(
        'images/snow_mask_2.png'),
    blending: THREE.AdditiveBlending,
})

rain = new THREE.Points(bufferGeometry, rainMaterial)
rain.rotation.x = -1.5707963267948963
rain.rotation.y = -3.22
scene.add(rain)

function rainVariation() {
    bufferGeometry.vertices.forEach(p => {
        p.velocity -= 0.1 + Math.random() * 0.1;
        p.y += p.velocity;

        if (p.y < -60) {
            p.y = 60;
            p.velocity = 0;
    }
});


    bufferGeometry.verticesNeedUpdate = true;
    rain.rotation.y += 0.008

}

标签: three.js

解决方案


以此移植代码为基础进行尝试。我建议您在单独的数组中管理每个雨滴的速度(因为这些数据在着色器中不是必需的)。

let camera, scene, renderer, rain;

const vertex = new THREE.Vector3();

init();
animate();

function init() {

    camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.1, 1000 );
    camera.position.z = 100;

    scene = new THREE.Scene();

    const geometry = new THREE.BufferGeometry();
    const vertices = [];

    for (let i = 0; i < 1000; i++) {
        vertices.push( 
		    Math.random() * 120 - 60,
		    Math.random() * 180 - 80,
		    Math.random() * 130 - 60
        );
    }
		
    geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) );

    const material = new THREE.PointsMaterial( { color: '#ffffff' } );

    rain = new THREE.Points( geometry, material );
    scene.add(rain);

    renderer = new THREE.WebGLRenderer( { antialias: true } );
    renderer.setSize( window.innerWidth, window.innerHeight );
    document.body.appendChild( renderer.domElement );

}

function rainVariation() {

    var positionAttribute = rain.geometry.getAttribute( 'position' );
	
    for ( var i = 0; i < positionAttribute.count; i ++ ) {
	
        vertex.fromBufferAttribute( positionAttribute, i );
		
        vertex.y -= 1;
		
        if (vertex.y < - 60) {
            vertex.y = 90;
        }
		
        positionAttribute.setXYZ( i, vertex.x, vertex.y, vertex.z );
	
    }

    positionAttribute.needsUpdate = true;

}

function animate() {

    requestAnimationFrame( animate );

    rainVariation();

    renderer.render( scene, camera );

}
body {
	  margin: 0;
}
canvas {
	display: block;
}
<script src="https://cdn.jsdelivr.net/npm/three@0.115/build/three.js"></script>


推荐阅读