HarmonyOS开发者限时福利来啦!最高10w+现金激励等你拿~ 了解详情
写点什么

基于 Threejs 的 web 3D 开发入门

  • 2019-08-21
  • 本文字数:3113 字

    阅读完需:约 10 分钟

基于Threejs的web 3D开发入门

随着软硬件的发展,在 PC 和移动端浏览器上进行 web 3D 开发的条件已经基本成熟了,出现了不少 js 3D 库,Threejs 是 js 3D 库中的佼佼者。国内也有企业开始做一些应用尝试,某宝 2016 年双 11 就用 ThreeJS 做了一个比较酷炫的 3D 宣传页面刷爆了朋友圈。


下图是用 Threejs 绘制的一个 3D 立方体动画的截图,在这个 demo 里,立方体会动态的旋转,threeJS 30 行代码就可以完成这么一个 demo。Threejs 让没有丰富 3D 编程经验的 web 前端开发人员,也可以快速上手开发 web 3D 应用。


Threejs 是什么

官网对 Threejs 的介绍非常简单:“Javascript 3D library”。openGL 是一个跨平台 3D/2D 的绘图标准,WebGL 则是 openGL 在浏览器上的一个实现。web 前端开发人员可以直接用 WebGL 接口进行编程,但 WebGL 只是非常基础的绘图 API,需要编程人员有很多的数学知识、绘图知识才能完成 3D 编程任务,而且代码量巨大。Threejs 对 WebGL 进行了封装,让前端开发人员在不需要掌握很多数学知识和绘图知识的情况下,也能够轻松进行 web 3D 开发,降低了门槛,同时大大提升了效率。

Threejs 应用场景举例

1、web 3D 游戏

2、3D 模型展示

下图的例子中,用户可以跟浏览器交互,通过鼠标操作 360 度查看汽车,点击车门进入到车内,查看车内立体视图,如同身临其境。


3、数据可视化

4、web vr

Threejs 的基本要素

3D 编程跟 2D 编程有较大不同,因此需要掌握一些 3D 编程的基本概念。Threejs 的基本要素包括以下几个方面:场景、相机、光、物体。


场景:是一个三维空间,所有物品的容器。可以把场景想象成一个空房间,接下来我们会往房间里面放要呈现的物体、相机、光源。



相机:Threejs 必须要有往场景中添加一个相机,相机用来确定观察位置、方向、角度,相机看到的内容,就是我们最终在屏幕上看到的内容。在程序运行过程中,可以调整相机的位置、方向、角度。想象一下,在房间里放了一个摄像机,你不在房间里面,但可以远程控制相机移动,摄像机传给远程电脑上展示出来的画面,就是 Threejs 在屏幕上呈现的画面。


光:假如没有光,摄像机看不到任何东西,因此需要往场景中添加光源。为了跟真实世界更加接近,Threejs 支持模拟不同光源,展现不同光照效果,有点光源、平行光、聚光灯、环境光等。


物体:有了场景、相机、光,就可以往场景中放物体了,在 Threejs 中,物体由形状和材质两部分组成,形状决定物品的轮廓,材质则是物体的材料和质感。

渲染

Threejs 绘制的东西,最终需要在屏幕一块矩形画布上显示出来。为了实现动画效果,我们需要有一个重绘机制。由于视神经元的反应速度问题,图像消失后仍然会在人眼残留 1/24 秒,只要一秒内绘制的帧数超过 24 就能实现流畅的动画效果。Threejs 提供了重绘接口,我们有两种方式去调用接口实现重绘。一种是 setInterval,以固定的时间间隔去调用,可以用于我们对渲染帧数要求比较高的场景,但事实上由于 Javascript 是单线程的,这种方式并不能 100%保证相同的时间间隔调用,如果浏览器繁忙可能会导致 setInterval 的延迟执行;第二种方式是 requestAnimationFrame,让浏览器自行根据当前 cpu 负载等情况决定何时重绘,达到最佳帧率。

