この記事はGrimoire.js Advent Calender 2016の4日目の記事です。
はじめに
Grimoire.js はタグベースで Web の 3D 表現を拡張するライブラリのようです。少し興味があったので、他にも類似したライブラリが無いか、調べてみました。
タグベースの WebGL ライブラリの一覧
探してみると、そこそこあるようですね。Link とあるのは、jsdo.it に投稿したサンプルへのリンクになります。
ライブラリ名 | ライセンス | バージョン | 作者 | ||
---|---|---|---|---|---|
GLAM | MIT | beta(2015.02.13) | Tony Parisi | Link | Link |
X3DOM | MIT and GPL | 1.7.2(2016.12.19) | X3DOM | Link | Link |
xml3d.js | MIT | 5.2.1(2016.08.09) | DFKI, Saarland University | Link | Link |
A-Frame | MIT | v0.3.2(2016.10.13) | A-Frame | Link | Link |
three-canvas | MIT | -(2015.08.12) | technohippy | Link | |
model-tag | MIT | -(2016.11.19) | Mr.doob | Link | |
Grimoire.js | MIT | v0.11.17(2016.12.08) | GrimoireGL | Link | Link |
は、キューブにテクスチャを貼り付けるサンプル、
は、3D モデルファイル(COLLADA や glTF ファイル等)の表示サンプルになります。
各ライブラリの特徴
GLAM
作者の Tony Parisi さんは、古くは VRML、最近だと glTF の仕様策定に関わっている、Web3D 界の巨匠のような方です。Three.js 版の glTF Loader も初版は Tony Parisi さんによるものです。
また、GLAM(GL A nd M arkup)は、3D Webコンテンツを作成するための宣言的言語とのことです。残念ながら開発は beta で止まっているようです。レンダリングには Three.js が用いられているようです。
<glam>
<scene>
<box id="photocube" class="animRotateY"></box>
</scene>
</glam>
#photocube {
image:url(frog.jpg);
rx:30deg;
}
@keyframes kfRotateY {
from {
transform: rotateY(0deg);
}
to {
transform: rotateY(360deg);
}
}
.animRotateY
{
animation-duration: 10s;
animation-name: kfRotateY;
animation-iteration-count: infinite;
animation-timing-function:linear;
}
X3DOM
X3DOM は X3D シーンを HTML5 DOM 要素として統合および操作するためのフレームワークとのことです。
<x3d width='465px' height='465px'>
<scene>
<transform DEF="cube" rotation="0 1 0 3.14159265359">
<shape>
<appearance>
<ImageTexture url="frog.jpg"></ImageTexture>
</appearance>
<box size='3, 3, 3'></box>
</shape>
</transform>
<timeSensor DEF="time" cycleInterval="2" loop="true"></timeSensor>
<OrientationInterpolator DEF='move' key='0 0.5 1' keyValue='1 0 0 0, 1 1 1 3.14, 1 0 0 6.28'/>
<Route fromNode="time" fromField ="fraction_changed" toNode="move" toField="set_fraction"></Route>
<Route fromNode="move" fromField ="value_changed" toNode="cube" toField="rotation"></Route>
</scene>
</x3d>
xml3d.js
XML3D は Intel が推奨する 3D 拡張規格 のようです。
以下はサンプルコードですが、少し冗長になってしまいました。もしかしたらプリミティブ型があるのかもしれませんが、見つけることができませんでした。
<xml3d id="MyXml3d" style="width: 100%; height: 100%" xmlns="http://www.xml3d.org/2009/xml3d" onload="initAnim()" view="#myview">
<defs>
<transform id="myxfm" rotation="1 0 1 0"></transform>
<transform id="lightTransform" translation="-2 5 10" />
<material id="phongShader" model="urn:xml3d:material:phong">
<float3 name="diffuseColor">1.0 0.9 0.8</float3>
<float name="ambientIntensity">1.0</float>
<texture name="diffuseTexture">
<img src="frog.jpg"/>
</texture>
</material>
<lightshader id="lightShader" script="urn:xml3d:lightshader:point">
<float3 name="intensity">1.0 1.0 1.0</float3>
<float3 name="attenuation">1.0 1.0 1.0</float3>
</lightshader>
<data id="box">
<int name="index">
0 1 2 0 2 3 <!-- Front face -->
4 5 6 4 6 7 <!-- Back face -->
8 9 10 8 10 11 <!-- Top face -->
12 13 14 12 14 15 <!-- Bottom face -->
16 17 18 16 18 19 <!-- Right face -->
20 21 22 20 22 23 <!-- Left face -->
</int>
<float3 name="position">
<!-- Front face -->
-0.5 -0.5 0.5 0.5 -0.5 0.5 0.5 0.5 0.5 -0.5 0.5 0.5
<!-- Back face -->
-0.5 -0.5 -0.5 0.5 -0.5 -0.5 0.5 0.5 -0.5 -0.5 0.5 -0.5
<!-- Top face -->
0.5 0.5 0.5 -0.5 0.5 0.5 -0.5 0.5 -0.5 0.5 0.5 -0.5
<!-- Bottom face -->
-0.5 -0.5 0.5 0.5 -0.5 0.5 0.5 -0.5 -0.5 -0.5 -0.5 -0.5
<!-- Right face -->
0.5 -0.5 0.5 0.5 0.5 0.5 0.5 0.5 -0.5 0.5 -0.5 -0.5
<!-- Left face -->
-0.5 -0.5 0.5 -0.5 0.5 0.5 -0.5 0.5 -0.5 -0.5 -0.5 -0.5
</float3>
<float3 name="normal">
<!-- Front face -->
-0.5 -0.5 0.5 0.5 -0.5 0.5 0.5 0.5 0.5 -0.5 0.5 0.5
<!-- Back face -->
-0.5 -0.5 -0.5 0.5 -0.5 -0.5 0.5 0.5 -0.5 -0.5 0.5 -0.5
<!-- Top face -->
0.5 0.5 0.5 -0.5 0.5 0.5 -0.5 0.5 -0.5 0.5 0.5 -0.5
<!-- Bottom face -->
-0.5 -0.5 0.5 0.5 -0.5 0.5 0.5 -0.5 -0.5 -0.5 -0.5 -0.5
<!-- Right face -->
0.5 -0.5 0.5 0.5 0.5 0.5 0.5 0.5 -0.5 0.5 -0.5 -0.5
<!-- Left face -->
-0.5 -0.5 0.5 -0.5 0.5 0.5 -0.5 0.5 -0.5 -0.5 -0.5 -0.5
</float3>
<float2 name="texcoord">
<!-- Front face -->
0.0 0.0 1.0 0.0 1.0 1.0 0.0 1.0
<!-- Back face -->
1.0 0.0 1.0 1.0 0.0 1.0 0.0 0.0
<!-- Top face -->
0.0 1.0 0.0 0.0 1.0 0.0 1.0 1.0
<!-- Bottom face -->
1.0 1.0 0.0 1.0 0.0 0.0 1.0 0.0
<!-- Right face -->
1.0 0.0 1.0 1.0 0.0 1.0 0.0 0.0
<!-- Left face -->
0.0 0.0 1.0 0.0 1.0 1.0 0.0 1.0
</float2>
</data>
</defs>
<view id="myview" style="transform: translate3d(0px, 0px, -4px) rotate3d(0, 1, 0, 180.0deg)"><float name="fovVertical">0.7854</float></view>
<group transform="#lightTransform">
<light shader="#lightShader"/>
</group>
<group transform="#myxfm" style="material: url(#phongShader)" >
<mesh src="#box" type="triangles">
</mesh>
</group>
</xml3d>
var anim = {};
function initAnim() {
anim.xfm = document.getElementById("myxfm");
anim.lastTime = (new Date()).getTime();
anim.rotAngle = 0.0;
anim.intervalID = window.setInterval(function () {
var currentTime = (new Date).getTime();
var delta = currentTime - anim.lastTime;
anim.rotAngle += (30 * delta) / 1000.0;
anim.xfm.setAttribute("rotation", "1.0 0.0 1.0 "+(anim.rotAngle * Math.PI / 180));
anim.lastTime = currentTime;
}, 20);
}
A-Frame
A-Frame は VR シーンを記述するのに優れた最近人気のフレームワークのようです。レンダリングには Three.js が用いられています。
<a-scene>
<a-assets>
<img id="my-texture" src="frog.jpg">
</a-assets>
<a-entity scale="2 2 2" geometry="primitive: box;" position="0 1 0" material="src: #my-texture">
<a-animation easing="linear" attribute="rotation" dur="10000" to="360 360 360" repeat="indefinite"></a-animation>
</a-entity>
<a-entity position="0 0 3.8">
<a-camera></a-camera>
</a-entity>
</a-scene>
three-canvas
three-canvas は technohippy さんによる Three.js を用いた Custom Elements ライブラリです。使用している Three.js のバージョンは少し古いようです。
残念ながら、今のところ、Custom Elements は仕様策定中であり、一部のブラウザしか対応していません。実行には、Chrome を推奨します。
<three-canvas width="465" height="465" antialias="true" clear-color="#000000" default-light="true">
<three-camera position="0,0,8" look-at="0,0,0" controls="orbit"></three-camera>
<three-mesh name="box">
<!-- frog.jpg -->
<three-material color="#ffffff" map="frog.jpg"></three-material>
<three-box-geometry width="1" height="1" depth="1"></three-box-geometry>
</three-mesh>
</three-canvas>
function rotateBox() {
var threeCanvas = document.getElementsByTagName('three-canvas')[0];
var threeJsMesh = threeCanvas.scene.getObjectByName('box');
threeJsMesh.rotation.x += 0.01;
threeJsMesh.rotation.y += 0.01;
}
function animate() {
requestAnimationFrame(animate);
rotateBox();
}
animate();
model-tag
model-tag は Three.js の作者でもある Mr.doob さんによる実験プロジェクトです。
three-canvas 同様、Custom Elements を用いたライブラリである為、一部のブラウザしか対応していません。実行には、Chrome を推奨します。
<model-gltf src="BoxTextured.gltf"/>
Grimoire.js
Grimoire.js は以前は jThree V3 と呼ばれていましたが、途中で名前が変わったようです。
Grimoire.js は XML に準拠した記法である GOML(Grimorie Object Markup Language) が特徴です。別ファイルに書くことが推奨されているようですが、HTML に埋め込むことも可能なようです。
<script id="main" type="text/goml" src="index.goml"></script>
<goml width="465" height="465">
<import-material type="sprite" src="index.sort" />
<material id="sprite" type="sprite" color="blue" sun="0.5,0.5" texture="frog.jpg"/>
<scene>
<camera>
<camera.components>
<MouseCameraControl rotateX="10" moveSpeed="1" />
</camera.components>
</camera>
<mesh geometry="cube" material="#sprite"/>
</scene>
</goml>
var ratio = 0;
function rot() {
gr('#main')('mesh').setAttribute('rotation', ratio + ',' + ratio + ',' + ratio);
ratio += 1;
requestAnimationFrame(rot);
}
rot();
おわりに
いかがでしょうか。Web 上の 3D 表現に関しては、標準的な仕様が確立されていない為、多くの実験プロジェクトが存在するように思います。
ライブラリやフレームワークは十人十色なので、一概にこれが良い、というのは言えないですが、
その中で、Grimoire.js には、勢いがあるので是非 Web 3D 界の未来を切り開いていってほしいですね。