Babylon.jsを使うためのメモ〜Blender連携のおまけを添えて〜


どうも皆様本日はお日柄も良く云々かんぬん、ってこれはお見合い的なあれでしたっけか。

ともあれ、こんにちは。
今回はBabylon.jsを使ってちょっとしたサンプルを作ってみたので、そこに至るまでのメモになります。

近頃、モデリングや映像分野に興味を持ちまして、色々試しております。
先月先々月辺りでHTML,CSS,Javascriptを触りはじめ、どうせならそこら辺使って何か出来ないかなーと思ってたらWebGLなるものがあるではありませんか。

・WebGL Overview - The Khronos Group Inc
https://www.khronos.org/webgl/

・WebGL - Wikipedia
https://ja.wikipedia.org/wiki/WebGL


これをJavascriptとHTMLで扱えるらしいと。
とりあえず上手ぶってGLSLとかいうものを触ろうとしましたが爆死。
おとなしくライブラリを触ることにしました。

どうやら、WebGL用Javascriptライブラリには結構な種類があって、シェアだけで言えば、Three.jsが一番の模様。

少なくとも日本語で得られる情報はThree.jsが一番多いようなので、これを使うべきだと思いましたが、その名前のお洒落さから、次点のシェアを持つBabylon.jsを使うことにしました。
ルパンとか、英雄王とかロマン溢れるじゃない。
(まだ「ちょっと触った」段階ですが、英語の情報がほとんどで調べるのが面倒なので、2018/07段階では特に理由がなければThree.js使った方がいいと思います)

で、お試しに作ってみたのがこちら。

「Phantoma | HollowCradle」
http://hollowcradle.cf/phantoma/index.html

空を覆う銀河を反射する水面の上で変なテクスチャの貼られたオブジェクトがくるくる周るだけのものです。

コードはこんな感じ。

HTML(scriptは読み込みたい部分に記述)
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
</head>
<body>
    <main>
        <canvas id='canvas'>This Browser Not support
            <code>&lt;canvas&gt;</code> element.</canvas>
    </main>
    <script src="https://preview.babylonjs.com/babylon.js"></script>
    <script src="https://preview.babylonjs.com/loaders/babylonjs.loaders.min.js"></script>
    <script src="https://code.jquery.com/pep/0.4.1/pep.js"></script>
    <script src='https://preview.babylonjs.com/materialsLibrary/babylonjs.materials.js'></script>
    <script src='https://preview.babylonjs.com/materialsLibrary/babylonjs.materials.min.js'></script>
    <script src='../script/babylon.waterMaterial.js'></script>
    <script src='script/index.js'></script>
</body>
</html>

Javascript
var engine;
var flag_turn_alpha = true;
var alpha_var = 0.01;
var polyhedron_texture = ['img/sky0.jpg', 'img/sky1.jpg', 'img/sky2.jpg', 'img/sky3.jpg', 'img/surface0.png', 'img/unstable0.png', 'img/unstable1.png', 'img/unstable2.png']
const alpha_min = 0.3;
const alpha_max = 0.9;
const field_size = 1028;
const rotaion_x_var = 0.03;
const rotaion_y_var = 0.03;

const canvas = document.getElementById('canvas');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

engine = new BABYLON.Engine(canvas, true);

var scene = new BABYLON.Scene(engine);

// Camera
var camera = new BABYLON.ArcRotateCamera('Camera', Math.PI / 1.6, Math.PI / 2.1, 400, BABYLON.Vector3.Zero(), scene);
// camera.setPosition(new BABYLON.Vector3(1, -1, -1));
camera.attachControl(canvas, true);

// Light
var light1 = new BABYLON.HemisphericLight('light2', new BABYLON.Vector3(0, 1, 0), scene);

// Skybox
var skybox = BABYLON.Mesh.CreateBox('skybox', 5000.0, scene);
var skybox_material = new BABYLON.StandardMaterial('skybox', scene);
skybox_material.backFaceCulling = false;
skybox_material.reflectionTexture = new BABYLON.CubeTexture('img/nebula/nebula', scene);
skybox_material.reflectionTexture.coordinatesMode = BABYLON.Texture.SKYBOX_MODE;
skybox_material.diffuseColor = new BABYLON.Color3(0, 0, 0);
skybox_material.specularColor = new BABYLON.Color3(0, 0, 0);
skybox_material.disableLighting = true;
skybox.material = skybox_material;

// Ground
var ground_texture = new BABYLON.Texture('img/Ground.jpg', scene);
ground_texture.vScale = ground_texture.uScale = 4.0;
var ground_material = new BABYLON.StandardMaterial('groundMaterial', scene);
ground_material.diffuseTexture = ground_texture;
var ground = BABYLON.Mesh.CreateGround('ground', field_size, field_size, 32, scene, false);
ground.position.y = -1;
ground.material = ground_material;

