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

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

讲师介绍

徐乾伟(烧鹅)-淘宝前端技术专家,来自淘宝虚拟互动团队,这个团队主攻 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 ,这是一种误解。

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

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

大家是不是一脸懵逼呀~

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

使用 Web GL

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

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

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

难点一:建筑模型的制作,我们的设计师是个平面设计师,不会做 3D ,他当时给我的图是这样的,你看着办吧,我当时花了整整一天时间做模型。
**
难点二:地面算法**,这个地面是六边型的结构,要把地面从地球坐标系转换成 3D 世界里的场景,会分几步。我们小时候都看过世界地图,怎样把一个球形的面投射到平面上呢?

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

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

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

好不容易跨过了双十一的坎,我们已经看到 Canvas 2d 的方案在模型输入和绘制性能方面都是非常弱的。
如何继续开发 3D 类的游戏呢?可能大家会问,WebGL 在 PC 上都不行,在手机上行不行呀?我跟大家说,现在完全没问题,我们在上亿台同时在线的设备上都试过了,前提是要做一下 WebGL 能力检测。 PC 还有一些古董浏览器不支持 WebGL ,反而手机比 PC 发展快得太多。

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

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

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

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

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

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

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

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

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

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

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

游戏编辑器

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

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

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

2017 年我去澳洲参加了 Web 3D 大会,他们当时用了 X3dom 像 HTML 一样用标签地描述 3D 世界。
这是一种非常陈旧的技术,虽然也是基于 WebGL 渲染。这个方案已经推了十几年了,老外也不知道为什么这么执着,有几十个 Paper 都是讲这个的。他们讲的东西都非常学术,我觉得对我们的帮助并不是很大。

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

我发现里面有各种各样的新颖的技术。比如,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 源文件。这里我们看到,红包模型是预先切开的,大家知道切水果也是这样做的,即使你竖着切菠萝它还是横着裂开的。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Playcanvas 和 Threejs 有什么区别?

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

编辑器架构

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

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

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


原文链接
本文为云栖社区原创内容,未经允许不得转载。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/517897.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Warning: Missing charsets in String to FontSet conversion

当出现Warning: Missing charsets in String to FontSet conversion时 输入export LANGC即可解决

sstableloader工具使用及原理解析

sstableloader是cassandra提供的bulkload工具&#xff0c;可以将sstable文件导入到集群中。本文详细介绍其用法和实现原理。 用法 sstableloader工具在cassandra的bin目录下面&#xff0c;用法如下&#xff1a; bin/sstableloader <options> <dir_path> 具体的…

什么是工程师文化?

作者 | 王尊&#xff0c;帷幄 Whale CTO责编 | 唐小引头图 | CSDN 下载自东方 IC出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;什么是工程师文化&#xff1f;这篇文章的契机&#xff0c;是在 Whale All Hands 上团队成员提出的问题基础上展开的。All Hands 后我在…

Linux7/Redhat7/Centos7 安装Oracle 12C_安装Oracle软件_04

文章目录一、安装准备1. 下载oracle12c2. 上传oracle12c3. 赋予权限4. vnc远程连接主机5. 解压5. 安装二、安装流程2.1. 邮箱设置2.2. 只安装数据库软件2.2. 单实例数据库安装2.3. 企业级数据库2.4. 校验依赖2.5. 依赖安装2.6. root执行脚本2.7. OK2.8. 完成安装一、安装准备 …

从校招生到核心架构师,支付宝研究员李俊奎谈如何成为一名优秀的程序员

校招进入支付宝&#xff0c;11年时间&#xff0c;从一线工程师成长为支付宝安全核心架构师&#xff0c;这个技术牛人就是李俊奎。 李俊奎一直聚焦风控平台的技术和架构发展&#xff0c;并着手搭建了中国第一家云上的商业银行——网商银行。 在2016年双11和新春红包等活动中&a…

在 Apache Spark 中利用 HyperLogLog 函数实现高级分析

在 Apache Spark 中利用 HyperLogLog 函数实现高级分析 预聚合是高性能分析中的常用技术&#xff0c;例如&#xff0c;每小时100亿条的网站访问数据可以通过对常用的查询纬度进行聚合&#xff0c;被降低到1000万条访问统计&#xff0c;这样就能降低1000倍的数据处理量&#xf…

华为智能IP网络,加速联接智能化转型

