口罩前处理法(Native)

[最近更新时间:2019/09/03]

 

使用 Live2D Cubism SDK for Native,以保持智能手机等的绘图速度。
在模型绘制过程开始时,采用了为一个掩模缓冲区绘制所有掩模形状的“预处理方法”。

在原理绘制方法中,每次绘制需要蒙版的Drawable时,都会绘制蒙版形状(见图)。
使用这种方法,每次 Drawable 需要遮罩时,都会发生切换渲染目标和清除缓冲区等相对昂贵的处理。
因此,它可能会导致智能手机上的绘图速度降低。

但是,仅仅提前准备好掩码需要多个掩码缓冲区,这会给内存带来压力。
为了解决这个问题,可以对一个掩码缓冲区进行以下处理,以减少内存压力,同时将其视为正在使用多个掩码缓冲区。

 

面罩集成

由于所有的蒙版都是预先生成的,因此接受相同蒙版规范的Drawables可以减少使用相同蒙版图片生成的张数。

这个过程在 CubismRenderer_OpenGLES2::Initialize 函数调用中完成。
这是由 Cubism ClippingManager _OpenGLES2 :: Initialize 函数完成的。

 

 

按颜色信息分离

掩码缓冲区是一个 RGBA 视频数组,就像普通的纹理缓冲区一样。
普通遮罩仅使用此 A 通道来应用遮罩,而不是 RGB 通道。
因此,通过在 RGBA 中具有单独的掩码数据,一个掩码缓冲区可以作为四个掩码缓冲区处理。

 

 

拆分分离

当 4 个掩码图片不够用时,通过2等份、4等份和9等份处理掩码缓冲区来增加掩码数量。
由于还存在按颜色信息划分的情况,因此最多可以保存36 个 4x9 的不同蒙版。

此外,为防止蒙版图片被压扁,请使用应用蒙版的所有可绘制矩形绘制蒙版。
因此,需要使用掩码生成范围、掩码和矩阵。

 

 

 

检查矩形

在蒙版生成的第一步中,对于每个蒙版,检查适合所有蒙版的矩形。

 

 

分色和分色后的布局决策

确定每个蒙版所属的蒙版缓冲区的颜色通道和分割位置。

 

 

蒙版绘制,使用蒙版生成矩阵

根据绘制前检查的矩形范围及其所属位置,准备用于掩码生成和掩码使用的转换矩阵。

 

 

掩码缓冲区的动态调整大小

GLES2 渲染器提供了一个 API 来在运行时调整掩码缓冲区的大小。
目前,掩码缓冲区的大小设定为 256 * 256(像素)作为初始值,但如果要将掩码生成区域切割成 9 张,
在85 * 85(像素)的矩形区域内绘制的蒙版形状进一步放大,作为剪裁区域。
因此,剪裁结果的边缘会模糊或渗色。
作为解决方案,我们提供了一个 API,可以在程序执行时变更掩码缓冲区的大小。

例如,通过将遮罩缓冲区的大小从256 * 256设置为1024 *1024,如果将遮罩生成区域切成9张,则可以在341*341的矩形区域中绘制遮罩形状。
您还可以放大并将其用作剪裁区域,以消除剪裁结果边缘的模糊和渗色。

* 增加蒙版缓冲区的大小⇒如果要处理的像素数增加,速度会变慢,但绘制结果会很漂亮。
* 减少掩码缓冲区的大小⇒ 由于要处理的像素数减少了,所以速度会更快,但是绘制结果会很脏。

 

 

预处理方法能提高性能的原因

作为移动终端特有的情况,GPU的Clear指令和渲染目标切换指令的处理成本可能高于其他指令。
在使用原理方法绘制时,这些昂贵的指令会被执行的次数与需要遮罩的 Drawable 数量一样多。
然而,在预处理方法的情况下,可以减少这些指令的执行次数,这有望提高智能手机等的性能。

为了真正理解效果,我们来衡量一下每个处理单元在渲染中的时间成本。
作为测量方法,请检查下面显示的源代码。 为每个构建单独测量层。
另外,要测试的模型是Haru集成的。
我们准备了两种 Android 设备和一种 Windows 设备进行测量。
测量是通过Android端的clock_gettime函数和Windows端的QueryPerformanceCounter函数将结果缓存到缓冲区并计算平均值。

剪贴蒙版生成器(第1层)

CubismClippingManager_OpenGLES2::SetupClippingContext 测量切换绘图目标和填充的时间。

 

整体模型图(混合层1和 2)

测量绘图前、排序和绘图后处理。

它也是通过划分图层在掩码生成和其他绘图的轮廓中测量的。

 

绘制网格(第1层)

CubismRenderer_OpenGLES2::DrawMesh 测量设定到着色器的时间和绘图指令的单次时间。

 

第3层

更新的流程作为一个概要
我们把它分为三个部分:参数计算、模型更新和渲染。

 

 

结果

  Android1 Android2 Winpc1
L1clear  1781.20  218.80  26.80
L1gldraw  45.47  51.63  10.58
L1sharder  12.31  9.34  5.37
L1post 1.50 1.00 0.10
L1switch 10.70 56.30  7.80
L1predraw 15.90 8.20 2.20
L1sort 7.60 7.00 0.60
L2MaskMake 2686.80 1357.60 318.50
L2draw 4004.10 4013.20 1217.00
L3paramupdate 392.00 375.40 89.70
L3modelupdate 1357.50 1410.90 1070.40
L3rendering 6715.70 5233.70 1892.00

上表显示了上图部分的执行时间。
可以看到在移动端Clear的成本很高,切换渲染目标比其他指令重。
原则上,这条繁重的指令会运行尽可能多的 Drawable,因为它需要一个遮罩。
由于该计算只能进行一次,因此可以预期智能手机等的性能改进。

 

 

将遮罩处理切换为高清方式

如上所述,每次绘制时生成掩码的方法会影响低规格终端的性能。

但是,当屏幕质量比运行时的性能更重要时,例如当最终输出为视频时,此方法更适合。

在 2018/12/20 之后的 SDK 中,可以将遮罩处理切换为高清方式。
要切换到高清方法,请将 true 传递给以下 API。

© 2010 - 2022 Live2D Inc.