SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

JavaScriptとWebGLによるはじめての3Dプログラミング

「three.js」でつくるお手軽3Dマンガ作成ソフト - 前編

JavaScriptとWebGLによるはじめての3Dプログラミング(1)

ダウンロード サンプル (335.1 KB)

シーンとカメラとレンダラーの準備

「three.js」の読み込み

 まず、「three.js」を「script」タグでHTMLファイルに読み込みます。本記事では「jQuery」も使うので、こちらも同様に読み込みを行ってください。

 「three.js」をHTMLファイルに読み込むと、「three.js」は「THREE.WebGLRenderer 58」といったメッセージをコンソールに出力します。しかし、一部のブラウザではコンソールが存在しないために、この時点でエラーが出ます。エラーを回避したい場合は、以下の「console.js」のようなコードを、「three.js」の前に読み込むと、エラーが表示されません。

「three.js」の読み込み
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<script charset="UTF-8" src="js/console.js"></script>
<script charset="UTF-8" src="js/three.js"></script>
「console.js」
// Init Console.log
if (typeof window.console === "undefined") {
    window.console = new function() {
        this.log = function() {};
        this.error = function() {};
    };
}

カメラの設定と位置

 「three.js」で3D空間を描画するには「カメラ」と「シーン」と「レンダラー」の3つのオブジェクトを作成する必要があります。まずは、このカメラについて説明します。

 カメラを初期化する際は、4つの値「視野角」「アスペクト比」「近距離限界」「遠距離限界」を設定します。

 「視野角」の値を大きくすると、広い範囲を一度に見ることができますが、画面の端の方では物体が歪みます。対して値を小さくすると、狭い範囲しか見ることができませんが、画面の端の方でも歪みが少ないです。今回はマンガのコマを作るので、歪みが少なくなるように、値を小さくします。

 「アスペクト比」は、「横/縦」の値です。これは作成する描画領域を元に計算します。

 「近距離限界」「遠距離限界」は、3Dプログラミングが初めての場合には戸惑う値だと思います。3Dプログラミングでは、カメラが向いている方向の、すべての物体を描画するわけではありません。カメラに近すぎる物体や、遠すぎる物体は、計算を行わず描画をしません。

 これは無駄な計算をしてマシンに負荷を掛けないための仕組みです。「近距離限界」よりもカメラに近い物体は描画されません。また「遠距離限界」よりもカメラから遠い物体も描画されません。

 この仕様は、3Dプログラミングを始めて行う際には、見落としがちな所です。物体を作成しても、カメラに近すぎたり、逆に遠すぎたりして、何も表示されないということがよくあります。

 最後に、カメラの位置を変更します。なぜカメラの位置を変更するかというと、初期化の時点では原点(0, 0, 0)の位置にカメラがあるからです。これから物体を作成する際に、カメラが原点にあると、物体が近すぎて表示されません。そのため、カメラを少し下げて、作成する物体がうまく表示されるようにします。

 カメラを含め、「three.js」の3Dオブジェクトには「位置(position)」「回転(rotation)」「拡縮倍率(scale)」の値があります。この中でカメラで使うのは、位置と回転でしょう。本記事ではカメラは固定して使うので、位置のみを利用します。

「three.js」の3Dオブジェクト
obj3d = {
     position: {x: 0, y:0, z: 0}
    ,rotation: {x: 0, y:0, z: 0}
    ,scale:    {x: 0, y:0, z: 0}
    ,…
};
カメラの初期化
// カメラの初期化
camera = new THREE.PerspectiveCamera(
    10,        // fov(視野角) 10ぐらいが歪みが少ない
    w / .h,    // アスペクト比
    1,         // near 近距離限界
    10000      // far 遠距離限界
);
camera.position.z = 4000;    // カメラ位置を移動

 また、シーンも作成します。シーンには、カメラを追加します。

シーンの初期化
// シーンの初期化
scene = new THREE.Scene();
scene.add(camera);

「Canvasレンダラー」と「WebGLレンダラー」

 「three.js」には、「Canvasレンダラー」と「WebGLレンダラー」が存在します。「Canvasレンダラー」は、WebGLに対応していないブラウザでも、「Canvas」を利用して3D表示を行うためのレンダラーです。ただし、かなり重いです。実用レベルで使いたいのならば、「WebGLレンダラー」を選択して、対応するブラウザを利用するのがよいでしょう。

 「レンダラー」を初期化する際は、アンチエイリアスの有無など、各種パラメータを付けることができます。設定可能な引数は「WebGLRendererのドキュメント」で確認可能です。

 また、レンダラーは「setSize」で描画サイズ(Canvasのサイズ)を設定します。その後、「domElement」を、DOMツリーに追加することで、Webページ上に「WebGL」の表示を行うことができます。

レンダラーの初期化
// レンダラーの初期化
renderer = new THREE.WebGLRenderer({
    preserveDrawingBuffer: true,
    format:                THREE.RGBAFormat,
    antialias:             true
});
renderer.setSize(w, h);

// コンテナーにキャンバスを格納
cntnr.empty();    // 空にする
cntnr.append(renderer.domElement);    // DOM要素を追加

