inochi-avatar
v1.0.1
Published
Simple, drop-in library for animating Inochi2D models in the browser
Maintainers
Readme
Inochi2D Fox Girl Demo
A complete WebAssembly-based Inochi2D runtime for the browser, featuring random animation and interactive controls.
Features
- ✨ Full Inochi2D
.inpmodel support in the browser - 🎭 Random animation with realistic head movement and blinking
- 🖱️ Mouse-tracking in idle mode
- 🎨 WebGL2 rendering with stencil masking support
- 🎯 Interactive controls (zoom, pan, animation modes)
- 📊 Real-time FPS counter
- 🦊 Optimized WASM binary (~500KB)
Prerequisites
Rust toolchain (stable)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | shWASM target
rustup target add wasm32-unknown-unknownTrunk (WASM bundler)
cargo install trunk
Setup
1. Get an Inochi2D Model
You need a fox girl model in .inp format. Here's how to get one:
Option A: Download Pre-made Models
- Visit Inochi Session Demo Models
- Download a model pack (they come as
.inxfiles) - Download Inochi Creator
- Open the
.inxfile in Inochi Creator - Export as
.inppuppet:File → Export → Puppet (.inp)
Option B: Use the Official Test Model
# Clone the Inox2D repo to get test assets
git clone --depth 1 https://github.com/Inochi2D/inox2d.git temp-inox2d
cp temp-inox2d/examples/render-webgl/assets/puppet.inp model/fox_girl.inp
rm -rf temp-inox2dOption C: Create Your Own
- Use Inochi Creator to rig your own character
- Export as
.inppuppet
2. Place the Model
Copy your .inp file to:
inochi-fox-demo/model/fox_girl.inpThe file MUST be named fox_girl.inp or update the fetch path in index.html line 207.
Building & Running
Development Mode (with hot reload)
trunk serve --openThis will:
- Compile Rust to WASM
- Bundle all assets
- Start a dev server at
http://127.0.0.1:8080 - Open your browser automatically
- Watch for file changes and hot-reload
Production Build
trunk build --releaseOutput goes to dist/ folder. Deploy this to any static hosting:
# Example: Python HTTP server
cd dist
python3 -m http.server 8080
# Example: Deploy to GitHub Pages, Netlify, Vercel, etc.
# Just upload the dist/ folderUsage
Controls
- Random Animation - Randomized head movement and blinking
- Idle Pose - Subtle breathing, mouse-tracking head movement
- Zoom In/Out - Adjust camera scale
- Reset Camera - Return to default view
Mouse Interaction (Idle Mode)
In idle mode, move your mouse over the canvas to make the character follow your cursor!
Customizing Animation
Edit the animation parameters in index.html:
// In updateRandomAnimation() function
targetYaw = (Math.random() - 0.5) * 1.2; // Horizontal head range
targetPitch = (Math.random() - 0.5) * 0.8; // Vertical head range
blinkTimer = 2 + Math.random() * 4; // Blink frequencyAvailable Parameter Names
The exact parameter names depend on your model's rigging. Common ones:
Head:: Yaw-Pitch- 2D head rotationEye::Blink- Eye closureBody:: Yaw- Body rotationEye:: Look- Eye direction
Check the browser console on load to see all available parameters for your specific model.
Architecture
┌─────────────────────────────────────┐
│ JavaScript (index.html) │
│ - Animation logic │
│ - User interaction │
│ - requestAnimationFrame loop │
└──────────────┬──────────────────────┘
│ wasm-bindgen FFI
┌──────────────▼──────────────────────┐
│ Rust WASM (lib.rs) │
│ - InoxModel wrapper │
│ - Parameter API │
│ - Frame lifecycle management │
└──────────────┬──────────────────────┘
│
┌──────────────▼──────────────────────┐
│ Inox2D Core (inox2d crate) │
│ - INP parsing │
│ - Parameter system │
│ - Physics simulation │
│ - Mesh deformation │
└──────────────┬──────────────────────┘
│
┌──────────────▼──────────────────────┐
│ Inox2D OpenGL (inox2d-opengl) │
│ - Renderer via glow │
│ - WebGL2 context │
│ - Shader management │
└─────────────────────────────────────┘File Structure
inochi-fox-demo/
├── Cargo.toml # Rust dependencies
├── .cargo/
│ └── config.toml # WASM target config
├── src/
│ └── lib.rs # Rust WASM bindings
├── index.html # HTML + embedded JavaScript
├── model/
│ └── fox_girl.inp # Your Inochi2D model (YOU PROVIDE THIS)
├── dist/ # Build output (generated)
│ ├── index.html
│ ├── inochi-fox-demo.js
│ └── inochi-fox-demo_bg.wasm
└── README.md # This fileTroubleshooting
"Failed to load model: 404"
- Make sure
model/fox_girl.inpexists - Check the browser console for the exact path being fetched
- If using a different filename, update
index.htmlline 207
"Failed to get WebGL2 context"
- Your browser doesn't support WebGL2
- Try Chrome, Firefox, or Safari (recent versions)
- Check WebGL2 support
Black canvas / No rendering
- Check browser console for errors
- The model might not have the expected parameter names
- Try a different model
Parameters don't work
- Different models have different parameter names
- Check the "Available Parameters" section in the UI
- Update the animation code to match your model's parameters
Build fails
- Run
cargo cleanthen try again - Make sure you have the WASM target:
rustup target add wasm32-unknown-unknown - Update Rust:
rustup update
Performance
Typical performance on a modern browser:
- Load time: 1-2 seconds (including model parsing)
- WASM size: ~500KB (release build)
- FPS: 60fps on most devices
- Frame time: 5-10ms (depends on model complexity)
API Reference
Rust (InoxModel)
// Constructor
InoxModel::new(bytes: &[u8], canvas_id: &str) -> Result<InoxModel, JsValue>
// Parameters
set_parameter(name: &str, value: f32) -> Result<(), JsValue>
set_parameter_2d(name: &str, x: f32, y: f32) -> Result<(), JsValue>
get_parameter_names() -> Vec<JsValue>
// Frame lifecycle
begin_frame()
end_frame(delta_time: f32)
draw()
// Camera
set_camera_scale(scale: f32)
set_camera_position(x: f32, y: f32)
resize(width: u32, height: u32)
// Metadata
get_name() -> String
get_author() -> StringJavaScript
import init, { InoxModel } from './inochi-fox-demo.js';
await init(); // Initialize WASM
const bytes = new Uint8Array(await (await fetch('model.inp')).arrayBuffer());
const model = new InoxModel(bytes, 'canvas-id');
// Animation loop
function animate() {
model.begin_frame();
model.set_parameter_2d('Head:: Yaw-Pitch', x, y);
model.end_frame(deltaTime);
model.draw();
requestAnimationFrame(animate);
}License
This demo code is provided as-is for educational purposes.
The Inox2D library is licensed under BSD-2-Clause.
Resources
- Inox2D GitHub
- Inochi2D Documentation
- Inochi Creator
- Example Models
- Trunk Documentation
- wasm-bindgen Guide
Credits
- Inox2D: Rust implementation by the Inochi2D team
- Inochi2D: Original D implementation by Luna the Foxgirl
- Built with ❤️ using Rust and WebAssembly
