各Cubism SDK的比较

最終更新: 2022年10月6日

  Cubism SDK for Unity Cubism SDK for Native Cubism SDK for Web Cubism SDK for Java
蒙版共享 共享CubismMaskController指定的MaskTexture 使用在模型内共享的蒙版纹理 同左 同左
蒙版数量 默认情况下可以使用64个蒙版 默认情况下可以使用36个蒙版
* 通过启用高清蒙版可以解除限制。
有关详细信息,请参考“蒙版前处理方法(Native)”。
默认情况下可以使用36个蒙版 默认情况下可以使用36个蒙版
* 通过启用高清蒙版可以解除限制。
有关详细信息,请参考“蒙版前处理方法(Java)”。
蒙版的构成方法 蒙版大小是固定的
由一个正方形组成,该正方形可以包含要添加蒙版的一侧
自动调整大小
以能够包含可添加蒙版一侧的矩形完全配置为蒙版形状
同左 同左
如何绘制 绘制顺序(升序和降序)、Z值(升序和降序) 绘制顺序升序 同左 同左
OW姿势功能 有(R11 beta1~) 同左 同左
OW表情功能 有(R11 beta1~) 同左 同左
动态管理 将Unity的motion3.json转变为AnimationClip,
使用Mecanim进行
使用Cubism SDK for Native进行 使用Cubism SDK for Web进行 使用Cubism SDK for Java进行
SDK使用语言 C# C++ Type Script Java
Live2D置入 GUI上 代码上 同左 同左
输出目的地平台 Windows, macOS, iOS, Android, WebGL,
PlayStation 4, Nintendo Switch
Windows, macOS, Linux, iOS, Android,
PlayStation 4, Nintendo Switch
Web浏览器 Android

蒙版特性的差异

Cubism SDK for Unity

在Unity中,蒙版图片共享以CubismMaskController指定的MaskTexture为单位进行共享。
可以创建多个MaskTexture,即使模型是同一类型,如果MaskTexture指定不同,它们也会分开使用。
您不能在单个模型中使用多个MaskTexture。

可以通过改变MaskTexture的Subdivisions项来变更每个纹理处理的蒙版数量。
Subdivisions的值是各轴处理的蒙版数量,处理的蒙版数量变化如下表所示。

Subdivisions12345
蒙版数量416642561024

标准情况下,没有根据处理的蒙版数量调整Subdivisions的功能。
使用需要精细蒙版的模型时要小心。

上图是Unity中使用的GlobalMaskTexture的RenderTexture与模型一起绘制的内容。
右下的黑色部分是绘制的RenderTexture,从左下到上的顺序如下。

Mark1的眼睛、Mark1的眼睛、Mark1的嘴巴、名执的眼镜、
名执的右眼、名执的左眼、Mark2的眼睛、Mark2的眼睛、
Mark2的嘴巴

合并从同一图形网格生成的蒙版。
它不是查看用于蒙版的编号,而是将其与副本化的Drawable物体进行比较。
因此,即使模型数据相同,如果存在多个副本,蒙版也会按副本数所消耗。

当达到蒙版的上限时,蒙版将应用于整个表面,并且显示从执行时最慢的注册顺序消失。

此外,因为它的形状是一个包括要添加蒙版的一侧的正方形,所以它具有即使在大的图形网格上用小的图形网格进行蒙版时也不容易变形的特性。

* 制作AssetBundle的注意事项

有一个规范是GlobalMaskTexture的RenderTexture转换为AssetBundle时不释放。
要防止内存记忆泄漏,请参考教程“使用AssetBundle中的模型时的内存记忆泄漏及其解决方法”

Cubism SDK for Native、Cubism SDK for Web、Cubism SDK for Java

Cubism SDK for Native、Cubism SDK for Web和Cubism SDK for Java中的蒙版在每个模型的开头进行准备。
详见“蒙版前处理方法”

由于Cubism SDK for Native、Cubism SDK for Web和Cubism SDK for Java对于每个模型只有模型中的绘制顺序的绘制功能,因此每个模型都进行了蒙版共享。
与Unity一样,相同的蒙版被合并。仅通过Drawable编号进行比较。
最多可处理36个蒙版,大小根据蒙版数量自动调整。

上图是Cubism SDK for Native的剪贴纹理水平图。(使用Cubism SDK for Web可以获得相同的结果)
请注意,与Cubism SDK for Unity不同,Cubism SDK for Native、Cubism SDK for Web和Cubism SDK for Java是上下颠倒的,颜色较深的将绘制蒙版。
绘制了Mark的右眼、左眼和嘴巴。

与Cubism SDK for Unity不同,它生成为包含添加蒙版一侧的矩形,因此不受相邻蒙版缓冲区的影响。
因此,在分割数多的情况下,在大的图形网格被小蒙版覆盖的模型中,蒙版区域可能被压碎并且可能影响绘制结果。
将小蒙版应用于多个图形网格时也是如此。
如果蒙版区域被压碎,可以通过增加蒙版缓冲区的大小来改善。
(参考:蒙版缓冲区的动态大小变更)

Cubism SDK for Native和Cubism SDK for Java中还拥有换取性能以使用高清蒙版的功能。
有关启用高清蒙版的信息,请参考“蒙版前处理方法(Native) – 将蒙版处理切换为高清方法”或“蒙版前处理方法(Java) – 将蒙版处理切换为高清方法”。

绘制顺序管理

Cubism SDK for Unity

在Cubism SDK for Unity中,绘制顺序由Unity功能和脚本管理。

有四种方法。主要有两种方法。

·Z调整(Back To Front Z、Front To Back Z)

