科学技術館で毎週土曜日に行われている科学ライブショー「ユニバース」には、太陽系の様子をリアルタイムに計算してドーム上に投影する「太陽系の姿」と呼ばれるコーナーがあります。現在は3次元化し天球に対応するドームに投影していますが、2002年までは2次元かつ平面スクリーンに投影していました。最近のブラウザはWebGLと呼ばれる技術をサポートしており、この一昔前の太陽系シミュレーター(太陽系の姿で使われるシミュレーションエンジン)くらいであれば、ブラウザ上で動作させることができるようになっています。ここでは、この一昔前の太陽系シミュレーターをWebGLを用いて作っていく過程で調べたことを、メモしていこうと思います。
Three.jsとは
WebGLは、OpenGLをJavaScriptから利用できるようにしたAPI群で、ブラウザー上で3Dグラフィックスを動かすためのものです。2013年現在、Chrome、Firefox、Safariなどのブラウザが対応していますが、Internet Explorerは対応していません。JavaScriptからWebGLを直接利用することも可能ですが、ラッパーであるThree.jsを使うと、JavaScriptの流儀で3Dの世界を簡単に実現することができます。ただし、Three.jsが注目されたのが2011年頃だったこともあってウェブ上の情報は古くなっていますし、日本語の情報も少なく、また、サンプルページも削除されてしまっているものが増えています。さらに、Three.js自身のドキュメントがあまり充実しておらず、実例のソースを分析して自分なりに調べる必要があります。そこで、このシリーズでは、2013年6月18日現在で最新の Three.js(r58)について調べたことを日本語でメモしようと思っています。
最初のサンプル
Three.jsは、threejs.orgからダウンロードすることができます。ダウンロードしたZIPファイルは75MBくらいありますが、そのほとんどは、サンプルのコードです。実際に利用するには、HTMLのヘッダー等から、buildフォルダ中のthree.min.jsファイルを読み込めば十分です。また、マウスの動きに対応するためのTrackballControls、Three.jsの統計情報を表示するstatsも使うと便利ですので、examples/jsフォルダも一式コピーしておきます。ここまでで、以下のようなHTMLファイルを作ることができ、これが最初のひな形となります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<!DOCTYPE html> <html> <head> <script src="http://code.jquery.com/jquery.min.js"></script> <script src="build/three.min.js"></script> <script src="examples/js/libs/stats.min.js"></script> <script src="examples/js/controls/TrackballControls.js"></script> <style> html, body { margin: 0; padding: 0; width: 100%; height: 100%; } #sssim { width: 100%; height: 100%; margin: 0; padding: 0; } </style> </head> <body> <div id="sssim" style="background: black"></div> <script type="text/javascript"> /* ここに処理を書く */ </script> </body> </html> |
続いて、上記で/* ここに処理を書く */
とした部分に以下のスクリプトを追加します。ここでは、ひとまず背景を黒単色で塗りつぶした3D空間を用意し、直方体を一つ置いています。なお、簡単のため、距離の単位は1=1天文単位(AU)としています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
var renderer, scene, camera, light, controls, stats; function init() { var sssimElem = $('#sssim'); var w = sssimElem.width = $(window).innerWidth(); var h = sssimElem.height = $(window).innerHeight(); renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(w, h); renderer.setClearColor(0x000000, 1); sssimElem.append(renderer.domElement); scene = new THREE.Scene(); camera = new THREE.PerspectiveCamera(45, w/h, 0.001, 1500); camera.position = new THREE.Vector3(1, 1, 5); camera.lookAt(new THREE.Vector3(0, 0, 0)); scene.add(camera); light = new THREE.PointLight(0xffffff); light.position = new THREE.Vector3(0, 0, 0); light.intensity = 3.0; scene.add(light); stats = new Stats(); stats.domElement.style.position = 'absolute'; stats.domElement.style.top = '0px'; stats.domElement.style.stylezIndex = 100; sssimElem.append(stats.domElement); controls = new THREE.TrackballControls(camera, sssimElem.domElement); controls.maxDistance = 2500; // add an axis helper scene.add(new THREE.AxisHelper(1500)); // add a cube scene.add(new THREE.Mesh(new THREE.CubeGeometry(1, 1, 1), new THREE.MeshBasicMaterial({ color: 0xff8800 }))); } function main() { renderer.render(scene, camera); controls.update(); stats.update(); requestAnimationFrame(main); } $(function() { init(); main(); }); |
これを実際のHTMLとして保存し実行できるようにしたものがこちらです。オレンジ色の立方体と、XYZ軸(X軸がR、Y軸がG、Z軸がBに対応)が表示されています。これをテンプレートとして、sceneオブジェクトに対し、太陽系や銀河系の様々な天体をオブジェクト(Meshのインスタンス)として追加していくことになります。
(続く)
Login