2015年5月22日金曜日

透視投影におけるカメラのNearとFarと最終的なZの関係

通常,3Dグラフィックスでは奥行きのZが-1から1の範囲に変換されます.
ただし,0から1というような環境もあります.

この際に,透視投影カメラを使うと,Zの座標がNearからFarまで変化したとき(横軸),最終的なZの値(縦軸)との関係は,下の図のようになります.



見て分かるように,Nearに近いZ座標の変化は,最終的なZ座標の変化でも大きな差になっているのに対して,Farに近いZ座標の変化は,最終的なZ座標の変化では差が小さくなっています.

つまり,遠くのものほど,Zの違いが最終的なZの違いにならない,ということです.すると,モデルの前後関係が崩れてちらつきが発生するZファイティング,という現象が起こりやすくなります.

Zファイティングが起きる場合に,接しているモデルを少し離して起きないようにする,という対策も間違いではないですが,Nearを大きくして,表示したいもののZの差が最終的なZの差に反映されるようにするのも一つの手です.

2015年5月11日月曜日

明解WebGLを頂きました.

WebGL開発支援サイト wgld.orgWebGL総本山を運営する@h_doxas(杉本 雅広)さんがリックテレコムから「明解WebGL iOS/Androidも対応した3D CGプログラミングのWeb標準」を出版されました.

本を頂き,発売前に読む機会を得たので,感想を書きたいと思います.

明解WebGLは,「WebGLそのもの」について解説した入門書です.最近は,Unreal Engine 4やUnityもWebGLをサポートしており,WebGLを使ったコンテンツも増えてきており,WebGLへの注目も高まっています.しかし,意外なことに,何らかのライブラリを用いてWebGLを使った何かを作る方法を解説した本はいくつも出版されているものの,「WebGLそのもの」について解説した和書は2012年以来出版されていなかったのです.(確認漏れがあったらゴメンナサイ.)

ライブラリを使って面倒な部分を省略するのも悪くは無いのですが,それは基礎という土台があってこそです.基礎という土台が無ければ,何が省略されているのかも分からないので,何か困ったことがあったときに,思いつけることが限られてしまいます.

本書は,次のような方にお薦めです.
  • コンピュータグラフィックスに興味があるが,まだ触れたことが無い
  • 細かい解説を読むよりも,まずは手を動かして覚えたい
本書のあちこちに似たような表現が登場するのですが,本書では「まず動かしてみる」ということを重視しています.いきなり全てを理解する必要はない,まずは「できた」という感覚を大切にして欲しい,少しずつ学んで行けば良い,などなどです.

そのため,既にOpenGLなどを触ったことがある人には,少々物足りない内容に感じるかもしれません.

しかし,本書にはWebGLについて調べる場合のヒントや,実際に表示するモデルデータを入手する方法,WebGLでのデバッグ方法など,各種端末での実行やデバッグ方法など,入門書を読み終えた後に困りそうなポイントについても,さりげなくフォローされているため,OpenGLを触ったことがある人がさっとWebGLを覚えるのにも良いでしょう.

本書を読み終えた後は,WebGL開発支援サイト wgld.orgWebGL総本山を参照し,更に理解を深め,アイデアを磨いていくと良いでしょう.

個人的には,何か新しいことを覚える場合にはまず手を動かしてみることを重視しているので,この本は今からWebGLを学ぼうと考えている人にはお薦めです.

紙面の都合上,プログラムの全てが載っているわけではないので,どうしてもサンプルサイトを見ながら書き写すことになり,ついコピーして貼り付けしたくなるかもしれませんが,是非一度は自分でプログラムを打ち込んでみてください.実際に手を動かしてみると,色々とミスをするかもしれませんが,それを解決していくことも経験になると思います.

実際,自分も仕事ではOpenGL系のAPIを利用しているのですが,WebGLで色々と試して学んでいたことで,仕事で問題が起きたときの気付きへとつながったことが何度もありました.

今後WebGLはますます盛り上がっていくと思います.皆さんも本書を読んで,WebGLに触れてみませんか?

2015年5月6日水曜日

WebGLContextAttributesの切り替え

WebGLでは,canvasからgetContext()でWebGLRenderingContextを取得する際に,WebGLContextAttributesといういくつかの設定を渡すことができる.
var canvas = getElementById('canvas');
var options = { alpha : true };
var gl = canvas.getContext('webgl', options) || canvas.getContext('experimental-webgl', options);

この設定は,コンテキストの生成時にのみ利用され,それ以降は変更することができない.

実験的に色々切り替えてみたいときに不便だし,なんとかならないかなぁ,と思っていたけれど,生成時にしか設定できないなら,canvasを生成し直せば良いのでは,と思ったのでやってみた.

// アルファチャンネルのオンオフを設定するチェックボックスの要素を取得
var alpha = document.getElementById('alpha');

alpha.addEventListener('change', function(){
  // ノードを複製する
  var newCanvas = canvas.cloneNode(true);

  // WebGLContextAttributes設定用オブジェクトの生成
  var options = {};
  options.alpha = alpha.checked;

  // WebGLRenderingContextの差し替え
  gl = newCanvas.getContext('webgl', options) || newCanvas.getContext('experimental-webgl', options);

  // canvas要素の入れ替え
  canvas.parentNode.replaceChild(newCanvas, canvas);
  canvas = newCanvas;
}, false);

とりあえずいくつかのブラウザで試してみたが,上手く動いているみたい.

他に良い方法があれば知りたい.

以下サンプル.背景のクリアカラーを設定できて,アルファチャンネルの有無を切り替えられる.