写点什么

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

评论

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

1.基于Label studio的训练数据标注指南:信息抽取(实体关系抽取)、文本分类等

汀丶人工智能

数据标注 关系抽取 labelstudio 实体抽取

软件开发,如何同时保证效率和质量?

飞算JavaAI开发助手

【图解】白嫖阿里云价值3.3万的TiDB

TiDB 社区干货传送门

实践案例 管理与运维 扩/缩容 6.x 实践

体验ChatGPT后,陷入沉思...

Openlab_cosmoplat

开源 行业趋势 ChatGPT

还在头疼你的API,送你一个保姆级的API设计管理平台

华为云开发者联盟

云计算 开发 华为云 华为云开发者联盟 企业号 3 月 PK 榜

国内“谁”能实现chatgpt,对MOSS、ChatYuan给出关键技术简评,一文带你深入了解宏观技术路线| 社区征文

汀丶人工智能

ChatGPT

SVN vs Git 不是技术之争,而是生态之争

极狐GitLab

git svn DevOps 版本控制 极狐GitLab

文件传输协议的五种安全文件传输替代方案

镭速

如何通过C#和VB.NET压缩PDF文档

Geek_249eec

C# .net PDF VB.NET

如何在服务端渲染fabric.js

ModStart

PHP中出现Cannot modify header information - headers already sent

ModStart

云数据库 TiDB 体验

TiDB 社区干货传送门

社区活动 6.x 实践

备战一年半,我们让最火的开源网关上了云

API7.ai 技术团队

api 网关 APISIX SaaS 平台

吹爆Alibaba自研的Spring全能笔记,建议人手一份!

小小怪下士

Java spring springmvc springboot

BSN-DDC基础网络详解(四):资金账户充值

BSN研习社

【2.24-3.3】写作社区优秀技术博文一览

InfoQ写作社区官方

热门活动 优质创作周报

爱奇艺统一实时计算平台建设

Apache Flink

大数据 flink 实时计算

坚如磐石:TiDB 基于时间点的恢复(PiTR)特性优化之路丨6.5 新特性解析

PingCAP

TiDB

该如何正确的中断一个线程的执行

华为云开发者联盟

开发 华为云 华为云开发者联盟 企业号 3 月 PK 榜

国内“谁”能实现chatgpt,一文带你深入了解宏观技术路线| 社区征文

汀丶人工智能

ChatGPT

政企专属的IM即时通讯平台,促进团队安全沟通与协作

BeeWorks

百度点石隐私计算平台与FATE开源框架实现互联互通

百度安全

人工智能 开源 联邦学习 开发

Java Agent场景性能测试分析优化经验分享

华为云开发者联盟

开发 华为云 java 华为云开发者联盟 企业号 3 月 PK 榜

天下武功唯快不破:TiDB 在线 DDL 性能提升 10 倍

TiDB 社区干货传送门

基于Python+uiautomation的windowsGUI自动化测试概述

Python 自动化测试 unittest WindowsGUI UIaotumaiton

AI开发实践丨客流分析之未佩戴口罩识别

华为云开发者联盟

人工智能 华为云 华为云开发者联盟 企业号 3 月 PK 榜

极狐GitLab DevSecOps 为企业许可证安全合规保驾护航

极狐GitLab

许可证 DevSecOps 极狐GitLab 安全左移 安全合规

2023年2月中国网约车领域月度观察

易观分析

网约车 出行服务

火山引擎DataTester:A/B实验如何实现人群智能化定向?

字节跳动数据平台

大数据 AB testing实战

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