8
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Grimoire.jsAdvent Calendar 2016

Day 4

タグベースの WebGL ライブラリを比較してみる

Last updated at Posted at 2016-12-11

この記事はGrimoire.js Advent Calender 2016の4日目の記事です。

はじめに

Grimoire.js はタグベースで Web の 3D 表現を拡張するライブラリのようです。少し興味があったので、他にも類似したライブラリが無いか、調べてみました。

タグベースの WebGL ライブラリの一覧

探してみると、そこそこあるようですね。Link とあるのは、jsdo.it に投稿したサンプルへのリンクになります。

ライブラリ名 ライセンス バージョン 作者 texture glTF
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

texture は、キューブにテクスチャを貼り付けるサンプル、
glTF は、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 が用いられているようです。

index.html
<glam>
    <scene>
        <box id="photocube" class="animRotateY"></box>
    </scene>
</glam>
style.css
#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 要素として統合および操作するためのフレームワークとのことです。

index.html
<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 拡張規格 のようです。
以下はサンプルコードですが、少し冗長になってしまいました。もしかしたらプリミティブ型があるのかもしれませんが、見つけることができませんでした。

index.html
<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>
index.js
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 が用いられています。

index.html
<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 を推奨します。

index.html
<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>
index.js
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 を推奨します。

index.html
<model-gltf src="BoxTextured.gltf"/>

Grimoire.js

Grimoire.js は以前は jThree V3 と呼ばれていましたが、途中で名前が変わったようです。
Grimoire.js は XML に準拠した記法である GOML(Grimorie Object Markup Language) が特徴です。別ファイルに書くことが推奨されているようですが、HTML に埋め込むことも可能なようです。

index.html
  <script id="main" type="text/goml" src="index.goml"></script>
index.goml
<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>
index.js
var ratio = 0;

function rot() {
    gr('#main')('mesh').setAttribute('rotation', ratio + ',' + ratio + ',' + ratio);
    ratio += 1;
    requestAnimationFrame(rot);
}

rot();

おわりに

いかがでしょうか。Web 上の 3D 表現に関しては、標準的な仕様が確立されていない為、多くの実験プロジェクトが存在するように思います。
ライブラリやフレームワークは十人十色なので、一概にこれが良い、というのは言えないですが、
その中で、Grimoire.js には、勢いがあるので是非 Web 3D 界の未来を切り開いていってほしいですね。

8
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?