three.js粒子过度效果制作(二)

版权声明:本文为作者的原创文章,未经允许不得转载。 https://blog.csdn.net/lin5165352/article/details/83897238

three.js粒子过度效果制作(二)

从图片获取粒子

下面演示的是粒子是从图片中获取的。采用的cpu的方式,普通geometry,单一颜色。
你也可以使用彩色图片,并使用彩色粒子,效果会更好一些。
在这里插入图片描述
步骤

  1. 创建meshGeo,这个是粒子系统的载体,,它的顶点数量决定了整个粒子的数量,这里球体(1,160,160)=25442个顶点。所以从两幅图像中离子化的顶点数量要小于该值,如果大于,就会显示不完整,需要调整参数。
  2. 创建粒子材质,采用的统一材质。所以粒子颜色一致。
  3. 读取图像A,如果粒子数量小于预计值,就重复赋值。直到相等。
  4. 读取图像B,如果粒子数量小于预计值,就重复赋值。直到相等。
  5. 创建tween动画。
var meshGeo = new THREE.SphereGeometry(1, 160, 160).translate(0,0,0);
var meshP = [];
meshGeo.vertices.forEach(function (p,i) {
    meshP.push(p.clone());
});
var pointMaterial = new THREE.PointsMaterial({
    size: 1,
    color: 0x5899ef,
    map: new THREE.TextureLoader().load("../img/disc.png"),
    side: THREE.DoubleSide,
    alphaTest: 0.5,
    transparent: true,
});
var mesh = new THREE.Points(meshGeo, pointMaterial);
mesh.rotation.x = -Math.PI/2;

var spherePa = imgTodata('../img/map0.png',function (){
    if(spherePa.length < meshP.length ){
        var k = meshP.length - spherePa.length;
        for(var i =0;i< k;i++){
            spherePa.push(spherePa[i]);
        }else {
            alert('图片粒子化数据太大,请修改图片取样因子或meshGeo参数');
        }
    }
});
var spherePb = imgTodata('../img/map_inverteb.png',function () {
    if(spherePb.length < meshP.length){
        var k = meshP.length - spherePb.length;
        for(var i =0;i< k;i++){
            spherePb.push(spherePb[i]);
        }else {
            alert('图片粒子化数据太大,请修改图片取样因子或meshGeo参数');
        }
    }
});

var pos = {val: 1};
var tween = new TWEEN.Tween(pos).to({val: 0}, 2000).easing(TWEEN.Easing.Quadratic.InOut).delay(1000).onUpdate(callback);
var tweenBack = new TWEEN.Tween(pos).to({val: 1}, 2000).easing(TWEEN.Easing.Quadratic.InOut).delay(1000).onUpdate(callback);
tween.chain(tweenBack);
tweenBack.chain(tween);
tween.start();
function callback() {
    var val = this.val;
    for (var i = 0; i < mesh.geometry.vertices.length; i++) {
        var pos = {};
        pos.x = spherePa[i].x * val + spherePb[i].x * (1 - val);
        pos.y = spherePa[i].y * val + spherePb[i].y * (1 - val);
        pos.z = spherePa[i].z * val + spherePb[i].z * (1 - val);
        mesh.geometry.vertices[i].set(pos.x, pos.y, pos.z);
    }
    mesh.geometry.verticesNeedUpdate = true;
}
scene.add(mesh);

图片离子化程序,采用黑白二值化的图像,获取黑色的部分坐标。有取样因子,和坐标缩放因子。可以根据需要调整,默认4,10。

function imgTodata(src,callback) {
    var imgData = [];
    var image = new Image;
    image.src = src;
    image.onload = function () {
        var canvas = document.createElement("canvas");
        canvas.width = image.width;
        canvas.height = image.height;
        var context = canvas.getContext("2d");
        context.drawImage(image, 0, 0, image.width, image.height);
        var data = context.getImageData(0, 0, canvas.width, canvas.height);
        var dLength = data.data.length;
        for (var i = 0; i < dLength; i += 4) {
            var xyz = {};
            var x = (i / 4) % canvas.width;
            var y = (i / 4 - x) / canvas.width;
            if (i / 4 % 4 === 1 && y % 2 === 1 && 0 === data.data[i]) {
                xyz.x = (x-image.width/2)/10;
                xyz.y = -(y-image.height/2)/10;
                xyz.z = 0;
                imgData.push(xyz);
            }
        }
        callback();
    };
    return imgData;
}

从外部模型获取粒子

loading……

猜你喜欢

转载自blog.csdn.net/lin5165352/article/details/83897238