万谱




从踩坑到填坑|淘宝Web 3D应用与游戏开发实战(淘宝3d网站)

从踩坑到填坑|淘宝Web 3D应用与游戏开发实战(淘宝3d网站)

导读:本文是淘宝前端技术专家——徐乾伟(烧鹅)分享的淘宝 Web 3D 应用与游戏开发实战,这个话题在业界被谈及得比较少。今天将会从移动、3D 、游戏三种交叉的话题来和大家探讨。接下来和小编一起从初试 Web 3D 、使用 WebGL 、工作流相关的游戏编辑器三个部分来了解吧~

讲师介绍

从踩坑到填坑|淘宝Web 3D应用与游戏开发实战(淘宝3d网站)

徐乾伟(烧鹅)-淘宝前端技术专家,来自淘宝虚拟互动团队 ,这个团队主攻 3D /游戏/ VR / AR 。其中,我们有一个小团队叫斜杠实验室,主攻 Web 方向上的动画和 3D 技术。

为什么我们会在这样交叉领域去发力做一些事情?去年的双十一淘宝去年交易额多少 ?一千多亿 ,其中有 80% 的 GMV 是来自移动端的 ,简单地理解就是说我们公司在电商领域 80% 的钱是通过手机客户端赚取的 ,而不是 PC 。这就是为什么在我们要在移动端做 3D/VR/AR 的应用 。

初试Web 3D

有一句话叫:给我一个支点,我就能撬动地球 。

很多人都做过 2D 游戏 , 3D 最大的区别就是多了一根 Z 轴 ,而给我一个 Z 轴我就能创造 3D 世界 。很多做前端的同学对 3D 这个事情是有误解的,比如说 HTML5 中的 Canvas 有两个上下文 ,大家认为 2d Context 只能画 2D,WebGL context 才能画 3D ,这是一种误解。

从踩坑到填坑|淘宝Web 3D应用与游戏开发实战(淘宝3d网站)

其实 3D 和 2D 并不是由绘图引擎来决定的 ,而是由数学家决定的。假如我们要画这样的曲面会怎么画呢 ?

首先有描述这个面的公式 ,这个公式根据 X 、Y 入参算出 Z 的坐标值,假设 Z 越大颜色越红 ,Z 越小颜色越绿 ,画出来是这样的 。如果 X、Y、Z 乘以一种神奇的东西叫矩阵(矩阵是数学家发明的),这是 3×3 的旋转矩阵 ,把每个点都乘一下,然后画到屏幕上得到的结果就是这样的。

大家是不是一脸懵逼呀~

关于如何用 Canvas 2d 绘制 3D 曲面,以后再详细讲解,我有一段时间写过 CSS3D 的库,就是用 glMatrix 数学库做出非常酷炫的效果 。

使用 Web GL

从踩坑到填坑|淘宝Web 3D应用与游戏开发实战(淘宝3d网站)

2016 年双十一我们做过一个小游戏,不知道大家有没有玩过?

这个游戏是用 Canvas 2d 绘制,就是用的 glMatrix 数学库画实现 3D 效果 。当时为什么用 Canvas 2d 呢 ?我们淘宝市场部的同学说我们要做 3D ,因为 pokemongo 做了一个 3D 的,但是你这个东西最后要给我搞到 iphoness 4 上去。大家知道 iphoness 4是不支持 WebGL 的 ,而当时开发时间非常紧张,我只能用 Canvas 2d 的方案。

如果点了主场景中的猫,就会进入一个 AR 捉猫的环境。这个不是 web 渲染,因为当时移动端的 web 还不具备获取摄像头数据的能力,所以当时 AR 只能用 Native 的 3D 引擎渲染,叫 T3D,顾名思义 Taobao 3D 。另外还有一个比较有趣的 AR 场景,叫“黄金猫”。黄金猫在双十一前后三天会出现在银泰或者苏宁的商场上方 ,你只要抢到了这只猫至少有一百块钱的红包奖励。

难点一:建筑模型的制作,我们的设计师是个平面设计师 ,不会做 3D ,他当时给我的图是这样的 ,你看着办吧,我当时花了整整一天时间做模型。

**

难点二 :地面算法**,这个地面是六边型的结构 ,要把地面从地球坐标系转换成 3D 世界里的场景,会分几步。我们小时候都看过世界地图,怎样把一个球形的面投射到平面上呢?

