可视化
# 可视化笔记
canvas 和 webgl技术调研
# canvas vs webgl
- WebGL 是 OpenGL 的版本,它是一个 3D 引擎。它帮助用户在网络浏览器中执行 3D、2D 操作。
- Canvas 是 HTML5 的一部分,允许其用户使用动态的、脚本渲染的 2D 形状。它可以被认为是具有更新位图图像的能力并且没有内置场景图的低级别。
- 这些用于具有抽象层的游戏(2D 和 3D),如 PIXI.js 和其他几个如 Three.JS 和 Unity。
比较内容 | canvas | webgl | |
---|---|---|
开发者 | 由 Apple 推出,用于在内部和 MAC 操作系统中使用 | Mozilla 基金会是 WebGL 组件的原始作者。但是,开发人员是 Kronos WebGL 工作组 |
出现 | 2004年 | 2011年 |
诞生 | webgl的前身 | WebGL 从 Canvas 3D 实验演变而来 |
速度 | 谈到速度因素,Canvas 放慢了它的组件 | WebGL 在速度方面优于 Canvas |
开发选择 | 通常首选用于 2D 渲染和相关作品 | 虽然它也可以在 2D 上工作,但更适合 3d |
区别:
- canvas 元素是 HTML 元素,在其第 5代(HTML5) 中引入。这允许其用户使用 JavaScript 在屏幕上绘图;这种动态生成的图形和动画在客户端是可能的,而 WebGL 是一个非标准化的 API,它允许使用 JavaScript 实现 OpenGL 功能。可以使用浏览器渲染 3D
- 如果您的要求是 2D 游戏(高级),请确定画布。使用画布进行 2D 的惊人绘图功能。你的游戏性质决定了这种选择。如果你的需求是移动项目少的 2D 游戏,Canvas 是解决方案,如果有重复的新帧,那么对于这种渲染循环,你需要更喜欢 Webgl
结论:
- Canvas易于工作且学习曲线更容易,而另一些则难以执行并极大地影响了游戏行业。
- 当应用程序的要求是轻量级和面向 2D 时,Canvas 可以很好地工作。
- WebGL 当您正在开发的工作将变得更加复杂,帧速率更高,最重要的是它的 3D。
- 每个都有其优点和缺点,当需要为您的工作选择合适的匹配时,用户的工作取决于这些。Canvas 和 WebGL 都有很好的库和用户基础
# canvas
# 局部重绘
- 开始前先
save()
保存上下文环境 - 然后用
clearRect()
清空目标区域像素,然后用rect绘制一个相同的矩形路径(可以自行多次绘制,区域会叠加) - 接着
clip()
一下,之后所有的绘制操作都会自动被限制在rect的区域内。只要按正常方式去把跟重绘区相交的对象都绘制一遍就好了。 - 最后是调用restore()取消clip()的限制。
// region 是重绘区
context.save();
context.clearRect(region.minX, region.minY, region.width, region.height);
context.rect(region.minX, region.minY, region.width, region.height);
context.clip();
//在此绘制相关的显示对象...
context.restore();
1
2
3
4
5
6
7
2
3
4
5
6
7
接下来的关键是如何获取重绘区
# 获取重绘区
# webgl
# 性能优化
# 传统(GPU)位图生成算法性能问题
- 大量的循环处理,每个涉及的像素都要处理一遍(按照现在手机的分辨率,算算一帧有多少要处理的)
- 颜色融合其实就是浮点数插值算法,对每个次像素都要做,运算量巨大
解决:
- 对于像素太多的问题,最好的办法就是脏区域渲染。用人类话来说就是每次渲染的时候,最大化的在上一帧的基础上面进行,对本次这帧没有变化的像素来说直接忽略处理。
- 对于浮点数运算太多,可以通过多媒体指令来加速。比如:ARM Neon Intel MMX SSE 等等。以ARM为例,ARM有 16个通用计算寄存器,16个Neon指令寄存器,16个VFP高精度浮点数运算加速器。其中Neon指令可以让程序在一个指令周期里面计算8个浮点数的运算,理想的情况下相当于比传统的浮点运算性能提升了8倍。当然这些指令主要就是用来处理多媒体的,所以又叫多媒体指令 也叫 SIMD指令(Single Instruction Multiple Data,单指令多数据流,Android的底层绘图库就有基于Neon的优化器,我也尝试过用SSE指令优化Windows平台API AlphaBlend函数)。
# 图形硬件和硬件的渲染方式
# 图形渲染
全屏刷新渲染
基于显示列表结构的渲染方式,最常的就是全屏刷新模式。这也是目前大多数游戏引擎普遍采用的方案,因为不管是原理还是实现都比较简单:首先设定一个时钟频率,例如通常是每秒执行60次。每次都单独刷新一次屏幕。刷新过程就是直接清空整个屏幕,然后从显示列表的根节点开始遍历,按顺序找到每个可呈现的显示对象节点,按照它的坐标和大小绘制到屏幕上。这样开发者只需要改变显示对象的位置属性,等待下一次时钟周期到来,改变就会自动刷新到屏幕上。由于通常情况下,并不是每秒60次显示列表每次都会发生改变,或者发生改变时仅有一小部分改变。因此清空整个屏幕重绘的方式虽然实现简单,但是不必要的开销比较大。脏矩形渲染
脏矩形渲染是一种基于显示列表的局部刷新方法。依然是要有一个时钟频率,定时每秒执行60次。但区别是每次我们并不直接清空整个屏幕,而是首先计算屏幕上发生改变的区域,这里我们叫做重绘区,然后只清空指定的重绘区,并找出跟这个区域相交的所有显示对象重绘一遍。如果显示列表本次美并没有发生改变,那么将直接跳过本次绘制,什么也不做。
显而易见的是它能大幅提高屏幕整体渲染性能,特别是对于复杂UI界面的情况,全屏刷新算法会每秒60次不停地刷新所有UI对象,在有脏矩形渲染的情况下,哪改变绘制哪,极端情况直接跳过绘制,在复杂UI界面的情况非常容易达到满帧。另外脏矩形渲染能够节省设备电量以及降低发热量。我们曾经测试过同一个线上游戏,在更新到脏矩形渲染后,整体耗电量降到了原先的30%,发热量也从45度降低到了35度,结果还是非常显著的。
上次更新: 2022/03/28, 19:32:27