English (Current) | 简体中文 | 日本語
A Live2D rendering engine for PixiJS v8, supporting Cubism 2 / 3 / 4 / 5 models.
This project is a major refactor of pixi-live2d-display-mulmotion, adapted for PixiJS v8 and Cubism 5 SDK with improvements to API design, rendering pipeline, and type safety.
Registers a custom Render Pipe with extensions.add(Live2DPlugin) to integrate with the PixiJS v8 rendering architecture:
- Supports
FilterandRenderTexture - Participates in zIndex sorting and blend modes
- Inherits renderer resolution — filters won't blur due to downsampling
Works with both Cubism 2.1 (Legacy) and Cubism 5 (Modern), with separate bundle entries to import the corresponding runtime as needed.
For large texture atlases (4096px+), three LOD strategies are available:
full(default): generates a full mipmap chainsingle-auto: generates a lower-resolution texture on demand based on the model's actual screen size, reducing VRAM usagefalse: uses the original texture only
const model = await Live2DModel.from('model.json', {
textureOptions: { lod: 'single-auto' }
})Complex models (many masked drawables, high vertex density, etc.) can produce visual artifacts when mask precision is insufficient. The engine automatically analyzes the model structure and enables high-precision masks when needed. This is enabled by default and can also be controlled manually.
- Parallel playback: drive multiple motion groups simultaneously, useful for independent upper/lower body animations
- Last-frame freeze: hold a motion on its final frame, useful for pose switching or static illustrations
- Loop override: set
loopper parallel motion item to override Cubism 3/4/5 motion JSON loop metadata
// Parallel playback
model.parallelMotion([
{ group: 'upper_body', index: 0 },
{ group: 'lower_body', index: 1, loop: true }
])
// Last-frame freeze
await model.parallelLastFrame([
{ group: 'arm', index: 0 },
{ group: 'expression', index: 2 }
])- Cubism 2 / 3 / 4 / 5 model support
- Native PixiJS v8 rendering pipeline (Filter / RenderTexture / Render Pipe)
- Texture LOD and automatic high-precision mask detection
- Parallel motion playback / last-frame freeze
- Real-time lip sync
- PixiJS-style transforms:
position/scale/rotation/skew/anchor - Mouse tracking / hit area detection
- Improved motion reservation and priority scheduling
- Strict TypeScript type definitions
- Configurable Cubism work memory size
- PixiJS:
8.x - Cubism runtime:
2.1or5 - Browser: must support
WebGLandES6
pnpm add untitled-pixi-live2d-engine
# or
npm install untitled-pixi-live2d-engineimport { Live2DModel, Live2DPlugin } from 'untitled-pixi-live2d-engine'
// Cubism Legacy only (Cubism 2.1)
import { Live2DModel } from 'untitled-pixi-live2d-engine/cubism-legacy'
// Cubism Modern only (Cubism 3 / 4 / 5)
import { Live2DModel } from 'untitled-pixi-live2d-engine/cubism'<script src="https://cdn.jsdelivr.net/npm/untitled-pixi-live2d-engine/dist/index.min.js"></script>@pixi/sound is optional. Load it before this package only when using motion sounds, model.speak(), or lip sync:
<script src="https://cdn.jsdelivr.net/npm/pixi.js@8/dist/pixi.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@pixi/sound@6/dist/pixi-sound.js"></script>
<script src="https://cdn.jsdelivr.net/npm/untitled-pixi-live2d-engine/dist/index.min.js"></script>If your app does not use audio features, you can omit pixi-sound.js.
Live2D models are split into two categories by Cubism architecture, each requiring a different external runtime:
| Category | Model Version | External Runtime | Bundle Entry |
|---|---|---|---|
| Cubism Legacy | Cubism 2.1 | live2d.min.js |
cubism-legacy.js |
| Cubism Modern | Cubism 3 / 4 / 5 | live2dcubismcore.min.js |
cubism.js |
| Both | — | Both of the above | index.js |
Cubism Legacy — live2d.min.js
Official distribution was discontinued on September 4, 2019. Available from:
Cubism Modern — live2dcubismcore.min.js
Download from the official Cubism 5 SDK for Web.
The following example uses PixiJS v8 and supports both Cubism Legacy and Cubism Modern.
import { Application, extensions } from 'pixi.js'
import { configureCubismSDK, Live2DModel, Live2DPlugin } from 'untitled-pixi-live2d-engine'
// Register the Live2D render pipe before creating the Pixi renderer
extensions.add(Live2DPlugin)
const app = new Application()
await app.init({
resizeTo: window,
preference: 'webgl',
autoDensity: true,
resolution: window.devicePixelRatio
})
document.body.appendChild(app.canvas)
// Configure Cubism Modern work memory (optional, default 16MB)
// Increase when loading multiple or complex models
// configureCubismSDK({ memorySizeMB: 32 })
const model = await Live2DModel.from('model/model3.json')
model.anchor.set(0.5)
model.position.set(app.screen.width / 2, app.screen.height / 2)
app.stage.addChild(model)model.motion('group', index)model.parallelMotion([
{ group: group1, index: index1 },
{ group: group2, index: index2, loop: true }
])Single motion:
model.motionLastFrame('group', index)Multiple motions:
await model.parallelLastFrame([
{ group: group1, index: index1 },
{ group: group2, index: index2 }
])model.speak('audio_file_url')model.expression('id')When using the Cubism Modern runtime, this is usually caused by insufficient work memory. Increase memorySizeMB during initialization (minimum 16MB):
configureCubismSDK({ memorySizeMB: 32 })