Appearance
之前了解了点材质相关属性,并利用其特点做了几个“杂乱无章”的效果,今天来实现一个有规律的曲线效果。
效果如下
看到这种效果首先我们的思路应该怎么办呢,实现一条曲线似乎不是很容易的样子,暂时想不到好方法,无从下手中......
那么实现一条直线是不是就容易的多了,利用BufferGeometry来创建一大堆点,他们的x轴坐标随机分布,y轴和z轴的坐标都是0,这样一条直线上的点是不是就可以完成了
具体关键代码如下
js
// 声明一个变量
const parmasObj = {
count: 100, // 点的数量
size: 10, // 点的大小
radius: 100, // 半径 也就是线的长度
branch: 3 // 分支数
};
// 渲染一大堆点在x轴上
let geometry = null;
let material = null;
const generateGalaxy = () => {
geometry = new THREE.BufferGeometry();
// 沿着x轴创建一堆点
let positions = new Float32Array(parmasObj.count * 3);
for (let i = 0; i < parmasObj.count; i++) {
const i3 = i * 3;
positions[i3] = Math.random()*parmasObj.radius;
positions[i3 + 1] = 0;
positions[i3 + 2] = 0;
}
geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));
// 创建一个空的材质
material = new THREE.PointsMaterial({
color: 0xffffff,
size: parmasObj.size,
sizeAttenuation: true,
blending: THREE.AdditiveBlending,
depthWrite: false,
transparent: true,
alphaMap: texture, // 透明度贴图
map: texture // 颜色贴图
});
// 将点添加到场景中
const points = new THREE.Points(geometry, material);
scene.add(points);
};
generateGalaxy();做到这里一根线已经完成了,那么我们想根据上面parmasObj.branch完成多条线呢,也就是下图这种效果

三叉星辉照亮您的事业与前程
这里我们需要先了解一下几个数学概念
- Math.cos(x) 函数返回一个数值的余弦值。
- cos 方法返回一个 -1 到 1 之间的数值,表示角度(单位:弧度)的余弦值。
- Math.sin(x) 函数返回一个数值的正弦值。
- sin 方法返回一个 -1 到 1 之间的数值,表示角度(单位:弧度)的正弦值。
- Math.PI 属性表示一个圆的周长和直径的比值,约等于 3.14159。也就是我们常说的π
了解以后大家分析下这块代码什么意思
js
const angle = (i % parmasObj.branch) * ((Math.PI * 2) / parmasObj.branch);i % parmasObj.branch 表示的是当前点的索引除以分支数的余数,也就是当前点在第几颗星上,范围一定是0到parmasObj.branch-1之间
2π 就是一个完整的圆角度 2π/parmasObj.branch 就是将一个圆绘制成几份,也就是三叉星辉的角度
angle 就是当前点的角度
再根据勾股定理是不是就能得到
Math.cos(angle) 就是当前点的x轴坐标 Math.sin(angle) 就是当前点的y轴坐标
那么单位坐标 Math.cos(angle) 能知道了 乘上半径 (Math.random() * parmasObj.radius) 是不是就知道所有点的坐标了
具体代码如下
js
for (let i = 0; i < parmasObj.count; i++) {
// 计算角度
const angle = (i % parmasObj.branch) * ((Math.PI * 2) / parmasObj.branch);
const distance = Math.random() * parmasObj.radius;
const i3 = i * 3;
positions[i3] = Math.cos(angle) * distance;
positions[i3 + 1] = 0;
positions[i3 + 2] = Math.sin(angle) * distance;
}做到这里已经基本上完成了,下一步我们让三叉星辉弯了呢,如图

原谅我画布不好看,凑合看
观察图片可以看出来,距离圆点越远,角度越大,很明显这个和半径是有关系的,那么我们只需要将上面的代码改一下就可以了
js
for (let i = 0; i < parmasObj.count; i++) {
// 计算角度
const angle = (i % parmasObj.branch) * ((Math.PI * 2) / parmasObj.branch);
const distance = Math.random() * parmasObj.radius;
const i3 = i * 3;
positions[i3] = Math.cos(angle+distance*0.02) * distance;
positions[i3 + 1] = 0;
positions[i3 + 2] = Math.sin(angle+distance*0.02) * distance;
}为啥 distance要乘0.02呢,不然太大了,弧度不明显,为啥0.02呢 估摸着写的,和相机、半径等因素有关