three.js入门

安装

1
npm install three

渐变色

改一下颜色和高度

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
let c = new THREE.Color('#09e7ea');
const material = new THREE.ShaderMaterial({
uniforms: {
targetColor:{value:new THREE.Vector3(c.r,c.g,c.b)},
height: { value: 10},
},
side: THREE.DoubleSide,
transparent:true,
//depthTest:false,
depthWrite:false,
vertexShader: [
"varying vec3 modelPos;",
"void main() {",
" modelPos = position;",
" gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
"}"
].join("\n"),
fragmentShader: [
"uniform vec3 targetColor;",
"uniform float height;",
"varying vec3 modelPos;",

"void main() {",
" gl_FragColor = vec4(targetColor.xyz,(1.0 - modelPos.y/height)*(1.0 - modelPos.y/height));",
"}"
].join("\n")
});

边缘

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 椭圆
const ellipseShape = new THREE.Shape();
ellipseShape.absellipse(0, cardProps.value.height / -2, cardProps.value.width / 2, cardProps.value.height / 4, 0, Math.PI * 2, false, 0);
const ellipseGeometry = new THREE.ShapeGeometry(ellipseShape);
const ellipseMaterial = new THREE.MeshBasicMaterial({
color: '#22e3e3',
transparent: true,
opacity: 0.3,
depthTest: false,
});
// 边
const ellipseEdgeGeometry = new THREE.EdgesGeometry(ellipseGeometry);
const ellipseEdgeMaterial = new THREE.LineBasicMaterial({
color: '#22e3e3',

});
const ellipse = new THREE.Mesh(ellipseGeometry, ellipseMaterial);
const ellipseEdge = new THREE.LineSegments(ellipseEdgeGeometry, ellipseEdgeMaterial);
imagePlane.add(ellipse, ellipseEdge);

问题

重叠闪烁

深度测试(depthTest)

  1. 当启用深度测试时(默认启用)渲染器会根据像素深度渲染像素
  2. 深度相同时不到渲谁
  3. 闪烁开始。。
  4. 关闭深度测试
  5. 重贴像素一起计算像素值(会变色)
1
2
3
4
5
6
7
8
9
const iconGeometry = new THREE.PlaneGeometry(1, 1);
const iconMaterial = new THREE.MeshBasicMaterial({
map: textureLoader.load(images[i]),
transparent: true,
opacity: 1,
side: THREE.TwoPassDoubleSide,
depthTest: false, // 关闭深度测试解决重叠闪烁
});
const iconMesh = new THREE.Mesh(iconGeometry, iconMaterial);

组内坐标是相对坐标

1
2
3
4
// 原
item.position.distanceTo(camera.position)
// 改成
item.localToWorld(new THREE.Vector3(0, 0, 0)).distanceTo(camera.position)

字体居中

1
2
3
4
5
6
7
8
9
10
11
12
13
const fontLoader = new FontLoader();
fontLoader.load('font/gentilis_regular.typeface.json', font => {
const textGeometry = new TextGeometry('114514', {
font: font,
height: cardProps.value.height / 3 * 0.05,
size: cardProps.value.width / 2 * 0.5,
});
textGeometry.center(); // 字体居中
const textMaterial = new THREE.MeshBasicMaterial({color: 0xffffff});
const textMesh = new THREE.Mesh(textGeometry, textMaterial);
textMesh.position.set(cardProps.value.width / -2, cardProps.value.height / 3 * -1.75, 0.0);
imagePlane.add(textMesh);
});