Mii body, accurate scaling, shaders, shadow, head from glTF
by arian_
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
body {
margin: 0;
overflow: hidden;
}
canvas {
display: block;
}
.floating {
position: absolute;
top: 10px;
left: 10px;
}
#ui {
background: rgba(255, 255, 255, 0.8);
padding: 10px;
border-radius: 4px;
font-family: Arial, sans-serif;
z-index: 1;
resize: both;
overflow: hidden;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);
width: 180px;
}
#ui input,
#ui button,
#ui label,
#ui select {
display: block;
margin: 5px 0;
width: 100%;
}
.controls {
display: flex;
justify-content: space-between;
align-items: center;
}
.hint {
font-size: 12px;
color: gray;
word-wrap: break-word;
}
</style>
<script type="importmap">
{
"imports": {
"three": "https://esm.sh/[email protected]",
"three/": "https://esm.sh/[email protected]/",
"./FFL.js/": "https://esm.sh/*gh/ariankordi/[email protected]/"
}
}
</script>
</head>
<body>
<!-- UI container. -->
<div id="uiContainer">
<button id="showUiButton" class="floating" type="button" style="display: none;">Show UI</button>
<!-- This is the floating options box. -->
<div id="ui" class="floating">
<form id="modelForm">
<!-- URL and options. -->
<div class="controls">
<label for="modelUrl">Head URL:</label>
<select id="shaderSelector">
<option selected>FFLShaderMaterial</option>
<option>LUTShaderMaterial</option>
<option>SampleShaderMaterial</option>
<option>NigaoeShaderMaterial</option>
</select>
<button id="hideUiButton" type="button">Hide UI</button>
</div>
<input type="text" id="modelUrl"
value="https://mii-unsecure.ariankordi.net/miis/image.glb?nnid=JasmineChlora&texResolution=256&resourceType=middle">
<small...
JavaScript
/*!
* @file Mii rendering with body, accurate scaling,
* all shaders, shadow, and head model from glTF.
*
* Uses SkeletonScalingExtensions to support body scaling by extending THREE.Skeleton.
* Definitions for how to scale each body model are in ModelScaleDesc.js.
* Shader material classes are included (as UMD) from FFL.js.
*
* Mii head models are consumed from glTFs made from
* mii-unsecure.ariankordi.net/FFL-Testing GLTFExportCallback.
* This was also made with the goal to hopefully be
* flexible enough to accept Mii head models from FFL.js.
*
*
* Snippet originally published on jsfiddle.net: https://jsfiddle.net/arian_/egmvt5o9/1/
* Code to achieve accurate Mii body scaling has been initially
* reverse engineered/decompiled from nn::mii::VariableIconBody
* by me, implemented in C++ here: https://github.com/ariankordi/FFL-Testing/blob/renderer-server-prototype/src/BodyModel.cpp
*
* **Please credit me if you use any portion of this.**
*
* @author Arian Kordi <https://github.com/ariankordi>
*/
// @ts-check
import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'; // Optional.
// Dependencies for body scaling.
import * as SkeletonUtils from 'three/examples/jsm/utils/SkeletonUtils.js';
import { addSkeletonScalingExtensions } from './FFL.js/helpers/SkeletonScalingExtensions.js';
import { detectModelDesc, applyScaleDesc } from './FFL.js/helpers/ModelScaleDesc.js';
// Material classes.
import FFLShaderMaterial from './FFL.js/materials/FFLShaderMaterial.js';
import LUTShaderMaterial from './FFL.js/materials/LUTShaderMaterial.js';
import SampleShaderMaterial from './FFL.js/materials/SampleShaderMaterial.js';
import NigaoeShaderMaterial from './FFL.js/materials/NigaoeShaderMaterial.js';
/**
* Imports for standalone JSDoc types:
* @typedef...