[中国&#xff0c;深圳&#xff0c;2020年5月19日]在华为第17届全球分析师大会期间&#xff0c;华为“引领智能网络&#xff0c;加速联接智能化转型”峰会隆重召开&#xff0c;会上首次阐述了智能IP网络的三大特征——“智能超宽、智能联接、智能运维”&#xff0c;并分享智能I…

Linux7/Redhat7/Centos7 安装Oracle 12C_监听配置及DBCA安装数据库_05

文章目录一、监听配置二、创建数据库一、监听配置 # 切换到oracle用户 su - oracle# 启动监听图形化页面 netca二、创建数据库 dbca

Kubernetes-native 弹性分布式深度学习系统

9月11日&#xff0c;蚂蚁金服在 Google Developer Day Shanghai 2019 上宣布开源了基于 TensorFlow 2.0 eager execution 的分布式深度学习系统 ElasticDL。基于 TensorFlow 的支持弹性调度的深度学习系统&#xff0c;据我们所知&#xff0c;ElasticDL 是第一 个。项目负责人王…

递归(特别重要,小计算用)

递归&#xff08;特别重要,小计算用&#xff09; 递归就是&#xff1a;A方法调用B方法&#xff0c;就是自己调用自己。 利用递归可以简单的程序来解决一些复杂的问题。它通常把一个大型的问题层层转化为一个与原问题相似的规模较小的问题来求解&#xff0c;递归策略只需少量的…

达摩院送你100万,请坚持“看月亮”

首批青橙奖获奖者合影 30年前&#xff0c;随便走进一间中国的小学教室&#xff0c;问其中埋头苦读的孩子&#xff0c;长大以后要做什么&#xff1f; “做个科学家&#xff01;” 梦想改变世界的小娃娃眼神透亮&#xff0c;声音也透亮。 但少有人能够真正在成年之后&#xf…

深度剖析数据库国产化迁移之路

作者 | 吴夏&#xff0c;腾讯云 TDSQL 高级工程师责编 | 唐小引头图 | CSDN 下载自东方 IC出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;随着国家有关部门近年来陆续出台相关政策指导文件&#xff0c;推动探索安全可控的金融科技产品&#xff0c;加强银行业信息安…

常用排序算法总结

概述 在计算器科学与数学中&#xff0c;一个排序算法&#xff08;英语&#xff1a;Sorting algorithm&#xff09;是一种能将一串数据依照特定排序方式进行排列的一种算法。本文将总结几类常用的排序算法&#xff0c;包括冒泡排序、选择排序、插入排序、快速排序和归并排序&…

4. java——多态(java巅峰设计,超越了C++的理解,取其精华,去其糟粕)

多态指的是同—个行为具有多个不同表现形式 。是指—个类实例(对象&#xff09;的相同方法在不同情形下具有 不同表现形式。封装和继承是多态的基础&#xff0c;也就是说&#xff0c;多态只是—种表现形式而已。一个对象&#xff0c;同一个方法不同形态&#xff0c;方法必须重…

ETL异构数据源Datax_日期增量同步_13

文章目录一、全量同步1. 增量同步SQL2. 构建reader3. 构建writer4. 字段对应关系映射5. 构建json6. 选择同步模板7. 查询最早时间8. 修改任务信息9. 添加增量参数10. 数据清理11. 执行任务12. 查看执行日期13. 数据验证15. 查看同步脚本二、基于日期增量同步2.1. 新增新数据2.2…

如何使用 SQL Server FILESTREAM 存储非结构化数据?这篇文章告诉你!

作者 | ALEN İBRI译者 | 火火酱&#xff0c;责编 | Carol封图 | CSDN 付费下载于视觉中国 在本文中&#xff0c;我将解释如何使用SQL Server FILESTREAM来存储非结构化数据。同时&#xff0c;还会介绍FILESTREAM的优缺点。 在SQL Server的早期版本中&#xff0c;非结构化数据的…

Apache Flink 进阶入门(二):Time 深度解析

前言 Flink 的 API 大体上可以划分为三个层次&#xff1a;处于最底层的 ProcessFunction、中间一层的 DataStream API 和最上层的 SQL/Table API&#xff0c;这三层中的每一层都非常依赖于时间属性。时间属性是流处理中最重要的一个方面&#xff0c;是流处理系统的基石之一&am…

月活用户达7.55亿,阿里淘系如何在后流量时代引爆用户增长?

2019 年 8 月&#xff0c;阿里巴巴集团公布截至 2019 年 6 月 30 日止季度业绩。 财报显示&#xff0c;本季度阿里巴巴集团收入为 1149.24 亿元人民币&#xff0c;同比增长 42%。其中&#xff0c;淘宝、天猫在内的中国零售平台移动月活跃用户达 7.55 亿&#xff0c;较上一季度…

数组,三种初始化和内存分析

数组&#xff0c;三种初始化和内存分析 Java内存分析&#xff1a; 堆&#xff1a;存放new的对象和数组 ​ 可以被所有的线程共享&#xff0c;不会存放别的对象引用 栈&#xff1a;存放基本变量类型&#xff08;会包含这个基本类型的具体数值&#xff09; ​ 引用对象的变量&a…