是在模型中移动Drawable的Z位置,通过Z排序来修正绘制顺序的方法。
如果相机设置为Perspective、或模型的Tramsform旋转,则显示可能会失真。
如果将其旋转180度,则绘制顺序将反转。
所有Drawable的绘制顺序都是相同的。

·Order调整(Back To Front Order,Front To Back Order)

是通过逐个移位来修正模型中Drawable绘制顺序的方法。
显示不会受到相机设置或模型旋转的干扰。即使在背面,面向相机的绘制顺序也是相同的。
如果CubismRenderController的Order In Layer对各模型都不够用时,
绘制顺序混杂,会处于精细切换的状态。
如果DrawCall增加或显示位置被覆盖,则显示可能与Drawable混合。

相反,您可以通过在模型的绘制中插入Unity物体等,使其看起来像拥有物体。

Cubism SDK for Native、Cubism SDK for Web、Cubism SDK for Java

在Cubism SDK for Native、Cubism SDK for Web和Cubism SDK for Java中,绘制顺序是按照与模型关联的Renderer的内容排序的。

// Cubism SDK for Native
void CubismRenderer_OpenGLES2::DoDrawModel()
{
  ・
  ・
  ・
    const csmInt32 drawableCount = GetModel()->GetDrawableCount();
    const csmInt32* renderOrder = GetModel()->GetDrawableRenderOrders();
 
    // 按绘制顺序排序索引
    for (csmInt32 i = 0; i < drawableCount; ++i)
    {
        const csmInt32 order = renderOrder[i];
        _sortedDrawableIndexList[order] = i;
    }
 
    // 绘制
    for (csmInt32 i = 0; i < drawableCount; ++i)
    {
        const csmInt32 drawableIndex = _sortedDrawableIndexList[i];
 
		・
        ・(中略)
        ・
 
        DrawMesh(
            GetModel()->GetDrawableTextureIndices(drawableIndex),
            GetModel()->GetDrawableVertexIndexCount(drawableIndex),
            GetModel()->GetDrawableVertexCount(drawableIndex),
            const_cast<csmUint16*>(GetModel()->GetDrawableVertexIndices(drawableIndex)),
            const_cast<csmFloat32*>(GetModel()->GetDrawableVertices(drawableIndex)),
            reinterpret_cast<csmFloat32*>(const_cast<Core::csmVector2*>(GetModel()->GetDrawableVertexUvs(drawableIndex))),
            GetModel()->GetDrawableOpacity(drawableIndex),
            GetModel()->GetDrawableBlendMode(drawableIndex)
        );
    }
}
// Cubism SDK for Web
public doDrawModel(): void {
  ・
  ・
  ・
  const drawableCount: number = this.getModel().getDrawableCount();
  const renderOrder: Int32Array = this.getModel().getDrawableRenderOrders();
 
  // 按绘制顺序排序索引
  for (let i = 0; i < drawableCount; ++i) {
    const order: number = renderOrder[i];
    this._sortedDrawableIndexList.set(order, i);
  }
 
  // 绘制
  for (let i = 0; i < drawableCount; ++i) {
    const drawableIndex: number = this._sortedDrawableIndexList.at(i);
 
    ・
    ・(中略)
    ・
 
    this.drawMesh(
      this.getModel().getDrawableTextureIndices(drawableIndex),
      this.getModel().getDrawableVertexIndexCount(drawableIndex),
      this.getModel().getDrawableVertexCount(drawableIndex),
      this.getModel().getDrawableVertexIndices(drawableIndex),
      this.getModel().getDrawableVertices(drawableIndex),
      this.getModel().getDrawableVertexUvs(drawableIndex),
      this.getModel().getDrawableOpacity(drawableIndex),
      this.getModel().getDrawableBlendMode(drawableIndex),
      this.getModel().getDrawableInvertedMaskBit(drawableIndex)
    );
  }
}
// SDK for Java
@Override
protected void doDrawModel() {
    ...
 
    final int drawableCount = model.getDrawableCount();
    final int[] renderOrder = model.getDrawableRenderOrders();
 
    // Sort the index by drawing order
    for (int i = 0; i < drawableCount; i++) {
        final int order = renderOrder[i];
        _sortedDrawableIndexList[order] = i;
    }
 
    // Draw process
    for (int i = 0; i < drawableCount; i++) {
        final int drawableIndex = _sortedDrawableIndexList[i];
        ...
 
        drawMeshAndroid(
            model.getDrawableTextureIndex(drawableIndex),
            model.getDrawableVertexIndexCount(drawableIndex),
            model.getDrawableVertexCount(drawableIndex),
            model.getDrawableVertexIndices(drawableIndex),
            model.getDrawableVertices(drawableIndex),
            model.getDrawableVertexUvs(drawableIndex),
            model.getMultiplyColor(drawableIndex),
            model.getScreenColor(drawableIndex),
            model.getDrawableOpacity(drawableIndex),
            model.getDrawableBlendMode(drawableIndex),
            model.getDrawableInvertedMask(drawableIndex) // Whether the mask is used inverted
        );
    }
    postDraw();
}

显示不会在模型之间混合。
在模型之间,最先绘制的显示在后面。

动态管理

在Cubism SDK for Unity中,动态管理使用两种类型执行:Unity功能的Mecanim、以及使用Unity的Playable API的SDK的组件“CubismMotionController”。
使用Mecanim可以在图形环境中直观地设计动态组合。
使用CubismMotionController可以播放脚本中的所有动态,而无需担心状态。

在Cubism SDK for Native、Cubism SDK for Web和Cubism SDK for Java中,动态管理由Live2D端的SDK执行。
虽然会直接用代码进行操作,但也可以通过姿势功能等类似于Cubism 2.1的形式进行操作。

SDK制作动画的差异请参考“不同工作流程的动态创建差异”

关于本报道,敬请提出您的意见及要求。