NVIDIA 初创加速计划,免费加速您的创业启动 了解详情
写点什么

基于 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:329796

评论

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

函数递归习题(easy版)

芒果酱

c++ C语言 7月月更

发现增长新动力,企业到底需要一朵什么样的云?

ToB行业头条

如何在Docker部署安装ETL调度运维工具TASKCTL

TASKCTL

DevOps 大数据运维 Kafka ETL TASKCTL Docker 镜像

实操演示:如何用 ONES 制定 Scrum 迭代计划?

万事ONES

小李:“有没有特别简单的Python解密rsa的案例?”“还真有”

梦想橡皮擦

Python 爬虫 7月月更

LabView实验——温度检测系统(实验学习版)

一碗黄豆酱

LabView---信号发生器

一碗黄豆酱

服务器运维需要24小时在线吗?需要周末加班吗?

行云管家

服务器 IT运维

数据仓库开发 SQL 使用技巧总结

C++后台开发

MySQL 数据库 sql 中间件 后端开发

低代码软件开发平台怎么选?

优秀

低代码开发 低代码平台

LabView中禁用模块(属性节点)

一碗黄豆酱

Ampere Altra Max 提供可持续的高分辨率 H.265 编码

亚马逊云科技 (Amazon Web Services)

编码 Tech 专栏

如何选择合适的体育场馆用LED显示屏

Dylan

LED显示屏 户外LED显示屏 led显示屏厂家

Python图像处理丨三种实现图像形态学转化运算模式

华为云开发者联盟

Python 人工智能 AI 图像形态学

2022年中国娱乐直播市场年度综合分析

易观分析

直播市场

ABAP-EXCEL上传下载

桥下本有油菜花

abap ABAPexcel

百度APP Android包体积优化实践(一)总览

百度Geek说

Java 安卓

直播预告 | 多云时代如何建设企业云管理平台?

BoCloud博云

cmp 云管理平台 云管理

一文了解 Nebula Graph 上的 Spark 项目

NebulaGraph

spark 图数据库 知识图谱 NebulaGraph

IT小白也能轻松get日志服务---使用Nginx模式采集日志

云端explorer

nginx 运维 日志服务

React原理学习路线

郭明

李宏毅《机器学习》丨3. Gradient Descent(梯度下降)

AXYZdong

机器学习 7月月更

云图说丨数字资产链:您的数字资产产权保护神

华为云开发者联盟

区块链 云计算 开发 开发工具

可以 DIY 装修的商城系统,你也能拥有!

CRMEB

消息中间件

Damon

7月月更

如何做好安全开发?

华为云开发者联盟

云计算 开源 安全 开发

SDL文字显示

柒号华仔

7月月更

医院怎么实现高效低成本运维?有什么软件可以满足吗?

行云管家

运维 IT运维 医院运维

京东云联合Forrester咨询发布混合云报告 云原生成为驱动产业发展新引擎

京东科技开发者

云原生 数字化 科技 混合云 多云

短视频直播系统源码

开源直播系统源码

短视频源码 直播系统源码 短视频直播系统

不是我说,不掌握这些坑,你敢用BigDecimal吗?

程序员小毕

Java 程序员 面试 后端 BigDecimal

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