update three-vrm-3
This commit is contained in:
1
min-ts/dist/CNAME
vendored
Normal file
1
min-ts/dist/CNAME
vendored
Normal file
@ -0,0 +1 @@
|
||||
vrm.syui.ai
|
94
min-ts/dist/css/style.css
vendored
Normal file
94
min-ts/dist/css/style.css
vendored
Normal file
@ -0,0 +1,94 @@
|
||||
body {
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
progress {
|
||||
width: 100%;
|
||||
height:8px;
|
||||
position: absolute;
|
||||
border-radius: 0px;
|
||||
}
|
||||
|
||||
::-webkit-progress-bar {
|
||||
border-radius: 0px;
|
||||
background-color: #e6e6fa;
|
||||
}
|
||||
|
||||
::-webkit-progress-value {
|
||||
background-color: #4682b4;
|
||||
}
|
||||
|
||||
::-moz-progress-bar {
|
||||
border-radius: 0px;
|
||||
background-color: #e6e6fa;
|
||||
}
|
||||
|
||||
::-moz-progress-value {
|
||||
background-color: #4682b4;
|
||||
}
|
||||
|
||||
::-ms-progress-bar {
|
||||
border-radius: 0px;
|
||||
background-color: #e6e6fa;
|
||||
}
|
||||
|
||||
::-ms-progress-value {
|
||||
background-color: #4682b4;
|
||||
}
|
||||
|
||||
div#menu {
|
||||
padding: 20px;
|
||||
border-bottom:solid 1px #ccc;
|
||||
}
|
||||
|
||||
button {
|
||||
border: none;
|
||||
margin: 0;
|
||||
padding: 0 20px 0 20px;
|
||||
width: auto;
|
||||
overflow: visible;
|
||||
background: transparent;
|
||||
color: inherit;
|
||||
font: inherit;
|
||||
line-height: normal;
|
||||
-webkit-font-smoothing: inherit;
|
||||
-moz-osx-font-smoothing: inherit;
|
||||
appearance: none;
|
||||
-webkit-appearance: none;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
a:hover{
|
||||
/* color: #fff700; */
|
||||
color: #847e00;
|
||||
}
|
||||
|
||||
footer {
|
||||
border-top:solid 1px #ccc;
|
||||
padding: 20px 0 20px 0;
|
||||
font-size:20px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
span.menu-nav button#nav {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media screen and (max-width:1000px) {
|
||||
span#nav-mobile {
|
||||
display: none;
|
||||
}
|
||||
span.menu-nav button#nav {
|
||||
right:0;
|
||||
display: block;
|
||||
position: absolute;
|
||||
top:20px;
|
||||
}
|
||||
}
|
BIN
min-ts/dist/favicon.ico
vendored
Normal file
BIN
min-ts/dist/favicon.ico
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
BIN
min-ts/dist/img/0.hdr
vendored
Normal file
BIN
min-ts/dist/img/0.hdr
vendored
Normal file
Binary file not shown.
10744
min-ts/dist/img/1.hdr
vendored
Normal file
10744
min-ts/dist/img/1.hdr
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
min-ts/dist/img/2.hdr
vendored
Normal file
BIN
min-ts/dist/img/2.hdr
vendored
Normal file
Binary file not shown.
BIN
min-ts/dist/img/og.png
vendored
Normal file
BIN
min-ts/dist/img/og.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 306 KiB |
21
min-ts/dist/index.html
vendored
Normal file
21
min-ts/dist/index.html
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>ai</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<meta property="og:url" content="https://vrm.syui.ai">
|
||||
<meta property="og:title" content="ai/vrm">
|
||||
<meta property="og:description" content="ai[vrm] model viewer">
|
||||
<meta property="og:image" content="/img/og.png">
|
||||
<link rel="icon" href="/favicon.ico"/>
|
||||
<link rel="stylesheet" href="/css/style.css"/>
|
||||
<link rel="stylesheet" href="https://syui.ai/bower_components/icomoon/style.css" />
|
||||
<link rel="stylesheet" href="https://syui.ai/bower_components/font-awesome/css/all.min.css" />
|
||||
<script src="main.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<progress value="0" max="100" id="progressBar"></progress>
|
||||
<div id="canvas"></div>
|
||||
<footer>© syui</footer>
|
||||
</body>
|
||||
</html>
|
120
min-ts/docs/wiki.md
Normal file
120
min-ts/docs/wiki.md
Normal file
@ -0,0 +1,120 @@
|
||||
## example three-vrm
|
||||
|
||||
- vrm : [download](https://hub.vroid.com/characters/675572020956181239/models/7175071267176594918)
|
||||
- vrma : [download](https://vroid.booth.pm/items/5512385)
|
||||
|
||||
> ./dist/vrma
|
||||
|
||||
```js
|
||||
load("/vrma/model.vrm");
|
||||
load("/vrma/VRMA_01.vrma");
|
||||
```
|
||||
|
||||
## iframe
|
||||
|
||||
```html
|
||||
<div class="vrm-model">
|
||||
<iframe src="https://vrm.syui.ai" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen scrolling="no"></iframe>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.vrm-model iframe {
|
||||
margin:30px 0 30px 0;
|
||||
width: 100%;
|
||||
height: 640px;
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
## head
|
||||
|
||||
```js
|
||||
let head = currentVrm.humanoid.getRawBoneNode("head");
|
||||
```
|
||||
|
||||
## blink
|
||||
|
||||
```js
|
||||
currentVrm.expressionManager.setValue('blink', 0);
|
||||
```
|
||||
|
||||
## bloom
|
||||
|
||||
```js
|
||||
//import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer';
|
||||
//import { UnrealBloomPass } from 'three/examples/jsm/postprocessing/UnrealBloomPass';
|
||||
//import { RenderPass } from "three/examples/jsm/postprocessing/RenderPass";
|
||||
// https://github.com/pmndrs/postprocessing
|
||||
import { BloomEffect, EffectComposer, EffectPass, RenderPass } from "postprocessing";
|
||||
|
||||
const composer = new EffectComposer(renderer);
|
||||
composer.addPass(new RenderPass(scene, camera));
|
||||
composer.addPass(new EffectPass(camera, new BloomEffect()));
|
||||
|
||||
requestAnimationFrame(function render() {
|
||||
|
||||
requestAnimationFrame(render);
|
||||
composer.render();
|
||||
|
||||
});
|
||||
```
|
||||
|
||||
## progress
|
||||
|
||||
```js
|
||||
// https://sbcode.net/threejs/progress-indicator
|
||||
let manager = new THREE.LoadingManager();
|
||||
let progressBar = document.getElementById('progressBar') as HTMLProgressElement
|
||||
|
||||
// https://threejs.org/docs/#api/en/loaders/managers/LoadingManager
|
||||
manager.onStart = function ( url, itemsLoaded, itemsTotal ) {
|
||||
//console.log( 'Started loading file: ' + url + '.\nLoaded ' + itemsLoaded + ' of ' + itemsTotal + ' files.' );
|
||||
progressBar.style.display = 'block'
|
||||
let percentComplete = (itemsLoaded / itemsTotal) * 100
|
||||
progressBar.value = percentComplete === Infinity ? 100 : percentComplete
|
||||
};
|
||||
manager.onLoad = function ( ) {
|
||||
//console.log( 'Loading complete!');
|
||||
progressBar.style.display = 'none'
|
||||
};
|
||||
manager.onProgress = function ( url, itemsLoaded, itemsTotal ) {
|
||||
let percentComplete = (itemsLoaded / itemsTotal) * 100
|
||||
progressBar.value = percentComplete === Infinity ? 100 : percentComplete
|
||||
//console.log( 'Loading file: ' + url + '.\nLoaded ' + itemsLoaded + ' of ' + itemsTotal + ' files.' );
|
||||
};
|
||||
manager.onError = function ( url ) {
|
||||
//console.log( 'There was an error loading ' + url );
|
||||
progressBar.style.display = 'block'
|
||||
};
|
||||
```
|
||||
|
||||
```html
|
||||
<progress value="0" max="100" id="progressBar"></progress>
|
||||
```
|
||||
|
||||
```css
|
||||
progress {
|
||||
width: 100%;
|
||||
height:8px;
|
||||
position: absolute;
|
||||
border-radius: 0px;
|
||||
}
|
||||
|
||||
::-webkit-progress-bar {
|
||||
border-radius: 0px;
|
||||
background-color: #e6e6fa;
|
||||
}
|
||||
|
||||
::-webkit-progress-value {
|
||||
background-color: #4682b4;
|
||||
}
|
||||
```
|
||||
|
||||
## link
|
||||
|
||||
- https://vrm.dev/
|
||||
- https://threejs.org/docs/
|
||||
- https://github.com/pixiv/three-vrm
|
||||
- https://github.com/vrm-c/vrm-specification/blob/master/specification/
|
||||
- https://github.com/pmndrs/postprocessing
|
||||
|
23
min-ts/package.json
Normal file
23
min-ts/package.json
Normal file
@ -0,0 +1,23 @@
|
||||
{
|
||||
"name": "vrm",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "webpack",
|
||||
"dev": "webpack-dev-server --open"
|
||||
},
|
||||
"devDependencies": {
|
||||
"ts-loader": "^9.5.1",
|
||||
"typescript": "^5.4.2",
|
||||
"webpack": "^5.90.3",
|
||||
"webpack-cli": "^5.1.4",
|
||||
"webpack-dev-server": "^5.0.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@pixiv/three-vrm": "^3.0.0",
|
||||
"@pixiv/three-vrm-animation": "^3.0.0",
|
||||
"@pixiv/three-vrm-springbone": "^3.0.0",
|
||||
"postprocessing": "^6.35.2",
|
||||
"three": "^0.167.1"
|
||||
}
|
||||
}
|
123
min-ts/src/index.ts
Normal file
123
min-ts/src/index.ts
Normal file
@ -0,0 +1,123 @@
|
||||
import * as THREE from "three"
|
||||
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader"
|
||||
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
|
||||
import { VRMLoaderPlugin } from "@pixiv/three-vrm";
|
||||
import { createVRMAnimationClip, VRMAnimationLoaderPlugin } from "@pixiv/three-vrm-animation";
|
||||
import { GridHelper, Mesh, MeshLambertMaterial, BoxGeometry, Vector3, Vector2, Color, DirectionalLight, Fog, HemisphereLight, HalfFloatType } from 'three';
|
||||
import { BloomEffect, EffectComposer, EffectPass, RenderPass } from "postprocessing";
|
||||
|
||||
window.addEventListener("DOMContentLoaded", () => {
|
||||
|
||||
let manager = new THREE.LoadingManager();
|
||||
const canvas = document.getElementById("canvas");
|
||||
if (canvas == null) return;
|
||||
const scene = new THREE.Scene();
|
||||
const camera = new THREE.PerspectiveCamera( 70, canvas.clientWidth/canvas.clientHeight, 0.1, 2000);
|
||||
camera.position.set(0, 1.5, -1.5)
|
||||
camera.rotation.set(0.0, Math.PI, 0.0)
|
||||
camera.lookAt(new THREE.Vector3(0, 0, 0));
|
||||
|
||||
const renderer = new THREE.WebGLRenderer({
|
||||
alpha: true,
|
||||
powerPreference: "high-performance",
|
||||
antialias: true,
|
||||
stencil: false,
|
||||
});
|
||||
renderer.setPixelRatio(window.devicePixelRatio);
|
||||
renderer.setSize(canvas.clientWidth, canvas.clientHeight);
|
||||
renderer.outputColorSpace = THREE.SRGBColorSpace;
|
||||
renderer.toneMapping = THREE.ReinhardToneMapping;
|
||||
renderer.toneMapping = THREE.NeutralToneMapping;
|
||||
canvas.appendChild(renderer.domElement);
|
||||
renderer.toneMappingExposure = 1.5;
|
||||
renderer.setClearColor(0xffffff, 1.0);
|
||||
|
||||
const light = new THREE.DirectionalLight(0xffffff, Math.PI);
|
||||
light.position.set(1.0, 1.0, 1.0);
|
||||
scene.add(light);
|
||||
|
||||
let currentVrm: any = undefined;
|
||||
let currentVrmAnimation: any = undefined;
|
||||
let currentMixer:any = undefined;
|
||||
let percentComplete = null;
|
||||
|
||||
function load(url: string) {
|
||||
loader.load(
|
||||
url,
|
||||
(gltf) => {
|
||||
tryInitVRM(gltf);
|
||||
tryInitVRMA(gltf);
|
||||
},
|
||||
(xhr) => {
|
||||
percentComplete = (xhr.loaded / xhr.total) * 100
|
||||
},
|
||||
(error) => console.error(error)
|
||||
);
|
||||
}
|
||||
|
||||
function tryInitVRM(gltf: any) {
|
||||
const vrm = gltf.userData.vrm;
|
||||
if ( vrm == null ) {
|
||||
return;
|
||||
}
|
||||
currentVrm = vrm;
|
||||
scene.add(vrm.scene);
|
||||
initAnimationClip();
|
||||
}
|
||||
|
||||
function tryInitVRMA(gltf: any) {
|
||||
const vrmAnimations = gltf.userData.vrmAnimations;
|
||||
if (vrmAnimations == null) {
|
||||
return;
|
||||
}
|
||||
currentVrmAnimation = vrmAnimations[0] ?? null;
|
||||
initAnimationClip();
|
||||
}
|
||||
|
||||
function initAnimationClip() {
|
||||
if (currentVrm && currentVrmAnimation) {
|
||||
currentMixer = new THREE.AnimationMixer(currentVrm.scene);
|
||||
const clip = createVRMAnimationClip(currentVrmAnimation, currentVrm);
|
||||
currentMixer.clipAction(clip).play();
|
||||
}
|
||||
}
|
||||
|
||||
const loader = new GLTFLoader(manager);
|
||||
loader.register((parser) => {
|
||||
return new VRMLoaderPlugin(parser);
|
||||
});
|
||||
loader.register((parser) => {
|
||||
return new VRMAnimationLoaderPlugin(parser);
|
||||
});
|
||||
|
||||
load("/models/default.vrm");
|
||||
load("/models/default.vrma");
|
||||
|
||||
const clock = new THREE.Clock();
|
||||
clock.start();
|
||||
|
||||
onResize();
|
||||
window.addEventListener('resize', onResize);
|
||||
function onResize() {
|
||||
const width = window.innerWidth;
|
||||
const height = window.innerHeight;
|
||||
renderer.setPixelRatio(window.devicePixelRatio);
|
||||
renderer.setSize(width, height);
|
||||
camera.aspect = width / height;
|
||||
camera.updateProjectionMatrix();
|
||||
}
|
||||
|
||||
animate();
|
||||
function animate() {
|
||||
const delta = clock.getDelta();
|
||||
if (currentMixer) {
|
||||
currentMixer.update(delta);
|
||||
}
|
||||
if (currentVrm) {
|
||||
currentVrm.update(delta);
|
||||
}
|
||||
requestAnimationFrame(animate);
|
||||
renderer.render(scene, camera);
|
||||
}
|
||||
|
||||
})
|
7
min-ts/tsconfig.json
Normal file
7
min-ts/tsconfig.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es2016",
|
||||
"module": "commonjs",
|
||||
"skipLibCheck": true
|
||||
}
|
||||
}
|
26
min-ts/webpack.config.js
Normal file
26
min-ts/webpack.config.js
Normal file
@ -0,0 +1,26 @@
|
||||
const path = require('path');
|
||||
|
||||
module.exports = {
|
||||
mode: 'development',
|
||||
entry: './src/index.ts',
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.ts$/,
|
||||
loader: 'ts-loader'
|
||||
}
|
||||
]
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.ts', '.js']
|
||||
},
|
||||
output: {
|
||||
filename: 'main.js',
|
||||
path: path.join(__dirname, "dist")
|
||||
},
|
||||
devServer: {
|
||||
static: {
|
||||
directory: path.join(__dirname, "dist"),
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user