初期化までの「まとめコード」

 ここまでの初期化処理をまとめた「crocro.bc.js」を掲載します。本記事の処理については「crocro.bc」(bcはBoxComicの略)オブジェクトにすべて格納するようにしています。また、Three.jsに関わるようなオブジェクトは「crocro.bc.d3」以下に格納するようにしています。

「crocro.bc.js」
//= 3D表示の基本部分の関数群

//== パッケージの初期化
if (typeof crocro === "undefined") {var crocro = function() {};}
if (typeof crocro.bc === "undefined") {crocro.bc = function() {};}

crocro.bc.cntnr = null;    // 格納要素
crocro.bc.ui    = null;    // UI要素
crocro.bc.d3    = {};      // 3D格納用

//========================================
//== コンテナーの初期化
crocro.bc.initContainer = function() {
    // 変数の初期化
    var d3 = crocro.bc.d3;    // 3D格納用
    d3.w = 640;
    d3.h = 480;

    // コンテナーの初期化
    crocro.bc.cntnr = $("#container");
    var cntnr = crocro.bc.cntnr;
    cntnr.width(d3.w).height(d3.h);    // 縦横をセット
    cntnr.empty();    // 空にする
}

//== 構築
crocro.bc.build = function() {
    // 変数の初期化
    var d3 = crocro.bc.d3;    // 3D格納用
    var cntnr = crocro.bc.cntnr;    // コンテナー

    //=== カメラの初期化
    d3.camera = new THREE.PerspectiveCamera(
        10,             // fov(視野角)10ぐらいが歪みが少ない
        d3.w / d3.h,    // アスペクト比
        1,              // near 近距離限界
        10000           // far 遠距離限界
    );
    d3.camera.position.z = 4000;    // カメラ位置を移動

    //=== シーンの初期化
    d3.scene = new THREE.Scene();
    d3.scene.add(d3.camera);

    //=== レンダラーの初期化
    d3.renderer = new THREE.WebGLRenderer({
        preserveDrawingBuffer: true,
        format:                THREE.RGBAFormat,
        antialias:             true
    });
    d3.renderer.setSize(d3.w, d3.h);

    // コンテナーにキャンバスを格納
    cntnr.empty();    // 空にする
    cntnr.append(d3.renderer.domElement);    // DOM要素を追加
};

//== レンダリング実行
crocro.bc.render = function() {
    var d3 = crocro.bc.d3;    // 3D格納用
    d3.renderer.render(d3.scene, d3.camera);
}

//== UIのリセット
crocro.bc.resetUI = function() {
    $("window").unbind("blur");    // イベント削除

    crocro.bc.cntnr.unbind();    // イベント削除

    crocro.bc.ui = $("#ui");
    crocro.bc.ui.empty();     // 空にする
    crocro.bc.ui.unbind();    // イベント削除
}

//== 切り替え時の終了処理
crocro.bc.finalizeFnc = null;

crocro.bc.setFinalize = function(arg) {
    crocro.bc.finalizeFnc = arg;
}

crocro.bc.execFinalize = function() {
    if (typeof crocro.bc.finalizeFnc === "function") {
        crocro.bc.finalizeFnc();
    }
    crocro.bc.finalizeFnc = null;
}

 また、実行を開始する「main.js」も掲載します。

「main.js」
//= 読み込み後実行
$(document).ready(function() {
    //== ブラウザ判定
    if (/*@cc_on!@*/false) {
        return;    // IEなので終了
    }

    //== コンテナーの初期化
    crocro.bc.initContainer();

    //== リストの値を設定
    $("#lstSmplTyp > option").each(function() {
        var ths = $(this);
        ths.val(ths.text());
    });

    //== 実行ボタンの処理
    $("#btnSmplTypExec").click(function() {
        // 3Dの初期化
        crocro.bc.execFinalize();    // 終了処理
        crocro.bc.build();    // 構築

        // UIの初期化
        crocro.bc.resetUI();

        //========================================
        // サンプルによる分岐
        var smplType = $("#lstSmplTyp").val();

        if (smplType == "基本オブジェクトの表示") {
            crocro.bc.viewBasicObject();
        }
        // 以降、サンプル作成ごとに追加。
    });
});

 これで準備はできました。この先は、「crocro.bc.js」「main.js」が読み込まれているという前提で話を進めます。また、作成したファイルは、以後の記事においても、すべて読み込み済みということでご案内していきますので、ご承知おきください。

 では次ページでは、立方体を作成して表示してみます。

次のページ
立方体の表示

この記事は参考になりましたか?

JavaScriptとWebGLによるはじめての3Dプログラミング連載記事一覧

もっと読む

この記事の著者

柳井 政和(ヤナイ マサカズ)

クロノス・クラウン合同会社 代表社員http://crocro.com/オンラインソフトを多数公開。プログラムを書いたり、ゲームを作ったり、記事を執筆したり、マンガを描いたり、小説を書いたりしています。「めもりーくりーなー」でオンラインソフト大賞に入賞。最近は、小説家デビューして小説も書いています(『裏切りのプログラム』他)。面白いことなら何でもOKのさすらいの企画屋です。 

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/7208 2013/06/21 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー