使用Three.js的炫酷无限管道特效


由于WebGL越来越受欢迎,我们开始看到一大堆使用它的网站用于出色的创意设计。品牌Fornasetti最近使用WebGL的强大功能发布了他们的网站,效果非常好:让我们看起来像是在变化的模式中穿越隧道的动画这个经验中最有趣的部分是通过隧道的运动是由鼠标的移动来控制的。今天我们将和大家分享一些类似的Three.js动力隧道实验。

注意:您将需要支持WebGL(> IE10)的最新浏览器才能看到演示。

WX20171224-233003@2x.png

入门

对于这个演示,我们使用Three.js这是一个有用的库来创建WebGL,而不会弄脏你的手。在生成管之前,我们首先需要使用渲染器,相机和空场景来设置场景。

如果你觉得使用Three.js不太熟悉,我建议你先阅读一个教程来开始使用它。雷切尔·史密斯(Rachel Smith)在这里写了三篇好文章

一旦我们有了我们的场景,我们将继续这些步骤:

  1. 创建一个曲线来确定管的形状
  2. 基于曲线生成管
  3. 向前移动一切
  4. 添加一些用户交互

曲线

由于Three.js,我们有一个有用的功能,可以让我们创建一个基于一组点的曲线。我们首先需要计算这些点的位置。一旦完成,我们可以像这样创建我们的曲线:

// Create an empty array to stores the points
var points = [];

// Define points along Z axis
for (var i = 0; i < 5; i += 1) {
    points.push(new THREE.Vector3(0, 0, 2.5 * (i / 4)));
}

// Create a curve based on the points
var curve = new THREE.CatmullRomCurve3(points)

该曲线稍后将被更新以实时修改管的形状。正如你所看到的,所有的点都有相同的X和Y位置。此刻,曲线是一条直线。

管子

现在我们有一条曲线(根本不是曲线),我们可以使用Three.js创建一个管。要做到这一点,我们需要三个部分:一个几何体(管的形状),一个材料(如何看起来),最后是一个网格物体(几何体和材料的组合):

// Create the geometry of the tube based on the curve
// The other values are respectively : 
// 70 : the number of segments along the tube
// 0.02 : its radius (yeah it's a tiny tube)
// 50 : the number of segments that make up the cross-section
// false : a value to set if the tube is closed or not
var tubeGeometry = new THREE.TubeGeometry(this.curve, 70, 0.02, 50, false);

// Define a material for the tube with a jpg as texture instead of plain color
var tubeMaterial = new THREE.MeshStandardMaterial({
    side: THREE.BackSide, // Since the camera will be inside the tube we need to reverse the faces
    map: rockPattern // rockPattern is a texture previously loaded
});
// Repeat the pattern to prevent the texture being stretched
tubeMaterial.map.wrapS = THREE.RepeatWrapping;
tubeMaterial.map.wrapT = THREE.RepeatWrapping;
tubeMaterial.map.repeat.set(30, 6);

// Create a mesh based on tubeGeometry and tubeMaterial
var tube = new THREE.Mesh(tubeGeometry, tubeMaterial);

// Add the tube into the scene
scene.add(this.tubeMesh);

向前移动管子

这部分是我最喜欢的,因为让我吃惊的是动画并没有起作用,因为我最初相信。我首先想到的是管子实际上正在朝着相机的方向移动。然后,我建议摄像机在管内移动。但是这两个想法都是错的!

实际的解决方案是非常聪明的:没有任何东西在沿着管子翻译的纹理旁边的“物理”上前进

为此,我们需要在每个帧上定义纹理的偏移量,以创建运动幻觉

function updateMaterialOffset() {
  // Update the offset of the material with the defined speed
  tubeMaterial.map.offset.x += speed;
};

用户交互

如果我们没有实现一些用户交互,演示将不会那么好。在浏览器中移动鼠标时,可以控制管的形状。这里的技巧是更新我们在第一步创建的曲线的点。一旦曲线发生变化,我们可以通过一些转换来更新管道。

// Update the third point of the curve in X and Y axis
curve.points[2].x = -mouse.position.x * 0.1;
curve.points[2].y = mouse.position.y * 0.1;

// Update the X position of the last point
curve.points[4].x = -mouse.position.x * 0.1;

演示

一旦你有一个基本的管,你可以改进它有很多不同的选择。看看所有的演示给你一些想法!

InfiniteTubes_01.jpg 上面介绍的砖样式的演示。
infiniteTube2.jpg 按下你的鼠标(或触摸你的屏幕)释放一个新的粒子彩虹!
infiniteTube3.jpg 这个演示受到所有科幻电影的启发,具有一定的时间旅行效果。
infiniteTube4.jpg 潜入你的身体,探索血管:)
infiniteTube5.jpg 为什么所有的管子都是圆的?这一次,我们正在通过一个三角形旅行。
InfiniteTubes_06.jpg 在您的手机或平板电脑上试用这个演示,以设备方向控制管道!演示地址:http://www.9iweb.com.cn/effects/resource/effects_id/3376.html
下载地址:http://www.9iweb.com.cn/effects/3376.html
要在three.js中创建管道截面,可以使用THREE.TubeGeometry和THREE.PlaneGeometry。 首先,我们需要创建一个THREE.TubeGeometry对象,该对象需要以下参数: - path:管道路径,可以是一个THREE.Curve路径或一个THREE.SplineCurve3路径。 - radius:管道半径。 - segments:管道在周向上的分段数。 - radiusSegments:管道在径向上的分段数。 - closed:管道是否封闭。 接下来,我们需要创建一个THREE.PlaneGeometry对象,该对象需要以下参数: - width:平面的宽度。 - height:平面的高度。 - widthSegments:平面在水平方向上的分段数。 - heightSegments:平面在垂直方向上的分段数。 最后,我们需要使用THREE.ShapeGeometry将管道和平面组合在一起。 以下是一个示例代码,用于创建一个带有管道截面的THREE.Mesh对象: ``` // 创建管道路径 var path = new THREE.SplineCurve3([ new THREE.Vector3(0, 0, 0), new THREE.Vector3(0, 0, 10), new THREE.Vector3(10, 0, 10), new THREE.Vector3(10, 5, 10), new THREE.Vector3(20, 5, 0), new THREE.Vector3(20, 0, 0) ]); // 创建管道几何体 var tubeGeometry = new THREE.TubeGeometry(path, 64, 0.5, 32, true); // 创建平面几何体 var planeGeometry = new THREE.PlaneGeometry(20, 20, 32, 32); // 创建管道截面几何体 var shape = new THREE.Shape(); shape.moveTo(-10, -10); shape.lineTo(-10, 10); shape.lineTo(10, 10); shape.lineTo(10, -10); var hole = new THREE.Path(); hole.moveTo(-5, -5); hole.lineTo(-5, 5); hole.lineTo(5, 5); hole.lineTo(5, -5); shape.holes.push(hole); var shapeGeometry = new THREE.ShapeGeometry(shape); // 组合管道和平面 var tubeMesh = new THREE.Mesh(tubeGeometry, new THREE.MeshBasicMaterial({ color: 0xff0000 })); var planeMesh = new THREE.Mesh(planeGeometry, new THREE.MeshBasicMaterial({ color: 0x00ff00 })); var shapeMesh = new THREE.Mesh(shapeGeometry, new THREE.MeshBasicMaterial({ color: 0x0000ff })); // 将所有物体添加到场景中 scene.add(tubeMesh); scene.add(planeMesh); scene.add(shapeMesh); ``` 这将创建一个带有管道截面的场景,其中红色物体是管道,绿色物体是平面,蓝色物体是管道截面。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值