2023-04-09
前回の記事で、blenderで無事3Dキャラクターにアニメーションをつけることができました。改めて見るとタイトル酷い。
今回はいよいよ、three.jsを使って3Dキャラクターをブラウザに表示させるまでの記録です。(ここまで本当に長かった..)
もうここまで来るとわかったことですが、
絶対に簡単にはできない。
まず最初から動かそうとはせず、仕組みを知るために、止まってる状態の3Dキャラクターをブラウザに表示させようと思いました。
blenderのオブジェクトモードで書き出したい箇所を選択→ファイル→エクスポート→gltf2.0を選択
エクスポートを行います。
※「Punctualライト」にチェックするとblenderで設定したライトも保存できるのだけど、three.jsとの相性が悪いようで、ブラウザで見ると真っ白になりました。なのでライトはthree.jsのコードで設定します。
glbファイルを無事書き出せたことが確認できたら、今度はthree.jsサイトを開きファイル一式をダウンロードをしてきます。
必要なファイルは下記3つのファイルです。
ちなみにthree.jsサイトのeditorページを開き、書き出したglbファイルを画面にドラッグすると、正常に書き出しがされているか確認することができます。便利!
次からはいよいよコードを書いていくのですが、最近何かと話題になっているchatGPTに質問しながらコードを書いてみました。
すっごい雑な質問
こんな雑な質問にもスラスラ答えてくれる。なんて便利なんだ。
私はchatGPTのことを心の中で「ドラえもん」と呼んでいます。
何も調べずに、ただドラえもんが答えてくれたコードをそのまま書いたわけですが、ページを開いてびっくり。キャラクターが闇落ちした状態で表示されました。夜にこの作業を行なっていたのですが、こわすぎて震えました。
調子に乗って痛い目にあう、のび太状態。
何回聞いてもうまくいかない。そりゃそーだ。内容を全く理解してないんだもの。
つぶれた状態で表示された時、ちゃんと勉強しようと強く思うのでした。
そんなわけで、ちゃんとコードの内容を理解するために勉強しました。
あとは、blenderで色の指定をマテリアルにしないといけないこと、テクスチャ部分はベイクという画像にする設定を行わないといけないことも学びました。
コード内容を理解し、blenderで学んだ照明の大事さをここでも学びます。
いろいろな方のブログや動画を見たり、わからない箇所はchatGPTに聞きながら書いたコードがこちらです↓
(あくまでも私が見つけてきたコードなので、もっといい書き方がある気もします。誰かのお役に立てれば..)
ちなみにblenderで-yを前面にしていた場合になります。
<body>
<div id="main_canvas">
<canvas id="canvas"></canvas>
</div>
<script src="./assets/js/three.min.js"></script>
<script src="./assets/js/GLTFLoader.js"></script>
<script src="./assets/js/OrbitControls.js"></script>
<script src="./assets/js/index.js"></script>
</body>
window.addEventListener('DOMContentLoaded', init);
function init() {
// レンダラーを作成
const renderer = new THREE.WebGLRenderer({
canvas: document.querySelector('#canvas'),
antialias: true,
});
// ウィンドウサイズ設定
width = document.getElementById('main_canvas').getBoundingClientRect().width;
height = document.getElementById('main_canvas').getBoundingClientRect().height;
renderer.setPixelRatio(1);
renderer.setSize(window.innerWidth, window.innerHeight);
console.log(window.devicePixelRatio);
console.log(width + ", " + height);
// シーンを作成
const scene = new THREE.Scene();
scene.background = new THREE.Color( 0x691DB3 ); // 背景色
// カメラを作成
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );
camera.position.set(0, 2, 500);
const controls = new THREE.OrbitControls(camera, renderer.domElement);
// glbファイルを読み込み
const loader = new THREE.GLTFLoader();
const url = '/moco.glb';
// window size
let model = null;
loader.load(
url,
function (gltf) {
model = gltf.scene;
// model.name = "model_with_cloth";
model.scale.set(80.0, 80.0, 80.0);
model.position.set(0, (window.innerHeight / 3 * -1.2), 0);// ブラウザの中心に持ってくる設定
scene.add(model);
// model["test"] = 100;
},
function (error) {
console.log('An error happened');
console.log(error);
}
);
renderer.gammaOutput = true;
renderer.gammaFactor = 2.2;
// 平行光源
const light = new THREE.DirectionalLight(0xFFCFC8, 0.5);
light.position.set(0, -50, 0); // 光源の位置を指定
// シーンに追加
scene.add(light);
// PointLightを作成
const pointLight = new THREE.PointLight(0xFFCFC8, 0.3);
pointLight.position.set(0, 0, -500); // 光源の位置を指定
scene.add(pointLight); // シーンに追加
//環境光源(アンビエントライト)
const ambient = new THREE.AmbientLight(0xFFCFC8, 0.8);
scene.add(ambient); //シーンにアンビエントライトを追加
// 初回実行
tick();
function tick() {
controls.update();
if (model != null) {
console.log(model);
}
renderer.render(scene, camera);
requestAnimationFrame(tick);
}
// アニメーションループ
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
animate();
}
そして完成したのがこちらです。
なんとか綺麗に表示されたことが本当に嬉しい。ブラウザに自分が作った3Dを表示させられたことが嬉しい。
ただ、blenderで作ったような見た目ではないし、目や髪が綺麗じゃない。この解決にはblenderでベイクという作業が必要なようです。他にも方法あるのかな..
この質感を頑張って再現させたい。あと色味が違うのでここも解決しないとですね。
そんなわけで、次回はベイクを使って、よりblenderで作った見た目に近づけて、そしていよいよアニメーションをつける作業を行いたいなと。
まだまだエラーをたくさん起こしそうだけど、blender地獄に比べたら全然かわいいものです。
頑張るぞ!!!
コメントを見る(0 件)