效果图
three.js制作水管
创建纹理(texture)
// 初始化纹理材质
initTexture() {
// 引用资源 水管贴图
var tubeImg = require("图片路径");
// 加载器
var textureLoader = new THREE.TextureLoader();
this.textureTube = textureLoader.load(tubeImg);
// 设置阵列模式为 RepeatWrapping
// 纹理在水平方向上纹理包裹方式 在UV映射中对应于U
this.textureTube.wrapS = THREE.RepeatWrapping;
// 纹理贴图在垂直方向上的包裹方式 在UV映射中对应于V
this.textureTube.wrapT = THREE.RepeatWrapping;
// 用来设置纹理将在表面上,分别在U、V方向重复多少次。
this.textureTube.repeat.x = 100;
// 创建 material
this.tubeMaterialTube = new THREE.MeshPhongMaterial({
map: this.textureTube,
transparent: true,
color: 0x47d8fa,
side: THREE.DoubleSide,
opacity: 0.8,
});
},
创建水管路径
// 创建水管路径
createPath(pointsArr) {
// pointsArr是存放三维空间点的参数数组 如 pointsArr = [ [0, 0, 0], [100, 100, 100] ];
// 将参数数组转换成点数组的形式
newPointsArr = pointsArr.map((point) => new THREE.Vector3(...point));
// 自定义三维路径 curvePath
const path = new THREE.CurvePath();
for (let i = 0; i < newPointsArr.length - 1; i++) {
// 每两个点之间形成一条三维直线
const lineCurve = new THREE.LineCurve3(
newPointsArr[i],
newPointsArr[i + 1]
);
// curvePath有一个curves属性,里面存放组成该三维路径的各个子路径
path.curves.push(lineCurve);
}
return path;
},
创建水管
// 创建水管
initTube(pointsArr) {
var curve = this.createPath(pointsArr);
var tubeGeometry = new THREE.TubeGeometry(
curve, // path 一个由基类Curve继承而来的路径
1000, // tubularSegments — Integer - 组成这一管道的分段数,默认值为64
10, // radius — Float - 管道的半径,默认值为1
100, // radialSegments — Integer - 管道横截面的分段数目,默认值为8
false // closed — Boolean 管道的两端是否闭合,默认值为false。
);
// 设置数组材质对象作为网格模型材质参数
var mesh = new THREE.Mesh(
tubeGeometry,
this.tubeMaterial
);
//网格模型对象Mesh
mesh.position.y = 4;
mesh.rotateZ(3.14);
this.scene.add(mesh); //网格模型添加到场景中
},
水流效果
// 实时渲染
animate() {
// 不要同时使用 requestAnimationFrame()和controls.addEventListener('change', render)调用同一个函数,这样会冲突。
this.requestAnimationId = requestAnimationFrame(this.animate);
this.renderer.render(this.scene, this.camera);
this.textureTube.offset.x -= 0.01; // 每次渲染时,纹理贴图都在位移,实现水流效果
},