这种投影叫做墨卡托投影(Mercator projection) 。这个投影算法的代码是服务端拷给我的,因为要保持前后端算法一致,我复制了后端的投影算法 。相比墨卡托投影 ,这是简化的算法,因为要求看到周围的猫是在五十米左右 ,所以精度并不是特别高,简单的算法就能够满足了 。

从踩坑到填坑|淘宝Web 3D应用与游戏开发实战(淘宝3d网站)

当时的视角是这样的,以用户当前的位置经纬度为中心,辐射一圈就可以看到周围有多少只猫。

这里的六边型地面如果用 X、Y 两个轴的算法去计算其实是比较慢的,我当时看了一篇论文,这是一个斯坦福的同学花了二十年研究六边型的算法,他本质上是以夹角为 120 度的 X 、Y 、Z 三个轴为坐标轴算,相比算 X 、Y 两个轴的算法快很多。上面还有很多基于这个基础算法拓展的算法如寻路等 。

好不容易跨过了双十一的坎 ,我们已经看到 Canvas 2d 的方案在模型输入和绘制性能方面都是非常弱的。

如何继续开发 3D 类的游戏呢?可能大家会问,WebGL 在 PC 上都不行,在手机上行不行呀 ?我跟大家说,现在完全没问题 ,我们在上亿台同时在线的设备上都试过了,前提是要做一下 WebGL 能力检测。 PC 还有一些古董浏览器不支持 WebGL ,反而手机比 PC 发展快得太多 。

从踩坑到填坑|淘宝Web 3D应用与游戏开发实战(淘宝3d网站)

大家之前理解了 3D 的概念 , 3D 不是绘图引擎的功能, 3D 是数学的概念。那 CPU 绘图与 GPU 绘图有什么区别呢?GPU 是并行处理每一个像素的。

我们刚开始尝试 WebGL 小心翼翼,因为怕给手淘带来影响,事实上也造成比较大的 Crash  。

2016 年的圣诞节,市场部同学说要不在手淘里下一场雪吧,那就下了。后面我会和大家介绍下这场雪的代价。我们还尝试做类似于右边这种模型粒子动画,这是一只天猫的模型。这两个都是粒子系统,因为我们刚开始不知道怎么做复杂的 3D 渲染 ,我们只能从最基础的绘制“点”出发去尝试 。

从踩坑到填坑|淘宝Web 3D应用与游戏开发实战(淘宝3d网站)

我们团队有一种叫 PopLayer 的技术,可以在当前 Native View 上面随时弹出一层 Web View。比如之前搜一下鹿晗出弹幕,还有明星打电话 ,都是通过 PopLayer 技术实现的。

上文提到,在淘宝首页的 Poplayer 里 下一场雪导致了大面积的客户端Crash  。原因是 ioses 下的 UIWebView 使用 webgl 渲染时,WebCore 会调用到 OpenGL ES 进行渲染,而苹果发现有在后台调用 OpenGL ES,就会直接结束 App。

知道 RequestAnimationFrame API 吗?解法就是监测当前用户退出后台或当前页面不可见时 ,会把 RequestAnimationFrame 停止。

小倩也提到过 Page Visibility 方面的 API ,我们发现安卓是支持这个 API 的 , 但 ioses 还是需要调 Js Bridge接口来监听 App 的是否退后台的状态。接着 ,我把游戏主循环(或者动画主循环)停下来之后还发现一些用户会 Crash 。最后我发现一件非常神奇的事情~这个代码大家都知道,它是用来获取Canvas的WebGL context,这行代码为什么Crash呢?我们翻了 Webkit 的源码发现它有一个 reshape 函数 ,reshape 会通过 GPU 获取当前画布的高宽,所以它还是会 Crash 。

接下来将会分享 3D 之旅我们的心情,以及我的思维是如何进化的。

2017 年的造物节时我们做了真正意义上的 3D 应用,当时跟英国一家设计公司合作叫 FRAMESTORE ,这个电影(《奇异博士》)大家知道吧 ,特效就是他们设计制作的。

从踩坑到填坑|淘宝Web 3D应用与游戏开发实战(淘宝3d网站)