// Water Material
var water_material = new BABYLON.WaterMaterial('waterMaterial', scene, new BABYLON.Vector2(512, 512));
water_material.bumpTexture = new BABYLON.Texture('img/waterbump.png', scene);
water_material.windForce = -3;
water_material.waveHeight = 0.5;
water_material.waveLength = 0.5;
water_material.waveSpeed = 50.0;
water_material.bumpHeight = 0.1;
water_material.colorBlendFactor = 0;
water_material.windDirection = new BABYLON.Vector2(1, 1);
water_material.colorBlendFactor = 0;

// Water Mesh
var water_mesh = BABYLON.Mesh.CreateGround('waterMesh', field_size, field_size, 32, scene, false);
water_mesh.material = water_material;

// Some Objects
let texture = polyhedron_texture[Math.floor(Math.random() * polyhedron_texture.length)];
var polyhedron_material = new BABYLON.StandardMaterial('polyhedron_material', scene);
polyhedron_material.diffuseTexture = new BABYLON.Texture(texture, scene);
var polyhedron = BABYLON.MeshBuilder.CreatePolyhedron('polyhedron', { type: Math.floor( Math.random() * 15 + 1), size: 20 }, scene);
polyhedron.position.y = 50;
polyhedron.material = polyhedron_material;
polyhedron.material.alpha = 0.3;

// Configure Water Material
water_material.addToRenderList(ground);
water_material.addToRenderList(skybox);
water_material.addToRenderList(polyhedron);

// scene.debugLayer.show();

engine.runRenderLoop(function () {
    scene.render();

    polyhedron.material.alpha += alpha_var;
    // polyhedron.rotation.x += rotaion_x_var;
    polyhedron.rotation.y += rotaion_y_var;

    if (polyhedron.material.alpha < alpha_min || polyhedron.material.alpha > alpha_max) {
        alpha_var = -alpha_var;
    }

});

window.onresize = function () {
    engine.resize();
}


まだやることが単純なものもありますが、そこまでごちゃごちゃしておらず、よく読んでいけば何やってるかは何となく掴める感じ。
GLSLに手を出そうとして最初の段階で「?????????」となったことを考えれば何と素晴らしい。

しかし、僕みたいなプログラマでない人間がちょろっと勉強しただけでこんなのが作れるなんて、素敵な時代ですね。
楽しみが本当に尽きない。


Babylon.jsでどんなことができるのかは、公式サイトにあるこのページでサンプルデモとサンプルコードを確認できますので、気になる方は是非。

https://doc.babylonjs.com/examples/

同士求む。



Babylon.js関連リンク

・BabylonJS - 3D engine based on WebGL/Web Audio and JavaScript
https://www.babylonjs.com/

・Babylon.js · GitHub
https://github.com/BabylonJS

・Babylon.js Documentation
https://doc.babylonjs.com/


現状、ChromeやChromiumではCORS(Cross-Origin Resource Sharing)の問題で、そのままテストで確認することができません。
そのため回避のためのオプションを付けて起動するか、Firefoxなど別のブラウザを使いましょう。

・【解説付き】chromeでXMLHttpRequestをローカルのファイルで行う方法
https://qiita.com/growsic/items/a919a7e2a665557d9cf4

・開発時にCORSを無視するGoogleChromeの起動オプション
https://qiita.com/mottox2/items/498bb31d67caa2d8a71f


おまけ
現在Blenderで作ってるもの。
ハンス・ベルメールの球体関節人形のつもりなのではありますが、いかんせんまだ荒いですね。
練習あるのみ。
SILENT HILL2のマネキンみたいに気持ち悪い動きさせるのが当座の目標。
勉強あるのみ。

モデルが完成したらBabylon.js使ってHollowCradleに上げますのでしばしお待ちを。



Blender+Babylon.jsに関してはここらへんを参考に。

・Babylon.js Documentation
http://doc.babylonjs.com/resources/blender
※こっちはBlender→Babylon.jsのインポートツールについてのドキュメント

・次世代の3Dデータフォーマット決定版 glTF 2.0 の概要図を日本語訳してみた
https://qiita.com/randall2835/items/ec911cb6b0f10677559b

・今話題の3Dファイル形式「glTF」でWebGLの表現力を高めよう!
https://qiita.com/emadurandal/items/1a034c4addd7ff8b5184

・Babylon.js Documentation
http://doc.babylonjs.com/resources/blender

・ramble3d | Image 3d, Animation 3d, 3d Temps Réel à Compiègne,Amiens,Paris
https://www.studio-ramble3d.com/MakingOf_En.html


お試しで作ったサンプル。

「Yurineko | HollowCradle」
http://hollowcradle.cf/yurineko/index.html

名前は"揺猫"です。

コメント