three.js粒子過度效果製作(二)
阿新 • • 發佈:2018-11-16
three.js粒子過度效果製作(二)
從圖片獲取粒子
下面演示的是粒子是從圖片中獲取的。採用的cpu的方式,普通geometry,單一顏色。
你也可以使用彩色圖片,並使用彩色粒子,效果會更好一些。
步驟
- 建立meshGeo,這個是粒子系統的載體,,它的頂點數量決定了整個粒子的數量,這裡球體(1,160,160)=25442個頂點。所以從兩幅影象中離子化的頂點數量要小於該值,如果大於,就會顯示不完整,需要調整引數。
- 建立粒子材質,採用的統一材質。所以粒子顏色一致。
- 讀取影象A,如果粒子數量小於預計值,就重複賦值。直到相等。
- 讀取影象B,如果粒子數量小於預計值,就重複賦值。直到相等。
- 建立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……