• そうだ、アプリの研究しよう vol.1

    この間、友人から「会社の紹介写真なんであんなカワイイポーズなの?w」って突っ込まれた坂田です。

    ギャグのつもりのポーズなので、指摘されてうれし恥ずかし。

    隣の銅像の真似してるんですよろしくどーぞ!

    さて前回に引き続き、お茶の間を楽しませたいと思います(‘∀`)
    Vol.0で告知しましたように、第一回目は以下のテーマで書いていきます!

    ============================
    vol1.じぶんインサイト。
    なぜ人はアプリをダウンロードし、アプリを使い続けるのか。
    ”削除”されないアプリとは何か。をまずは自分の事例から考えます。
    ============================

    “そうだ、アプリの研究しよう vol.1” の続きを読む


    投稿日:

    カテゴリー 技術 / デザイン / 制作
  • PhoneGapの検証【導入編】

  • WebGL+HTML5で3DCGを勉強してみた! Part1

    どうも。営業部の伊藤です。

    前回のブログで書いたように、今更感は否めないですが…最近WebGLの勉強をしています。
    まだ超々初心者レベルまでしか勉強できていないですが、これはなかなか頭の体操になります。
    今まであまり経験した事のない思考が必要という事もあり、抜け毛の本数が増えそうではありますが…初心者レベルになれるまでは頑張ろうと思います。

    という事で、復習も兼ねてWebGLを利用した3Dグラフィックの描画方法について書こうと思います。
    ※3DCG、WebGLに着目しているため、実装で利用するHTML、JavaScript、数学的知識の基礎については省かせていただきます。

    3DCGのサンプルは以下をご覧ください。

    ※ピカピカしているのは描画遅延ではないです。チカチカしたらすいません。。。

    【補足情報】
     利用しているオープンソースは以下2種類となります。
     ○Google webgl-utils.js
      setIntervalやsetTimeoutだと色々と問題が多い(複数オブジェクトの描画に向いていない、処理の効率化ができない(GPUに優しくない))ので、上記再帰処理はwebgl-utilsを利用しています。

     ○glMatrix.js
      3DCGを表現するために必要となる行列計算用ライブラリとして利用しています。
      後述しますが、STEP6の座標変換行列を生成&通知のところで利用します。

     勉強に利用しているサイトは以下になります。
     ○wgld.org
      初心者向けに基礎から細かくレクチャーしてくれており、非常に分かりやすいです。オススメ!!
      
    それではサンプルをもとに実装内容を書いていきます。
    3DCG描画までのSTEPは以下のようになります。

    STEP1 canvasエレメントを取得
    STEP2 canvasからWebGLコンテキストを取得
    STEP3 シェーダを生成&コンパイル
    STEP4 モデルデータを用意
    STEP5 モデルデータからVBO(VertexBufferObject)を生成&バインド
    STEP6 座標変換行列を生成&通知
    STEP7 描画命令
    STEP8 STEP6~7の再帰処理(canvasをレンダリング)

    それでは早速STEP1から処理の内容から確認していきます。

    ■STEP1(canvasエレメントを取得)
    WebGLを利用した3DレンダリングはHTML5で策定されたcanvasタグ上で動きますので、まずはHTML内のcanvasエレメントを取得します。
    今回の場合、以下部分でエレメントを取得しています。

    var canvas = document.getElementById(“cube”);

    ■STEP2(canvasからWebGLコンテキストを取得)
    次に、描画処理用オブジェクトとして、STEP1で取得したcanvasエレメントからWebGLコンテキストを取得します。
    このコンテキストで各種描画処理や属性の設定をするため、ここでコンテキストが取得できなれけばWebGLを利用できないブラウザという事になります。
    今回の場合、以下部分でコンテキストを取得しています。

    gl = c.getContext(“webgl”) || c.getContext(“experimental-webgl”);
    gl.clearColor(0.0, 0.0, 0.0, 1.0);
    gl.enable(gl.DEPTH_TEST);

    canvasに”webgl”という名前のコンテキストを要求しますが、仕様が策定中の時は失敗してしまうため”experimental-webgl”という名前のコンテキストも要求します。(失敗時用)
    その後、コンテキスト内部を初期化(clearColor)し、黒色に塗りつぶしています。
    3行目のenable(gl.DEPTH_TEST)はコンテキストに深度(DEPTH)を計算(TEST)しておけよ!という命令です。
    近くにあるものが遠くにあるものを隠すためにも描画の前に深度を把握しておく必要があります。

    サクサク進みますね。
    以外と簡単なのでは?と僕もここまでは今までの知識で問題なく吸収できたのですが、STEP3から急に難しくなり髪の毛が数本抜けたのを覚えています。。。

    ■STEP3(シェーダを生成&コンパイル)
    まず3D関係の知識が無い人はここで壁にぶるつかるでしょう。
    「シェーダ」ってなに?
    ウィキペディア先生には以下のように記載されています。

    主にライティング(光源計算)・シェーディング(陰影処理)とレンダリング(ピクセル化)を実行するためにグラフィックリソースに対して使用するソフトウェア命令の組み合わせである。
    「shade」とは「次第に変化させる」「陰影・グラデーションを付ける」という意味で、「shader」は頂点色やピクセル色などを次々に変化させるもの(より具体的に、狭義の意味で言えば関数)を意味する。
    ※wikipedia内の文章を引用

    難しい………

    超々初心者なりに要約します(間違えていたらすいません)。
    ソース内のコメントにも記載しておりますが、シェーダには大きく以下2種類のシェーダ存在します。

    1. バーテックスシェーダ(頂点シェーダ)
    2. フラグメントシェーダ(ピクセルシェーダ)

    【バーテックスシェーダ(頂点シェーダ)】
     3次元描画はポリゴンで表示する事が多く、ポリゴンは一般的に三角形の面をつなげたものが使われます(四角形を利用する事もあります)。
     三角形が利用されるポイントは、三角形は頂点の位置さえ決めれば面の位置やサイズが確定するという点です。
     四角形、五角形、、、それ以上の多角形も頂点だけでは面の位置やサイズを決める事はできません。
     この頂点の位置を計算するのがバーテックスシェーダ(頂点シェーダ)です。
     ※バーテックスシェーダは頂点の位置情報だけ管理する訳ではなく、頂点に関する”全ての情報(頂点の法線、テクスチャ座標、頂点色など)”を管理します。

    【フラグメントシェーダ(ピクセルシェーダ)】
     バーテックスシェーダ(頂点シェーダ)で頂点の位置や形状を決め、その後ラスタライズ(着色前準備)まで終えると、次にオブジェクトへの「着色」が必要になります。
     この着色内容を計算、決定する役割を担うのがフラグメントシェーダ(ピクセルシェーダー)です。
     色の計算だけであれば簡単に思えますが、これがそうでもないんです。
     3次元を表現するため、陰影、深度、光源、重複(オブジェクトやテクスチャの重なり)、乗算(透過時の後ろのテクスチャ色)などを考慮した着色計算が必要です。
     よって、上記のような色を計算するため、バーテックスシェーダ(頂点シェーダ)の情報が不可欠になります。
     このシェーダ連携についてはSTEP6で書かせていただきます。

    シェーダの生成&コンパイルは以下部分で実施しています。

    var shader;
    var shaderElement = document.getElementById(id);
    if (!shaderElement) {
    return null;
    }

    switch(shaderElement.type){
    case “x-shader/x-vertex”:
    shader = gl.createShader(gl.VERTEX_SHADER);
    break;
    case “x-shader/x-fragment”:
    shader = gl.createShader(gl.FRAGMENT_SHADER);
    break;
    default:
    return null;
    }

    //子ノード取得
    var source = “”;
    var childNodes = shaderElement.firstChild;
    while (childNodes) {
    if (childNodes.nodeType == 3) {
    source += childNodes.textContent;
    }
    childNodes = childNodes.nextSibling;
    }
    gl.shaderSource(shader, source); // ソース割り当て
    gl.compileShader(shader); // コンパイル

    見慣れないエレメントタイプがありますね。

    「x-shader/x-vertex」
    「x-shader/x-fragment」

    JavaScriptファイルではなく、HTMLファイルのheader部分も見てみてください。
    この2つのキーワードが上記で説明したバーテックスシェーダ(頂点シェーダ)とフラグメントシェーダ(ピクセルシェーダ)です。

    <script id=”vertex” type=”x-shader/x-vertex”>
    attribute vec3 vertexPosition;
    attribute vec2 vertexTexture;
    uniform mat4 vertexMatrix1;
    uniform mat4 vertexMatrix2;
    varying vec2 textureCoord;

    void main(void) {
    gl_Position = vertexMatrix1 * vertexMatrix2 * vec4(vertexPosition, 1.0);
    textureCoord = vertexTexture;
    }
    </script>
    <script id=”fragment” type=”x-shader/x-fragment”>
    precision mediump float;
    uniform sampler2D fragmentTexture;
    varying vec2 textureCoord;

    void main(void) {
    gl_FragColor = texture2D(fragmentTexture, vec2(textureCoord));
    }
    </script>

    中途半端にはなりますが…
    ここから説明が一気に難しくなる&細かくなり始めるので今回のブログはここまでにします。

    ではでは。


  • そうだ、アプリの研究しよう vol.0

  • videoタグで動画検証。

    少しHTML5のvideoタグについて検証したので纏めます。

    HTML5では、動画再生する為にタグが追加されています。

    このタグを使用することで、プラグインをインストールしてもらうことなく、
    HTML側から簡単に動画を扱えるようになります。

    細かい属性などについてはこちらをご確認下さい。

    以下のように各端末で読み込まれる動画を上から並べていきます。

    <video id="video" width="300" height="200" controls="controls" onclick="this.play()" preload="metadata">
    <source src="test.webm" type="video/webm">
    <!-- OGG/WebM 陣営向けの動画 -->
    <source src="test.ogv" type="video/ogg" media="all">
    <!-- MPEG-4 陣営向けの動画 -->
    <source src="test.mp4" type="video/mp4" media="all">
    </video>

    以下の指定で動画が再生されるはずが、落とし穴が二つ!
    まず、GALAXYS で再生が出来ない!
    GALAXYSは<video>タグを設置するだけでは再生できないようです。

    Javascriptで以下を指定し再生する必要があります。

    // JavaScript Document
    $(function(){
    	var video = document.getElementById('video');
    	video.addEventListener('click',function(){
    		  video.play();
    	},false);
    });

    その2!
    まさかのandroid 4.0 以降はストリーミング再生が不安定。

    android 2.0.× ~ 2.3.× などのバージョンは端末の動画プレイヤーを立ち上げるので
    読み込む時間が多少掛りますがみる事が出来ます。

    android 4.0 以上はストリーミング再生で重い動画だと
    音声だけが再生されたり、固まったり不安定です。(Wi-Fiでもかなりきつかったです。LTEなら快適かも?)

    1MB以下の短い15秒位の動画でやっと再生出来ました。
    再生したいのは約1.5MBの1分程の動画です。

    検証端末は
    ・GALAXYS android 2.3.6
    ・GALAXYS3 android 4.0
    ・iPhone4S、5
    ・他android端末
    です。

    まだまだ動画系はvideo タグでOK!というわけにはいかないようです・・・。

    もしかしたらjsの制御で改善出来るかもしれませんが調べた限りでは無さそうでした。

    android 4.0 も端末の動画プレイヤーで再生出来れば
    まだストレスを感じずに再生出来るのではないかと思います。

    なんとかならないかな― android


  • HTML5+WebGLのゲームが主流に!?WebRTCでKinectのようなゲームやソーシャルゲーム内のサムネイルが動画に!?

    どうも。営業部の伊藤です。

    今日は11/7です。
    先週末の日曜日は11/4です。
    そうなんです!そうです。
    3~4ヶ月前から着々と準備を進めていた、
    初ハーフマラソンの日でした。

    本来であればハーフマラソンを走った感想を書く予定でしたが、、、

    そうです。そうなんです!
    風邪をひいて参加できなかったんです。
    めちゃめちゃ楽しみにしていたハーフマラソンの日に体調不良がピークを迎え、自宅で引きこもりだったんです。
    よって、ハーフマラソンの感想は書けない事になりました。。。
    ※因みにブログを投稿した今日も回復していない状況の為、1週間以上長引いています。
    皆さんも体調管理には十分にご注意ください。

    そんなこんなで1日中引きこもりをしている中、9月頃FacebookのCEOであるザッカーバーグが発言した言葉を思い出しました。

    HTML5を過大評価したのは我々の最大の失敗

    ザッカーバーグが発言したように、まだまだスマートフォンアプリケーションの実装方法には課題を多く残しており、どこの企業もトライ&エラーの日々を繰り返しています。
    この発言だけ真に受けるとHTML5によるアプリケーションの実装方法はネイティブ実装に劣っていると感じる方が居るかも知れませんが、アプリのフレームのみネイティブで実装し、
    その他画面/UIはHTML + CSS + JavaScriptで実装するようなハイブリッドアプリで成功を収めている企業も多数あります。(クックパッドなど)

    実現したいものにより都度試行錯誤、検討が必要だと思いますが、個人的にはネイティブ実装は一部グラフィカルな描画を必要とするもの以外では利用されなくなり、その他のアプリケーションについてはHTML5やJavascript、Dartなどが利用されるようになると考えています。
    何故そう思うのか理由をいくつか並べてみます。

    1. ネイティブの強みであるデバイス機能の操作についても徐々にブラウザ側で対応が施されているため、じきにブラウザからネイティブに遜色なく利用が可能になる(と思う)。

    2. ウェブ向けプログラミング言語の高速化(安定板のSDKの提供が始まっているDartは、V8エンジンよりも高速にレンダリングが可能)によりオーバーヘッドが気にならなくなる。

    3. 通信回線速度の成長(LTE、そして4Gへ)により、サーバーサイドテクノロジーをより発揮できる実装手法/構築方法(ウェブ向けの開発)が選ばれるようになる。

    4. クロスプラットフォーム対策、工期短縮、価格圧縮、保守コスト軽減のため、テクノロジーが統一され始める!デバイス間の統一だけでなく、サーバーサイドとクライアントサイドのテクノロジーも統一される(して欲しい)。
    現状だとNode(JavaScript)、CoffeeScript、Dart、GWT(JAVA)などが選択肢にありますが、個人的にはGoogleの本気度や政治的問題や各々の言語の特性を考えると、1年後くらいにはDartが今以上に使われているのではと予想しております。

    5. Web技術の表現力の拡張(HTML5/CSS3を利用したパララックス効果やWebGLを利用した3D表現など)
    WebGL(OpenGL)についてはAndroid、iPhone(iAd広告のみ何故か対応)ともに一部Android端末以外未対応の状況ですが、近いうちに解禁されると思います。

    6. WebRTCの標準化(現状はChromeとOperaだけだが、Firefoxも実装を進めており、当初反対していたMicroSoftもサポートを計画している、いずれスマートフォンブラウザも!?)

    と色々とWeb贔屓の理由を書いてみましたが、もちろんネイティブが優れている点も多々あります。
    デバイス機能の操作や3Dグラフィカルなどは基本的にはバインディングになりますし、画像の描画においてもブラウザアプリケーション経由のためオーバーヘッドもあります。
    今後も当分は実現したい事、ユーザーに提供したいもの、重要視するもの、予算、工期など様々な条件のなか模索していくことになるでしょう。

    タイトルにも挙げましたが、個人的に特に注目しているのが上記理由の5点目に挙げた「WebGL」と6点目に挙げた「WebRTC」です。
    WebGLは「ブラウザ上で別途プラグインなしに3CGを表現できる」フレームワーク、WebRTCは「ウェブアプリケーション同士が”直接双方向通信”」できるフレームワークです。

    ○WebGL
    WebGLを用いたアプリケーションは今までにも数々登場していますが、まだまだインタラクティブなものは少なく、どちらかというと3次元空間で表現したビジュアルをブラウザでただ単純に見れるといったものが多いです。
    デバイスの対応状況、ソフトウェアの対応状況、技術的な難易度(ライブラリを使わずに全てを把握するとなると正直相当難しいと思います)など理由はいくつか挙げられますが、昨今のデバイスの拡張状況やライブラリの普及を考えると、今後はPlayStationやWiiのようなグラフィカルなゲームもブラウザ上で楽しむのがデファクトスタンダードになるのでは?とも感じています。

    WebGLを利用した参考サイトのURLをいくつか記載します。(ブラウザはChromeでご覧ください)
    http://webglsamples.googlecode.com/hg/aquarium/aquarium.html
    http://alteredqualia.com/three/examples/webgl_animation_skinning_tf2.html

    PlayStationもそう遠くはないですね。
    顔写真だけで高品質な3D顔を生成できるものもあります。
    ヨーロッパのVizagoです。※動画

    すごいですね!

    現在このWebGLの「3D表現の仕組み」を個人的にまったく理解できていないため、基礎から勉強をしようと奮闘中です。
    結果についてはまたどこかで投稿させていただきます。

    ○WebRTC
    直接双方向通信できますので、ブラウザ上で音声やビデオチャットをRTC(リアルタイムコミュニケーション)することが可能になります。
    Cometのように擬似的に同期を表現、且つサーバートリガーで双方向通信する訳ではなく、最近のブログで書いたWebSocketのようにWebアプリケーショントリガーでサーバーと双方向通信する訳でもないです。
    ウェブアプリケーション同士で直接双方向通信できるというのがポイントです。
    Chrome21から標準で使えるようになっており、KinectのようなゲームやブラウザとiOSデバイスの両方でビデオチャットができる世界も登場しています。

    WebRTCについてはWebGLの基礎を習得してから勉強してみます。
    こちらについてもまたどこかで投稿させていただきます。

    ではでは。