4.2 基本粒子效果Points
学习ThreeJS的捷径
本段内容会写在0篇以外所有的,本人所编写的Threejs教程中
对,学习ThreeJS有捷径
当你有哪个函数不懂的时候,第一时间去翻一翻文档
当你有哪个效果不会做的时候,第一时间去翻一翻所有的案例,也许就能找到你想要的效果
最重要的一点,就是,绝对不要怕问问题,越怕找找别人问题,你的问题就会被拖的越久
如果你确定要走WebGL/ThreeJS的开发者路线的话,以下行为可以让你更快的学习ThreeJS
- 没事就把所有的文档翻一遍,哪怕看不懂,也要留个印象,至少要知道Threejs有什么
- 没事多看看案例效果,当你记忆的案例效果足够多时,下次再遇到相似问题时,你就有可能第一时间来找对应的案例,能更快解决你自己的问题
- 上述案例不只是官网的案例,郭隆邦技术博客,跃焱邵隼,暮志未晚等站点均有不少优质案例,记得一并收藏
http://www.yanhuangxueyuan.com/ 郭隆邦技术博客
https://www.wellyyss.cn/ 跃焱邵隼
http://www.wjceo.com/ 暮志未晚
这三个站点是我最常逛的站点,推荐各位有事没事逛一下,看看他们的案例和写法思路,绝对没坏处
Points简介
points,点(复数),简单说就是一堆顶点
从官方文档中,我们不难看出,创建points和创建mesh基本上是同一个流程,唯二的区别,就是,我们这次创建的是Points,使用的材质是PointsMaterial
PointsMaterial
poitnsMaterial也是非常的简单
这里唯二值得注意的属性,一个是size,一个是sizeAttenuation
sizeAttenuation : 由于Points是一个2D的元素,所以它和sprite一样有一个深度衰减的属性,随着近大远小是否会改变大小
size:点的大小,在下面实际使用时会详细介绍
创建Points
使用的图片路径为 three.js-master\examples\textures\sprites
使用的文件为 snowflake1.png,snowflake2.png 。。。 等五张png图片
使用规则几何体创建Points
function addMesh(){
let texture = new THREE.TextureLoader().load('./snowflake1.png');
let geometry = new THREE.BoxGeometry(5,5,5,3,3,3);
let material = new THREE.PointsMaterial({
map:texture
});
let points = new THREE.Points(geometry,material);
scene.add(points);
}
其实这段代码,你把材质换成StandardMaterial,把points换成Mesh,也能用
但是我们发现,图片有明显的黑边,我们处理一下
renderer = new THREE.WebGLRenderer({
antialias:true
});
//关于blending(混合)的说明
//由于它本身的图片是带有黑色背景的,所以我们要用混合来解决黑色背景png的问题
//正常情况下,我们只需要使用带有透明通道的png,然后开启transparent即可
let material = new THREE.PointsMaterial({
map:texture,
blending: THREE.AdditiveBlending,
depthTest: false,
transparent: true
});
但是一般的雪花不是这么规则的,我们该怎么创建呢?还记得之前学过的创建BufferGeometry吗
使用BufferGeometry创建Points
function addMesh(){
let texture = new THREE.TextureLoader().load('./snowflake1.png');
let geometry = new THREE.BufferGeometry();
let vertices = [];
for(let i = 0;i< 100;i++){
//创建随机顶点
let x = Math.random() * 10 - 5;
let y = Math.random() * 10 - 5;
let z = Math.random() * 10 - 5;
vertices.push(x,y,z);
}
//向bufferGeometry添加position的数据
geometry.setAttribute('position',new THREE.Float32BufferAttribute(vertices,3))
let material = new THREE.PointsMaterial({
map:texture,
blending: THREE.AdditiveBlending,
depthTest: false,
transparent: true
});
let points = new THREE.Points(geometry,material);
scene.add(points);
}
这样我们的随机雪花的场景就出来了
调整并锁定Points大小
function addMesh(){
let texture = new THREE.TextureLoader().load('./snowflake1.png');
let geometry = new THREE.BufferGeometry();
let vertices = [];
for(let i = 0;i< 100;i++){
//创建随机顶点
let x = Math.random() * 10 - 5;
let y = Math.random() * 10 - 5;
let z = Math.random() * 10 - 5;
vertices.push(x,y,z);
}
//向bufferGeometry添加position的数据
geometry.setAttribute('position',new THREE.Float32BufferAttribute(vertices,3))
let material = new THREE.PointsMaterial({
map:texture,
blending: THREE.AdditiveBlending,
depthTest: false,
transparent: true,
size:15, //调整粒子大小,由于设置了不随近大远小衰减,原图又很小,所以需要一个很大的size才能看到粒子
sizeAttenuation:false//设置不随近大远小衰减
});
let points = new THREE.Points(geometry,material);
scene.add(points);
}
让Points动起来(选学)
若你在之前没有看过animejs的使用教学,请点击这里,否则接下来的代码你将很难看懂
【Animejs教程】一个绝赞易用的动画库 Animejs,一个绝好的threejs动画辅助库
anime({
targets:points.position,
y:[5,-5],
duration:3000,
easing:"linear",
loop:true,
})
哎呀,这个效果和雪花差距可太大了,怎么办?
不急,我们先封装一下创建雪花的过程
function createSnow(texturePath,count,seek) {
let texture = new THREE.TextureLoader().load(texturePath);
let geometry = new THREE.BufferGeometry();
let vertices = [];
for(let i = 0;i< count;i++){
//创建随机顶点
let x = Math.random() * 10 - 5;
let y = Math.random() * 10 - 5;
let z = Math.random() * 10 - 5;
vertices.push(x,y,z);
}
//向bufferGeometry添加position的数据
geometry.setAttribute('position',new THREE.Float32BufferAttribute(vertices,3))
let material = new THREE.PointsMaterial({
map:texture,
blending: THREE.AdditiveBlending,
depthTest: false,
transparent: true,
size:0.4
});
let points = new THREE.Points(geometry,material);
scene.add(points);
let a = anime({
targets:points.position,
y:[5,-5],//让points.position的y值,从5变化到-5
duration:3000,//动画时间3秒
easing:"linear",//线性动画
loop:true,//动画无限循环
autoplay:false,//关闭自动播放动画
})
a.seek(seek);//改变动画的播放时间,从第几秒开始,用于做一个动画时间差
a.play();//改变了起始播放时间后再播放动画
}
然后紧接着,我们创建N组雪花
function addMesh(){
createSnow('./snowflake1.png',100,0);//第一组雪花从第0秒播放
createSnow('./snowflake2.png',100,500);//第二组雪花从0.5秒播放,做一个雪花的视差效果
createSnow('./snowflake3.png',100,1000);//第三组雪花从1秒播放,以下以此类推
createSnow('./snowflake4.png',100,1500);
createSnow('./snowflake5.png',100,2000);
}
你创建的雪花组数越多,就更难看出来动画的差距,同时也消耗更多的计算性能,粒子效果需根据实际情况来使用
结语
Points能做的粒子效果非常有限,好快的粒子效果基本上都要使用顶点着色器来编辑
但是基本上市面上好看的项目,都多少带一些粒子效果,当你不知道怎么做时,可以尝试一下像笔者上面这种利用视差效果的简单动态粒子效果
后续在讲解到顶点着色器的时候,还会继续讲解粒子效果的相关内容,敬请期待
关于Points,就介绍到这里了,下一篇我们会对线段进行介绍