vrm-mtoon-outline
Fixes inconsistent outline thickness on VRM models by toggling between world and screen coordinate modes.
Install
mkdir -p .claude/skills/vrm-mtoon-outline && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/7176" && unzip -o skill.zip -d .claude/skills/vrm-mtoon-outline && rm skill.zipInstalls to .claude/skills/vrm-mtoon-outline
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Adjusting VRM MToon material outline thickness in three-vrm. Covers outline width modes, property access, and how to fix outlines that appear too thick when models are scaled.Key capabilities
- →Switch MToon outline width modes
- →Adjust outline thickness programmatically
- →Debug MToon material properties
- →Normalize outline thickness across scales
How it works
It traverses the VRM scene graph to identify MToon materials and modifies their outlineWidthMode and outlineWidthFactor properties to ensure consistent rendering.
Inputs & outputs
When to use vrm-mtoon-outline
- →Fixing thick outlines on scaled models
- →Normalizing outline width at different distances
- →Setting outline rendering modes programmatically
About this skill
VRM MToon Outline Thickness Adjustment
This skill covers how to adjust outline thickness for VRM models using MToon materials in @pixiv/three-vrm.
Common Symptoms
- Outline too thick when model is scaled up or camera is close
- Outline thickness inconsistent at different zoom levels
- Need to adjust outline programmatically at runtime
Key Concepts
Outline Width Modes
MToon materials have two main outline width modes:
| Mode | Description | Behavior |
|---|---|---|
'worldCoordinates' | Outline width is a physical world-space size | Outline appears thicker when model is scaled up or camera is closer |
'screenCoordinates' | Outline width is relative to screen pixels | Outline stays consistent size regardless of zoom/scale |
Critical Properties
material.outlineWidthMode // 'none' | 'worldCoordinates' | 'screenCoordinates'
material.outlineWidthFactor // Number - the actual width value
material.isMToonMaterial // Boolean - true for MToon materials
material.needsUpdate // Set to true after modifying properties
Solution: Switch to Screen Coordinates
To make outlines stay consistent regardless of zoom/scale:
function adjustOutlineThickness(vrm, screenFactor = 0.005) {
vrm.scene.traverse((object) => {
if (object.isMesh || object.isSkinnedMesh) {
const materials = Array.isArray(object.material) ? object.material : [object.material];
materials.forEach(material => {
if (!material || !material.isMToonMaterial) return;
// Check if this material has outlines enabled
const hasOutline = material.outlineWidthFactor > 0 &&
material.outlineWidthMode !== 'none';
if (hasOutline) {
// Switch to screen coordinates mode
material.outlineWidthMode = 'screenCoordinates';
material.outlineWidthFactor = screenFactor;
material.needsUpdate = true;
}
});
}
});
}
Factor Value Guidelines
For screenCoordinates mode:
| Factor Value | Approximate Effect |
|---|---|
0.002 - 0.003 | Very thin outline (1 pixel) |
0.005 | Thin outline (1-2 pixels) |
0.01 | Medium outline (2-3 pixels) |
0.02+ | Thick outline |
Detection Pattern
To diagnose outline issues, log all materials:
function debugOutlineMaterials(vrm) {
let count = 0;
vrm.scene.traverse((object) => {
if (!object.isMesh && !object.isSkinnedMesh) return;
const materials = Array.isArray(object.material) ? object.material : [object.material];
materials.forEach(material => {
if (material?.isMToonMaterial || 'outlineWidthFactor' in material) {
count++;
console.log({
name: material.name || '未命名',
type: material.type,
isMToonMaterial: material.isMToonMaterial,
outlineWidthMode: material.outlineWidthMode,
outlineWidthFactor: material.outlineWidthFactor
});
}
});
});
console.log(`Found ${count} MToon/Outline materials`);
}
Important Notes
[!IMPORTANT] Call timing matters! The function must be called AFTER
currentModelis set. Invrm-core.js, theloadModel()function setsmanager.currentModelnear line 923. Any function that accessescurrentModelmust be called after this point.
[!NOTE] Materials named
"XXX (Outline)"are outline pass materials automatically created by three-vrm. They share properties with the main material but render the outline effect.
API Reference (three-vrm MToon)
The enum values for outlineWidthMode:
// From three-vrm.module.min.js
{
None: "none",
WorldCoordinates: "worldCoordinates",
ScreenCoordinates: "screenCoordinates"
}
| Property | Type | Description |
|---|---|---|
outlineWidthMode | string | Width calculation mode |
outlineWidthFactor | number | Width value (meaning depends on mode) |
outlineColorFactor | Color | Outline color |
outlineLightingMixFactor | number | How much lighting affects outline |
outlineWidthMultiplyTexture | Texture | Texture to modulate outline width |
When not to use it
- →Adjusting non-MToon material outlines
- →General 3D model scaling tasks
Prerequisites
Limitations
- →Must be called after the model is loaded
- →Only affects MToon materials
How it compares
It automates the correction of outline thickness issues that occur when models are scaled, which is a manual process in standard three.js workflows.
Compared to similar skills
vrm-mtoon-outline side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| vrm-mtoon-outline (this skill) | 1 | 6mo | No flags | Intermediate |
| scroll-experience | 101 | 6mo | No flags | Intermediate |
| anthropic-frontend-design | 12 | 6mo | No flags | Intermediate |
| threejs-postprocessing | 1 | 6mo | No flags | Intermediate |
Try saying
Example prompts that trigger this skill in your AI assistant.
More by Project-N-E-K-O
View all by Project-N-E-K-O →You might also like
scroll-experience
davila7
Expert in building immersive scroll-driven experiences - parallax storytelling, scroll animations, interactive narratives, and cinematic web experiences. Like NY Times interactives, Apple product pages, and award-winning web experiences. Makes websites feel like experiences, not just pages. Use when: scroll animation, parallax, scroll storytelling, interactive story, cinematic website.
anthropic-frontend-design
chaibuilder
Create distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, artifacts, posters, or applications (examples include websites, landing pages, dashboards, React components, HTML/CSS layouts, or when styling/beautifying any web UI). Generates creative, polished code and UI design that avoids generic AI aesthetics.
threejs-postprocessing
CloudAI-X
Three.js post-processing - EffectComposer, bloom, DOF, screen effects. Use when adding visual effects, color grading, blur, glow, or creating custom screen-space shaders.
snapdom
2025Emma
snapDOM is a fast, accurate DOM-to-image capture tool that converts HTML elements into scalable SVG images. Use for capturing HTML elements, converting DOM to images (SVG, PNG, JPG, WebP), preserving styles, fonts, and pseudo-elements.
frontend-ui-engineering
charlieviettq
Build and refine web UI—component structure, responsive layout, design tokens, state, and accessibility. Use for feature UI work beyond WCAG checks alone.
guest-list-ui
robertschaub
Use when changing guest-list features, German UI text, mobile check-in workflow, CSV import/export, filtering/search, dashboard totals, accessibility, or responsive UI in the static app.