在three.js中改变单个精灵的颜色

Altering color of individual sprite in three.js

本文关键字:精灵 颜色 单个 改变 three js      更新时间:2023-09-26

我刚开始摆弄three.js,我在修改数组中单个精灵的颜色时遇到了一些麻烦。

我正在使用来自threejs.org的示例。

我试图修改每个精灵的颜色基于它的比例值。特别是,我在源文件的最后一个函数中添加了以下行:

            function render() {
            camera.position.x += ( mouseX - camera.position.x ) * .05;
            camera.position.y += ( - mouseY - camera.position.y ) * .05;
            camera.lookAt( scene.position );
            var i = 0;
            for ( var ix = 0; ix < AMOUNTX; ix ++ ) {
                for ( var iy = 0; iy < AMOUNTY; iy ++ ) {
                    particle = particles[ i++ ];
                    particle.position.y = ( Math.sin( ( ix + count ) * 0.3 ) * 50 ) +
                        ( Math.sin( ( iy + count ) * 0.5 ) * 50 );
                    particle.scale.x = particle.scale.y = ( Math.sin( ( ix + count ) * 0.3 ) + 1 ) * 4 +
                        ( Math.sin( ( iy + count ) * 0.5 ) + 1 ) * 4;
                    // Added this line in an attempt to change color based on scale //
                    particle.material.color.setHSL(particle.scale.x * .1, .2, .2);

                }
            }
            renderer.render( scene, camera );
            count += 0.1;
        }

然而,添加的线将每个粒子更改为相同的颜色值。我假设数组的每个元素都将在循环中被访问和修改,但事实似乎并非如此。

物质与所有粒子共享,

            var material = new THREE.SpriteCanvasMaterial( {
                color: 0xffffff,
                program: function ( context ) {
                    context.beginPath();
                    context.arc( 0, 0, 0.5, 0, PI2, true );
                    context.fill();
                }
            } );

将其移动到创建精灵粒子的循环上方,使它们各自获得单独的材料。

关于每个精灵都有自己的材料的答案让我找到了正确的方向。我将材质设置为一个数组,并在每个材质和精灵元素之间添加关联。

            var i = 0;
            var j = 0;
            for ( var ix = 0; ix < AMOUNTX; ix ++ ) {
                for ( var iy = 0; iy < AMOUNTY; iy ++ ) {
                    material[ j ] = new THREE.SpriteCanvasMaterial( {
                    vertexColors: THREE.VertexColors,
                    program: function ( context ) {
                        context.beginPath();
                        context.arc( 0, 0, 0.5, 0, PI2, true );
                        context.fill();
                     }
                    } );
                    particle = particles[ i ++ ] = new THREE.Sprite( material[ j ++ ] );
                    particle.position.x = ix * SEPARATION - ( ( AMOUNTX * SEPARATION ) / 2 );
                    particle.position.z = iy * SEPARATION - ( ( AMOUNTY * SEPARATION ) / 2 );
                    scene.add( particle );
                }
            }