一些有WebGL体验的页面,浏览者有种在一个带有材质的隧道中穿梭的感受。这有赖于Three.js以及由fornasetti.com带来的灵感。
例子地址 下载资源
WebGL变得原来越流行,我们可以看到一些列的网站使用WebGL来达到惊艳且具创造力的效果。 Fornasetti 近期发布了一个网站,其中借助WebGL达到了极好的效果:让我们身临穿梭于带有不断变换背景的隧道之中的运动。最有趣的莫过于可以通过鼠标控制我们穿梭的方向。本文将分享一些类似的Three.js管道运动。 注意: 你的浏览器需要支持WebGL(> IE10)以便可以浏览这些例子。
Fornasetti的网站截图
起步
在例子中我们会使用Three.js这个常用的库,来使构建WebGL效果更为便捷。在生成隧道前,我们先需要创建渲染器(renderer),场景(scene)以及相机(camera)。
当你对于使用Three.js不是那么顺畅,我建议你先阅读一些入门课程。这里提供一个Rachel Smith写的三部分的入门课程。
一旦创建好了场景(scene)我们就可以继续下面的流程:
- 创建一条曲线来确定隧道的形状
- 生成基于曲线的隧道
- 向前移动
- 增添交互
曲线
有赖于Three.js,我们有好用的函数用来基于一组点去创建曲线。我们首先需要计算这些点的位置,一旦完成这一步骤,我们可以用如下方法创建曲线:
// 穿建空数组来储存点 var points = [];
// 点沿z轴方向定义
for (var i = 0; i < 5; i += 1) {
points.push(new THREE.Vector3(0, 0, 2.5 * (i / 4)));
}
// 创建基于点的曲线
var curve = new THREE.CatmullRomCurve3(points)
在实际过程中,我们会改变曲线来保证管道形状变化。如你所见,所有的点都有相同的x,y值。目前,这条曲线还只是简单的直线。
隧道
现在我们有了一条曲线(一点也不弯),我们可以使用Three.js来创建一个隧道。为此我们需要:何体模型(用来描述管道的形状),材质(用来展示管道的视觉效果)以及最终的将几何体与材质结合成网格(mesh)。
// 基于曲线创建一个隧道几何模型
// 每个值的含义:
// 70 : 隧道模型的轴向片段数
// 0.02 : 曲率(虽然是个小隧道)
// 50 : 隧道模型径向片段数
// false : 用来决定隧道模型是否闭合
var tubeGeometry = new THREE.TubeGeometry(this.curve, 70, 0.02, 50, false);// 用一张纹理贴图而非单一的颜色来作为隧道呈现的材质
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);// 基于tubeGeometry与tubeMaterial创建网格(mesh)
var tube = new THREE.Mesh(tubeGeometry, tubeMaterial);
// 将隧道添加进场景(sence)
scene.add(this.tubeMesh);
向前移动
由于运动的原理并非我最初所想,这震撼到了我,因此这是我最喜欢的部分。我最初认为隧道实际上沿相机的方向运动,之后我觉得因该让相机移动进隧道中。但这两种想法都是错误的。
实际的解决方案非常巧妙: 场景中没有任何物体发生了实际的运动,发生的仅仅只是隧道贴图位置的移动.
为此,我们需要对每一帧的贴图都定义一个偏移量从而实现视觉上的运动。
function updateMaterialOffset() {
// 以定义的速度来更新材质的偏移量
tubeMaterial.map.offset.x += speed;
};
用户交互
没有用户交互的例子不是好例子。当你的鼠标在浏览器上移动的时候,你可以控制隧道的形状。这里的小技巧去更新我们在第一个步骤中创建的曲线。一旦曲线改变了,我们便可以借由一些过渡来更新隧道。
// 更新第三个的在x轴及y轴上的位置
curve.points[2].x = -mouse.position.x * 0.1;
curve.points[2].y = mouse.position.y * 0.1;
// 更新最后一个点的x轴位置
curve.points[4].x = -mouse.position.x * 0.1;
万事大吉?
其实并没有,实际的代码会比文章中提到的更复杂一点。但是如果你理解了以上的步骤,那么对例子是如何运作的原理会有大致的认识。如果你希望更深入地理解,查看第一个例子的源码。我已收到大量的评论。如果你依然有困惑,不要犹豫来Twitter上找我吧。
例子
一旦你有了基础的隧道模型,你可以不同的方向来改造它。浏览一下例子可以给你一些启发!
上文中介绍过的砖块图案。
点击你的鼠标或者是点按屏幕来释放粒子彩虹!
这个例子灵感来源于科幻电影的时空穿梭。
进入你的身体,观察一下血管吧:)
为何所有的隧道都是圆的?是时候让我们穿梭在三角形的隧道中了。
在手机或平板上尝试这个例子,并通过设备朝向来控制方向!