GLTF - Extra texture with skinned mesh
HTML
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>My first three.js app</title>
<script type="importmap">
{
"imports": {
"three": "https://cdn.jsdelivr.net/npm/three@0.170.0/build/three.module.js",
"three/addons/": "https://cdn.jsdelivr.net/npm/three@0.170.0/examples/jsm/"
}
}
</script>
</head>
<body></body>
</html>
CSS
body {
margin: 0;
}
.renderer-info {
position: fixed;
top: 10px;
left: 10px;
color: white;
background-color: rgba(200, 200, 200, 0.5);
font-family: monospace;
font-size: 14px;
padding: 10px;
}
button {
color: white;
background-color: rgba(200, 200, 200, 0.5);
font-family: monospace;
font-size: 12px;
padding: 5px;
cursor: pointer;
}
.dispose-button {
position: fixed;
top: 10px;
right: 10px;
}
.animation-button-container {
position: fixed;
top: 60px;
right: 10px;
display: grid;
gap: 4px;
}
.add-model {
position: fixed;
top: 80px;
left: 10px;
}
JavaScript
import * as THREE from "three"
import { OrbitControls } from "three/addons/controls/OrbitControls.js"
import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js"
let model
let animationActions = new Map()
let mixer
const scene = new THREE.Scene()
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000,
)
const renderer = new THREE.WebGLRenderer()
const clock = new THREE.Clock()
const gltfLoader = new GLTFLoader()
window.renderer = renderer
renderer.setSize(window.innerWidth, window.innerHeight)
renderer.setPixelRatio(window.devicePixelRatio)
document.body.appendChild(renderer.domElement)
window.addEventListener('resize', () => {
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
})
camera.position.z = 5
const controls = new OrbitControls(camera, renderer.domElement)
controls.enableDamping = true
let animationButtonContainer = document.createElement("div")
animationButtonContainer.className = "animation-button-container"
document.body.appendChild(animationButtonContainer)
/**
* Add Model Input
*/
const addModel = document.createElement("input")
addModel.classList.add("add-model")
addModel.type = "file"
addModel.innerText = "Add Model"
document.body.appendChild(addModel)
const reader = new FileReader()
addModel.addEventListener("change", (e) => {
const file = e.target.files[0]
if (!file) {
console.warn("No file")
return
}
reader.onload = (e) => {
const result = e.target.result
if (!result) {
console.warn("No result")
return
}
gltfLoader.parse(result, "", (gltf) => {
model = gltf.scene
let animations = gltf.animations
scene.add(model)
if (animations && animations.length) {
animationButtonContainer.innerHTML = ""
mixer = new THREE.AnimationMixer(model)
animations.forEach((clip) => {
const action...