位置

为了方便描述位置,引入了坐标系,Threejs 使用的是右手坐标系,如下图所示。坐标系的原点位于渲染画布的几何中心。我们对物体的位置的描述,也是指物体的几何中心的位置。


相机

相机有正交投影相机和透视投影相机两种。透视投影跟人眼看到的世界是一样的,近大远小;正交投影则远近都是一样的大小,三维空间中平行的线,投影到二维空间也一定是平行的。大部分场景都适合使用透视投影相机,因为跟真实世界的观测效果一样;在制图、建模等场景适合使用正交投影相机,方便观察模型之间的大小比例。


Threejs 中的相机跟真实世界的相机不完全一样,这里相机的可见区域是一个立方体,称为相机的示景体。

正交投影相机

示景体是一个长方体,由 6 个参数确定:THREE.OrthographicCamera(left, right, top, bottom, near, far),这 6 个参数规定了相机示景体的左、右、上、下、前、后六个面的位置。


透视投影相机

示景体是一个梯形体,由四个参数确定:THREE.PerspectiveCamera(fov, aspect, near, far)



fov 是相机在竖直方向的张角,aspect 则是宽高比,即 width/height,通常设为画布的宽高比,near 和 far 分别是近平面和远平面与相机的距离。

投影的大小

考虑一种比较简单的场景,相机示景体的远近平面和坐标系中的 xy 平面平行,从而示景体远近平面上的内容刚好可以垂直投影到画布上,并且示景体中与 xy 平面平行的任何一个平面,投影到画布上刚好等于画布大小。假如透视投影相机的近平面的大小为 axb,远平面大小为 2ax2b,则一张 axb 大小的纸放在近平面上,投影到画布时刚好铺满整张画布;放到远平面上则只能占据画布面积的 1/4(远平面的面积是近平面的 4 倍)。正是因为透视投影相机的示景体近小远大,才会导致同样一个物品放在不同位置显示出近大远小的效果。而正交投影相机因为远近平面大小一样,所以同一个物品距离相机的远近不影响物体在画布上投影展示的大小。

物体

物体由几何形状(Geometry)和材质(Material)组成。同样的几何形状,不同材质构成了不同物体,比如球状,有篮球、玻璃球、水晶球等。

形状

Threejs 提供了一些常见的几何形状,有三维的也有二维的,三维的比如长方体、球体、圆柱体、环等,二维的比如长方形、圆形、扇形等。如果默认提供的形状不能满足需求,也可以自定义,通过定义顶点和顶点之间的连线绘制自定义几何形状,更复杂的模型还可以用建模软件建模后导入。


计算机是如何绘制几何形状的呢?我们知道,计算机只能绘制直线,那么曲线和 3D 形状如何绘制出来呢?


1、绘制圆形。如下图所示,通过绘制多边形实现近似的圆形效果,当多边形的边数足够多的时候,两条边之间的过渡就显得平滑,多边形看起来就足够圆了。



2、绘制 3D 模型。常用的做法是用三角形组成的网格来模拟,如下图所示,用足够多的三角形时,兔子的身体看起来就足够平滑,跟真实兔子比较接近。著名的斯坦福兔子模型用了 69451 个三角形。


材质

Threejs 提供了几种比较有代表性的材质,常用的有漫反射、镜面反射两种材质,还可以引入外部图片,贴到物体表面,称为纹理贴图。

外部模型

现实世界丰富多彩,不是 Threejs 的几种默认几何形状和材质所能表达的,实际运用中,很多时候需要用到外部模型,通过 3D 建模软件构建物体的三维模型并导出模型文件,Threejs 导入模型文件进行使用。


光照

光源主要是以下几种:1)环境光,所有角度看到的亮度一样,通常用来为整个场景指定一个基础亮度,没有明确光源位置;2)点光源,一个点发出的光源,照到不同物体表面的亮度线性递减;3)平行光,亮度与光源和物体之间的距离无关,只与平行光的角度和物体所在平面有关;4)聚光灯,投射出的是类似圆锥形的光线。

