Comparison of Cubism SDKs

Updated: 10/06/2022

  Cubism SDK for Unity Cubism SDK for Native Cubism SDK for Web Cubism SDK for Java
Mask sharing Share MaskTexture specified in CubismMaskController Use mask textures shared only within the model Same as the details in the Cubism SDK for Native column Same as the details in the Cubism SDK for Native column
Number of masks 64 masks by default 36 masks by default
Note: Limitations can be removed by enabling the high-definition mask.
See “Mask Preprocessing Method (Native)” for details.
36 masks by default 36 masks by default
Note: Limitations can be removed by enabling the high-definition mask.
See “Mask Preprocessing Method (Java)” for details.
How to remove the mask Fixed mask size
Compose a square that can encompass the masking side
Automatic resizing
Compose a rectangle that can encompass the side to be masked
and that fills the mask shape
Same as the details in the Cubism SDK for Native column Same as the details in the Cubism SDK for Native column
Drawing method Draw order (ascending descending), Z value (ascending descending) Only in ascending order of draw order Same as the details in the Cubism SDK for Native column Same as the details in the Cubism SDK for Native column
OW pose function Available (R11 beta1-) Available Same as the details in the Cubism SDK for Native column Same as the details in the Cubism SDK for Native column
OW expression function Available (R11 beta1-) Available Same as the details in the Cubism SDK for Native column Same as the details in the Cubism SDK for Native column
Motion management Convert Unity motion3.json to AnimationClip and
perform motion management with Mecanim
Performing motion management with Cubism SDK for Native Performing motion management with Cubism SDK for Web Performing motion management with Cubism SDK for Java
Languages used by the SDK C# C++ Type Script Java
Live2D placement In the GUI In the code Same as the details in the Cubism SDK for Native column Same as the details in the Cubism SDK for Native column
Destination platforms Windows, macOS, iOS, Android, WebGL,
PlayStation 4, Nintendo Switch
Windows, macOS, Linux, iOS, Android,
PlayStation 4, Nintendo Switch
Web browser Android

Difference in Mask Characteristics

Cubism SDK for Unity

In Unity, mask images are shared on a MaskTexture basis as specified in the CubismMaskController.
Multiple MaskTextures can be created, and even models of the same type will be used separately if different MaskTextures are specified.
It is not possible to use multiple MaskTextures within a single model.

The number of masks handled per texture can be changed by changing the Subdivisions item in MaskTexture.
The value of Subdivisions is the number of masks handled per axis, and the number of masks handled varies as shown in the table below.

Subdivisions12345
Number of masks416642561024

There is no standard function to adjust Subdivisions for the number of masks handled.
Care should be taken when working with models that require detailed masks.

The image above shows a GlobalMaskTexture’s RenderTexture used in Unity, drawn with the model.
The black area in the lower right is the RenderTexture drawn, and the sequence is as follows from the lower left to the top.

Mark1’s eye, Mark1’s eye, Mark1’s mouth, Natori’s glasses,
Natori’s right eye, Natori’s left eye, Mark2’s eye, Mark2’s eye ,
and Mark2’s mouth

Masks generated from the same ArtMesh are merged.
This is because the system is not looking at the number used for the mask, but comparing it with the instantiated Drawable object.
Therefore, if there are multiple instances of the same model data, the mask is consumed only by the number of instances.

When the mask limit is reached, the mask is applied to the entire surface, starting from the one registered latest, and disappears from the display.

Also, since the shape is taken by a square that encompasses the side to be masked, it is difficult to distort a large ArtMesh by masking it with a small ArtMesh.

Note: Caution when converting to AssetBundle

There is a specification that the RenderTexture of GlobalMaskTexture is not released when it is converted to AssetBundle.
To avoid memory leaks, check the tutorial “Memory Leak Problems and Countermeasures When Using Models from AssetBundle.”

Cubism SDK for Native, Cubism SDK for Web, and Cubism SDK for Java

Masks in Cubism SDK for Native, Cubism SDK for Web, and Cubism SDK for Java are prepared at the beginning of each model.
See “Mask Preparation Method” for details.

Since Cubism SDK for Native, Cubism SDK for Web, and Cubism SDK for Java only have the ability to draw each model in the order in which it is drawn in the model, masks are shared on a per-model basis.
Like Unity, identical masks will be integrated. Comparisons are made only by Drawable number.
The maximum number of masks handled is 36, and the size is automatically adjusted according to the number of masks.

