1
0
hugo/content/blog/2024-03-19-vrm.md

113 lines
3.5 KiB
Markdown
Raw Normal View History

2024-04-23 13:21:26 +00:00
+++
date = "2024-03-19"
tags = ["vrm", "threejs"]
title = "three.jsでbloomを有効にする"
slug = "vrm"
+++
リファクタリングの一環としてweb周りで作ったものを整理しています。
- https://git.syui.ai/ai/vrm
ただ、整理といいつつ、ほとんど新しい実装を試していて、コード自体はきれいになっていません。
以前は、`three-vrm:v0.6`で作成されたプロジェクトのforkを使用していましたが、なかなかに複雑で古いpackageを使用していたので、イチから作り直しました。
`three-vrm:v2.1`にして、`node:v21`, `yarn:v1.22`を使っています。
## bloom
ぼんやりと発光させるには、bloomを有効にしなければなりません。
ただし、threeに入っているexampleはメンテナンスされていません。別のものを使ったほうが良いでしょう。
```sh
$ yarn add postprocessing
```
```js:src/index.ts
//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();
});
```
注意としては、`WebGLRenderer`のoptionによっては動かないことがあるらしいので、そのときは以下を設定してください。
```js:src/index.ts
import { WebGLRenderer } from "three";
const renderer = new WebGLRenderer({
powerPreference: "high-performance",
antialias: false,
stencil: false,
depth: false
});
```
## progress
progress-barを出します。既に用意されているらしいので、それを使います。
```js:src/index.ts
// 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:dist/index.html
<progress value="0" max="100" id="progressBar"></progress>
```
```css:dist/css/style.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;
}
```