FRAMESTORE 当时给我的东西是这样的,俯视图是这样的,灯光是这样打的。虽然他们在影视特效领域非常牛逼,但是他们也没做过 Web 应用。而我当时也不知道怎么和设计团队合作,还是我的老方法手写代码 。他们给我的模型,我当时也不知道其他高级的格式,只知道 Obj Mtl 。如果发现 WebGL 渲染有问题,我们就去代码里找原因,模型引用的材质对不对 ,贴图对不对。我们要翻代码看一下是不是引用错了。工作流的问题在这个项目中没有解决 ,但是促使我开始寻找问题的解法。

这个项目还有一个性能问题,广告牌发光效果,我第一个想到的是后处理(Post Processing),大家不理解的话,可以把它当作实时滤镜 ,如果在手机屏幕这么大的 Bloom 滤镜是会卡死的。我当时的方案是在每块广告牌上写一个独立的 Shader ,这样在iphoness6上至少是可以流畅渲染的。

游戏编辑器

上面讲了这么多 ,痛苦和迷茫。其实我之前做的东西也不能称之为真正的游戏,只能算是营销互动类游戏。

我们还是觉得做游戏要向业界规范的方案靠拢,所以 游戏编辑器是必须要做的。虽然我今天并没有做出一款游戏编辑器,我会跟大家分享为什么我要做游戏编辑器(现在已经正在做了) ,这中间的坎坷是今天要讲的重点。

从踩坑到填坑|淘宝Web 3D应用与游戏开发实战(淘宝3d网站)

和英国团队合作之后我非常难过,他们的设计做得那么酷,而我只能实现成这样。我在中国环顾一圈,没有看到 Web 3D 游戏方面比较好的方案,因为在中国做 WebGL 的都凤毛麟角。

2017 年我去澳洲参加了 Web 3D 大会 ,他们当时用了 X3dom 像 HTML 一样用标签地描述 3D 世界 。

这是一种非常陈旧的技术,虽然也是基于 WebGL 渲染 。这个方案已经推了十几年了 ,老外也不知道为什么这么执着,有几十个 Paper 都是讲这个的 。他们讲的东西都非常学术 ,我觉得对我们的帮助并不是很大 。

然后我又去工业界寻找解决方案。这是前索尼 PlayStation 的一位同学做的应用,他用的技术大家可能会大吃一惊 ,他用了Unity 。第一次看到 Unity 和 Web 嫁接起来是非常令我震惊的 。我当时用的是 iphoness6 ,运行这个 demo 都是 60 fps 满帧,他是怎么做到的呢?我去查了一下它的代码,虽然代码是压缩过的,但是为了突破这个技术难关 ,我阅读了压缩后的代码并且理解了它背后的实现。

从踩坑到填坑|淘宝Web 3D应用与游戏开发实战(淘宝3d网站)

我发现里面有各种各样的新颖的技术 。比如 ,Unity 可以合并 3D 模型的贴图。

合并贴图这件事情是很重要的 。做前端的同学都知道雪碧图 ,为什么做雪碧图 ?大家都知道是为了减少网络请求数,但是其实合并贴图对运行时的性能有很大影响 。

GPU 读一张图快还是读十张图快 ?计算机资源是非常宝贵的 ,图片要适度合并尽量压缩 。一张 200K 的图片,可能占用 3-4 倍的显存 。 JS 优化半年减少 30K ,图片批量压缩减少个几兆都是有可能的,所以要把时间花在能够快速见效的事情上面 。

下图的 Texture Baker 就是用来烘培并且合并图片。这个是 ITween Path 是 Unity 做路径动画的插件。

Unity还有一个插件叫 Collada Exporter 。Collada 是标准的 3D 模型格式,看到这里我们已经抛弃了之前 Obj Mtl 的老方案 。而Runtime根据我之前的开发经验封装了一套 MVC 的方案 。

基于这套工作流 ,我们做了 2017 年双十一切红包项目 。我们经常调侃:腾讯做游戏和阿里做有戏有什么区别?腾讯做游戏是收钱 ,我们做游戏是发钱。用 Unity 带来的好处是能够直接导入设计师给的源文件,如 Maya 源文件、 Photoshop 源文件。这里我们看到,红包模型是预先切开的 ,大家知道切水果也是这样做的,即使你竖着切菠萝它还是横着裂开的 。

从踩坑到填坑|淘宝Web 3D应用与游戏开发实战(淘宝3d网站)

至于红包的特效,我会经常逛一些国外的网站,这是某个游戏开发者写的 Shader 特效 ,我就照着他的思路来写了一个类似的。