The above image shows a clipping texture from Cubism SDK for Native drawn horizontally. (Similar results are obtained with Cubism SDK for Web.)
Note that in Cubism SDK for Native, Cubism SDK for Web, and Cubism SDK for Java , unlike Cubism SDK for Unity, the top and bottom are reversed and the darker mask is drawn.
The three images depicted are Mark’s right eye, left eye, and mouth.

Unlike in the Cubism SDK for Unity, the masked is generated as a rectangle that contains the side to be masked so that it is not affected by adjacent mask buffers.
Therefore, in a model where a large ArtMesh with many segments is covered by a small mask, the mask area may be collapsed and the drawing result may be affected.
The same is true when a small mask is applied to multiple ArtMeshes that are separated from each other.
If the mask area is crushed, increasing the size of the mask buffer may improve the problem.
(Ref.: Dynamic resizing of mask buffer)

Cubism SDK for Native and Cubism SDK for Java also offer the ability to use high-definition masks in exchange for performance.
See “Mask Preprocessing Methods (Native) # Switching to a high-definition method for processing masks” or “Mask Pretreatment Method (Java) # Switching to a high-definition method for processing masks” for information about enabling high-definition masks.

Draw Order Management

Cubism SDK for Unity

Cubism SDK for Unity uses Unity functions and scripts to manage the draw order.

There are four methods. There are two main methods.

• Z adjustment (Back To Front Z, Front To Back Z)

This is a method of shifting the Z position of a Drawable in a model and modifying the draw order by Z-sorting.
If the camera is set to Perspective or the model’s Transform is rotated, the display may be distorted.
Rotating 180 degrees reverses the draw order.
The same draw order is applied to all Drawables.

• Order adjustment (Back To Front Order, Front To Back Order)

This is a method of modifying the order in which the draw order of Drawable in the model is shifted itself one by one.
The display is not disturbed by camera settings or model rotation. Even on the reverse side, the draw order is the same toward the camera.
If the Order In Layer of the CubismRenderController is not sufficiently empty for each model,
the draw order is mixed and the displayed images are switched multiple times with unexpected timing.
If the number of DrawCalls increases or their display position is covered, the Drawable may be displayed in a mixed state.

Conversely, by inserting Unity objects or other objects into the drawing of the model, it can be made to appear as if the model has objects.

Cubism SDK for Native, Cubism SDK for Web, and Cubism SDK for Java

Cubism SDK for Native, Cubism SDK for Web, and Cubism SDK for Java sort the draw order according to the contents of the Renderer associated with the model.

// Cubism SDK for Native
void CubismRenderer_OpenGLES2::DoDrawModel()
{
  ・
  ・
  ・
    const csmInt32 drawableCount = GetModel()->GetDrawableCount();
    const csmInt32* renderOrder = GetModel()->GetDrawableRenderOrders();
 
    // Sort index by draw order.
    for (csmInt32 i = 0; i < drawableCount; ++i)
    {
        const csmInt32 order = renderOrder[i];
        _sortedDrawableIndexList[order] = i;
    }
 
    // Draw.
    for (csmInt32 i = 0; i < drawableCount; ++i)
    {
        const csmInt32 drawableIndex = _sortedDrawableIndexList[i];
 
		・
        • (Omitted)
        ・
 
        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();
 
  // Sort index by draw order.
  for (let i = 0; i < drawableCount; ++i) {
    const order: number = renderOrder[i];
    this._sortedDrawableIndexList.set(order, i);
  }
 
  // Draw.
  for (let i = 0; i < drawableCount; ++i) {
    const drawableIndex: number = this._sortedDrawableIndexList.at(i);
 
    ・
    • (Omitted)
    ・
 
    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();
}

Displays are not mixed between models.
Between models, the one drawn first is displayed behind.

Manage Motion

The Cubism SDK for Unity manages motion using two types of components: Mecanim, a Unity function, and “CubismMotionController,” a component included with the SDK that uses Unity’s Playable API.
Mecanim allows you to design motion combinations visually in a graphical environment.
CubismMotionController allows you to play back all motions from scripts without worrying about their state.

In Cubism SDK for Native, Cubism SDK for Web, and Cubism SDK for Java, motion management is performed by the SDK on the Live2D side.
Although the operation is done directly by code, it is similar to Cubism 2.1, such as the pose function.

See “Differences in Motion Creation with SDKs” for more information on motion-related differences between SDKs.

Please let us know what you think about this article.