小结

本文对 Threejs 编程做了一下简单介绍,目的是让读者对 Threejs 编程有个基本认识。纸上得来终觉浅,绝知此事要躬行!建议到 Threejs 官网首页看看那些有趣的 demo,着手写一些简单的 demo 进行实践。目前 web 3D 应用因为浏览器渲染性能、模型体积过大等原因,并没有大规模使用起来,只限于在品牌宣传等部分领域尝试使用。我刚好经历过浏览器 2D 数据可视化绘图由 flash 向 JS 转变的过程(2012 年前后),相信随着软硬件性能的提升和网络速度的提升,web 3D 应用也会慢慢的推广使用起来。


作者介绍:


朱海洋,高级工程师,增值产品部 QQ 会员营收团队负责人,目前团队负责 QQ 会员、靓号、SVIP+、大王超会等项目,有丰富的 Web 前端架构经验。


本文转载自公众号小时光茶舍(ID:gh_7322a0f167b5)。


原文链接:


https://mp.weixin.qq.com/s/-8DtRxuFYpH1gKezVlhjDw


2019-08-21 10:3210022

评论

发布
暂无评论
发现更多内容

今天社区团购了吗?

lenka

5月日更

架构营作业-模块4

大师兄

设计千万级学生管理系统的考试试卷存储方案

thewangzl

你真的会用ABAP, Java和JavaScript里的constructor么?

汪子熙

JavaScript CRM SAP abap

如何计算并测量ABAP及Java代码的环复杂度Cyclomatic complexity

汪子熙

Java SAP abap

如何查看某个用户指定时间段的ABAP开发记录

汪子熙

SAP abap SAPGUI

架构训练营模块四作业

Neil43

架构训练营

SAP UI5, CRM, S/4HANA 和 C4C里的Association, Composition and Aggregation

汪子熙

JavaScript CRM SAP SAP UI5

思考题太难了

Nydia

架构实战营模块四作业

冷大大

作业 架构实战营 模块四

SAP UI5和CRM WebUI的View和Controller是如何绑定的

汪子熙

CRM SAP abap WebClient UI SAP UI5

作业 - 设计千万级学生管理系统的考试试卷存储方案

sN0wpeak

架构实战营

千万级学生管理系统的考试试卷存储方案

王瑞强

架构实战营

S4CRM和C4C的技术比较

汪子熙

CRM SAP ERP abap Cloud for Customer

ABAP的include关键字,Java的import, C的include和C4C ABSL 的import比较

汪子熙

JavaScript nodejs CRM SAP C4C

使用ABAP Push Channel(APC)开发的乒乓球游戏,可双打

汪子熙

SAP abap APC

千万级学生管理系统的考试试卷存储方案

Lane

如何实现一个简易版的 Spring - 如何实现 AOP(上)

mghio

Java 技术 后端 基础知识 spring aop

架构实战营 模块4 作业

CR

架构实战营 模块四作业

Dylan

架构实战营

mongodb 修改字段类型

xiaolu

mongodb

sap.ui.require in SAP UI5 and require in nodejs

汪子熙

nodejs SAP SAP UI5

过拟合 - DAY13

Qien Z.

5月日更 过拟合

架构实战营模块 4 作业

梦寻解语花

架构实战营

身份认证

escray

学习 极客时间 安全 5月日更 安全攻防技能30讲

Dubbo 令牌验证和优雅停机

青年IT男

dubbo

第四课作业

杰语

华仔架构训练营作业(模块四)

不听不听王八念晶

S4HANA和CRM Fiori应用的搜索分页实现

汪子熙

CRM SAP Fiori SAP UI5 S/4HANA

架构实战营 模块四作业

夏日

架构实战营

架构师训练营模块4作业

歲月鎏金😈

基于Threejs的web 3D开发入门_大前端_朱海洋_InfoQ精选文章