大家看到一个红包在天上飞,上面有光在流动 ,其实整个场景中一盏灯都没有打。光照计算,特别是点光源的计算是非常耗性能的 。所以大家做 3D 应用的时候尽量要少放光源 。这种效果其实只要在像素着色器中写一行代码就解决了。

红包是怎么切中的呢?Picking 这个话题对没有开发过游戏的人也许比较陌生,切红包的游戏里我当时做了两种方案:一种叫做 CPU Picker ,另一种是 GPU Picker 。

CPU Picker:在每个红包上面套上一个包围盒,计算射线有没有击中这个包围盒,因为 CPU Picker 的计算成本和场景的复杂度正相关, 用包围盒会比较快;

GPU Picker:通过拾取离屏画布上面的颜色值就行了 。

虽然感觉 GPU Picker 性能会特别好,但在移动端性能表现却不佳,因为拾取颜色的过程实际上是 CPU 和 GPU 通信的过程,这个过程会比较慢 。所以,CPU Picker 性能会更好一点。

从踩坑到填坑|淘宝Web 3D应用与游戏开发实战(淘宝3d网站)

还有一点就是 Dom 操作,在 Web 游戏开发中,Dom 操作就是魔鬼。我抓了比较慢的一帧花了 25 毫秒(约 40 帧)。

游戏逻辑加上 Web GL 渲染就花了那么几毫秒 ,而 DOM 操作却耗掉很长的时间,而且还引发了重绘(紫色部分)。

所以 Dom在游戏里是不合适的 ,GUI 部分需要用 2D 的 Canvas 或者 Web GL 渲染去解决 。

从踩坑到填坑|淘宝Web 3D应用与游戏开发实战(淘宝3d网站)

最后讲一下音效 ,我个人非常喜欢游戏中声音给我带来的奖励  。我做切红包的时候注意到了上面几点,这也是我上周去北京 Unity 大会上听到关于 CRIWare 的声音中间件的内容:

  • 背景音乐要有渐有渐出,这样用户体验比较好 ;
  • 用户做一些操作或者比较重要操作的时候,当前声音要强调一下 ,背景音乐减弱一下 ;
  • 声音要有变化,比如说很多射击的游戏 ,如果枪声都一样 ,用户听觉会疲劳的 ,我们切红包时左切和右切都是不一样的。

这个软件叫 bfxr ,是一款制作游戏音效的小软件,在线和客户端版本都有,人人都可以设计音效。

从踩坑到填坑|淘宝Web 3D应用与游戏开发实战(淘宝3d网站)

讲了那么多技术点 ,我们总要看一下业界真正做游戏的人是怎么做的 。我大概探索了一两年,发现 Playcanvas 引擎是 Web 世界上最健全的游戏引擎。它的引擎代码是开源的,但是编辑器不开源。我分析了一下它的引擎源码 ,大概有几部分组成:

  • ECS 的架构 ,Unity 也是采用这样的设计模式 。
  • PBR,基于物理的渲染模型 ,看起来更像真实世界的渲染。物理引擎也是很重要的,还有输入设备,比如说你的游戏手柄 、手机都是输入设备。

Playcanvas 和 Threejs 有什么区别?

Threejs 只是一个 3D 渲染库。游戏还有一个非常重要的东西叫编辑器,这是 Playcanvas 在线的编辑器,我看了这个游戏之后就觉得一定要做编辑器 ,因为编辑器是引擎的载体。如果没有编辑器,我们每次开发游戏要注意的工程和技术问题太多。

编辑器架构

最后讲一下我们团队思考的编辑器的架构,现在只是一张工程架构图。

游戏最后发布的内容是什么?就是一堆资源 ,图片、模型 、音频 、脚本 ,在 Web 开发环境中最后都要发上 CDN 。

游戏里的大部分资源如音频 、全景图、模型这些都是第三方软件输入的,模型资源的序列化、减面、合并 、烘培等操作我们暂时可能不会去做(还是交给 Unity 做),中间 GUI 部分就是编辑器的面板操作,最后 Script 组件和 Shader 可以通过 Vscode 来编辑。这张图是我一两年的心得 ,大家可以留言区交流~

从踩坑到填坑|淘宝Web 3D应用与游戏开发实战(淘宝3d网站)

作者 :徐乾伟(烧鹅)

相关新闻

联系我们
联系我们
分享本页
返回顶部



XML地图