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...