Comparison of Cubism SDKs
Updated: 01/26/2023
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.
Subdivisions | 1 | 2 | 3 | 4 | 5 |
Number of masks | 4 | 16 | 64 | 256 | 1024 |
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), indexArrayBuffer, vertexArrayBuffer, uvArrayBuffer, 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.