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);

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

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

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
















2015年2月21日土曜日

失敗から学ぶユーザインターフェースの読書感想

失敗から学ぶユーザインターフェース (出版社紹介ページへ)

色々な本を読んでいるが,基本的に自分にとっては有益でも他人にとってはどうか分からない本は紹介しないようにしている.しかし,この本はUIに関わる人であれば必ず読むべきだと思ったので紹介しておく.

この本をざっと読んで思ったのが,よくもこれだけ可笑しなユーザーインターフェースを集めたものだ,ということだ.この本に載っているユーザーインターフェースを見れば,おそらく多くの人は,「誰だっ,このユーザーインターフェースを設計したのは!」と言いたくなるだろう.(某料理漫画の人物を思う浮かべて欲しい).

しかし,この本を読まず,色々なユーザーインターフェースを考慮せず,自分で良いと思うユーザーインターフェースを考えてデザイン優先でユーザーインターフェースを作ると,こういうことが起こるのでは,と思うのも確かだった.

自分が良いユーザーインターフェース,良くないユーザーインターフェースについての講義を受けたのは10年も前になるが,未だにそういったものが世の中にあふれていることを考えると,未だに多くのユーザーインターフェースデザイナーは見た目でユーザーインターフェースを考えていて,ユーザーがどう受け止めるか,アフォーダンスを考慮できていないのではないか,と考えてしまう.

10年前に受けた講義以降,ときおり遭遇したユーザーインターフェースについての善し悪しを考えるのだけれど,未だにどう見ても押すデザインなのに引く必要があったり,引くか押すかのデザインに見えるのにスライドするドア,なんてものがあったりする.

ちなみに,自分の知っているユーザーインターフェースデザイナーはそういった点も考慮した上でのデザインを考えているので,皆がそうだとは思えない.

とにかく,ユーザーインターフェースデザイナーもユーザーインターフェースプログラマーも,是非,この本は読んでみてもらいたい.(とりあえず会社では紹介しておこうと思う).

最後に一言を言うとすれば,タイトルのユーザは情報系では常識なものの,この本を読むであろうユーザーインターフェイスデザイナ的にはユーザーの方が良かったのでは,と言っておきたい.

(。ではなく.を使うのは情報系の日本語論文はそうするものだ,と教えられた癖である).

2015年2月10日火曜日

PopcornFXのUE4デモを見るまで

先日行われたVFX技術者交流会に参加し,PopcornFXというエフェクトツールの名前が出て,気になったのでUE4デモを落としてみました.

その際の手順が英語でちょっと分かりにくいので,手順を紹介します.

  1. PopcornFXのUE4用サイトにアクセスします.
  2. 手順に従い,登録サイトで登録を行います.
    • ログインはユーザーIDのことです.アルファベットにしておくのが良いでしょう.
    • パスワードは適当に.ある程度長めが良いでしょう.
    • 苗字と名前は日本語でOK.
    • メールアドレスは,この後の手順でメールを送るので,その際に使用するアドレスと同じにしておいた方が良いでしょう.
  3. 登録が出来ると,管理者の承認待ち,と表示された画面に移ります.
  4. PopcornFXのUE4用サイトの手順2に従い,メールを送ります.メールアドレスは,スパム対策として@ が at,. (ドット) が dot と太字で書かれています.ここでメールアドレスを書いてしまうと台無しになるので,サイトの方を見てアドレスを確認してください.
    • メールの内容は,自分の名前とPopcornFXへの興味を少々,とのことです.とりあえず,1行興味があるんです,ということを英語で書いて送ったらOKだったので,英語は苦手,という方もGoogle翻訳を使うなどしてみましょう.
  5. しばらく待っていると,承認メールが届きます.
  6. ダウンロードページにアクセスし,必要なファイルをダウンロードします.なお,理由は分かりませんが,私がダウンロードした際は非常にダウンロード速度が遅かったので,しばらく放置するくらいの覚悟でいてください.
PopcornFX_UE4_demoというファイルをダウンロードすると,中にUnreal Engine 4のプロジェクトファイルが入っているので,起動するとデモを確認できます.
なお,7zipというフォーマットの圧縮データを解凍できる解凍ツールが必要になります.

2014年12月26日金曜日

やってはいけないCG制作の感想

やってはいけないCG制作 (ボーンデジタル)

読みました.
感想としては,これはアーティストだけでなくアーティストから素材を受け取る側も是非読んで欲しい一冊だな,と思いました.

内容としては,新人アーティストがやらかしてしまった色々を上司かつ教師役の方が修正方法などを教えていく対話形式になっています.会話のテンポが良いこともあって,非常にサクサクと読み進めることができました.

まず良いなと思ったのは,教師の高野さんが新人の守本さんに色々と説明をする際に,この説明だと分かってなさそうだな,と感じたら別の例えなどで説明する,という一連の流れがあることです.あっ,新人ってこういう勘違いしてたりするんだ,こう言い換えるのもありなのか,など色々と勉強になります.プログラマにしてみれば,アーティストに何らかの技術の説明をする場合の参考になります.

例えば,アーティストから受け取ったデータが上手く扱えない場合に,プログラムに問題があって扱えないのか,そもそもデータに問題があるのかを判断する必要があります.アーティストがやってしまいそうなミスを知っていれば,まずそれをチェックしてみる,という選択肢が増えます.

また,アーティストに修正を依頼する際も,具体的な修正方法を指定できれば,アーティストにあれこれ問題点を調べてもらって,クリエイティブな作業をする時間を削る,ということも減ります.
提出してもらうデータの指定をする際にも,少しでも具体的な指定が出せれば,やり直しを減らすことができます.

ボーンデジタルの訳書はお高いことが多いですが,この本は訳書ではなく2,100円(税抜き)とお買い得です.新人アーティストにそっと渡すのも良いかもしれません.もちろん,ベテランでも何でも知っているというわけではないので,後輩に教えるときに参考になりますよ,と言って渡したりして勘違いを修正してもらうのも良いかもしれません.

この本みたいに,やってはいけないプログラミング,みたいな本が出て欲しいところです.

2014年12月12日金曜日

UMGで電卓を作る

この記事は,Unreal Engine 4 Advent Calendar 2014の12日目の記事です.
昨日の記事は,@aizen76さんのUE4で使えるプラグインいろいろでした.

先週の記事では,UMGのレイアウト用ウィジェットを紹介しました.
今日は実践編として,UMGを使って電卓を作ってみます.なお,UE4のバージョンは4.6となっています.

まず,適当なプロジェクトを作って,UMGのブループリントを追加します.コンテンツブラウザ上で右クリックメニューを開き,ユーザーインターフェースからWidgetブループリントを選びます.名前はとりあえずCalcとしておきましょう.

いったん解説に使う予定の画像だけ掲載します.この画像を見るだけでも何となく電卓は作れるかもしれません.
間に合えば今晩に解説を載せます.

間に合いませんでしたが,解説はちゃんと書きます.細かいことは画像の中に書いてたりするので,画像の方を参照してください.なお,ブループリントの基本は理解しているものとして話を進めます.

コンテンツブラウザを右クリックし,ユーザーインターフェースからWidgetブループリントを追加します.


メニューのブループリントの横の三角からレベルブループリントを開き,ゲーム開始時にウィジェットが表示されるようにします.


レベルブループリントに書き込む内容は,次の図のようにCreate Widgetノードとadd To Viewportノードです.


先ほど追加したWidgetブループリントをダブルクリックし,まずはデザインを決定します.電卓はマス目状にボタンを配置すればできるので,Grid Panelを利用します.ルートのCanvas Panelを削除して,Grid Panelを配置します.


Grid Panelを配置したら,詳細から4列(Column)と5行(Row)を追加します.追加した行や列の重みは1にしておいて,均等な幅になるようにします.

列と行の追加ができたら,ボタン(共通の中のButton)を配置していきます.ボタンの中にはテキストを追加して,それぞれの数字や演算子(+,-,/,*,=)を入力します.最後に,結果表示用のテキストを一番上に配置します.



デザインが終わったら,グラフエディタに移り,変数タイプIntegerの変数resultを追加します.この変数には,計算結果を格納します.


変数を追加したらコンパイルしておきましょう.


コンパイルが終わったらデザイナに戻り,結果表示用のテキストを選びます.テキストの表示内容として,先ほど追加したresultを読み取るように,プロパティバインドを作成します.


バインドを作成するとグラフエディタに移るので,単純にマイブループリントからresultを引っ張ってきて,取得するようにし,resultをReturn Valueにつなぎます.


この時点で実行してみると,見た目はそれっぽくなります.


では,まずは数を入力できるようにします.数字のボタンを選択し,詳細の下の方からAdd OnClickedを押しましょう.


グラフエディタに移り,OnClicked(ボタン名)が表示されていると思います.電卓の挙動を見てみると,数字のボタンを押す度に右側に数字が追加されていきます.これは,resultに入っている値を10倍して押したボタンに対応する数を足した値をresultに設定することと同じです.これを書いたのが次のブループリントになります.


まずは0のボタンで作ってみました.次は1のボタンを押した場合を作ってみましょう.


上の図の赤で囲った部分以外違いがありません.同じような処理を2度作った場合,関数やマクロにすることを検討しましょう.今回は,関数化しておきます.マイブループリントから関数追加を選び,Add Valueという名前を付けます.


関数を作った場合,何か入力が必要な場合は自分で追加する必要があります.この場合,どのボタンを押したのか,という情報が必要なので,外からvalueという名前で入力できるようにします.後は,最初に0のボタンを押した場合に作ったブループリントと同じになります.

これを全ての数字のボタンに適用すると,次のようなブループリントになります.


この時点で画面にウィジェットを表示させて数字のボタンを押すと,電卓のように数字が表示されます.ただし,扱える数値の上限を超えている場合の処理が無いので,途中から変な数値に変わっていきます.

さて,ここからが本番です.電卓なので,ちゃんと足し算やかけ算ができるようにしていきます.電卓の挙動を見てみると,演算子(+や-など)を押した後,次の数字を押すまでは前に入力した値が表示され,数字のボタンを押した瞬間に新しい値に表示が変わります.つまり,演算子ボタンを押した後に数字のボタンを押したかどうかを覚えておく必要があります.また,ある演算子ボタンを押した後に数値を入力し,再度何かの演算子ボタンを押すと,計算が実行されます.そのため,直前に押されている演算子ボタンが何かといった情報が必要です.

そこで,次のような変数を追加します.

mode (Integer)
直前に押した演算子ボタンの種類を覚えておくための場所です.
stack (Integer)
途中までの計算結果を保存しておく場所です.
stackUsed (Boolean)
stackに何か格納しているかを表します.何か値が入っているならtrue,入っていなければfalseになります.
digitPushed (Boolean)
数字のボタンを押したかどうかを表します.何かしらのイベント後に一度でも数字のボタンを押していればtrueになります.


追加した変数を組み込んでいきます.まず,Add Value関数の中で,数字を押した後には必ずdigitPushedがtrueになるように,digitPushedの設定ノードを組み込みます.


結果を表示するためのテキストのプロパティバインドに使っている関数は,次のように変更します.
まず,resultだけでなくstackの結果も取得し,Select Intノードを使ってどちらかを選んだ上でReturn Valueにつなぐようにします.


選択の条件は,スタックに何か入っていて,数字ボタンを押していない場合にstackを選ぶことなので,そのようにstackUsedとdigitPushedを取得して,上記を参考にノードをつないでいきます.NOTは否定用のノードで,digitPushedに対してNOTを使うと,ボタンを押していない時にtrueになり,ボタンを押した後はfalseになります.

ANDノードは,入力の両方がtrueの場合にtrue,それ以外の場合はfalseになるので,stackUsedかつdigitPushedではない,という条件ができあがります.あとは,ANDの結果をSelect Intノードにつなぎます.

ここまできたらあと一息です.最後に,modeに合わせてstackの内容などを更新するUpdate By Mode関数を追加します.

まず,modeの値によって条件分岐をするため,モードがどの数値かを判定する処理を作ります.
modeを取得し,Equalノードで値を比較します.


  • 0は何も押していない状態
  • 1は+を押した状態
  • 2は-を押した状態
  • 3は*を押した状態
  • 4は/を押した状態

まず,何も押していない状態の場合,resultの値をstackに退避させます.



次は,+が押されている場合と-が押されている場合です.それぞれ,stackの値とresultの値を+ノードで足したり,-ノードで引いたりして,結果をstackに戻します.-の場合,stack - resultとresult - stackは結果が違うので,ノードをつなぐ順番に注意しましょう.


最後は,* (かけ算)と/(割り算)です.こちらも処理は+や/と変わりませんが,割り算は順序に気をつけましょう.


最後に,それぞれの計算結果をstackに設定した後に,stackUsedをtrueにし,resultを0に再設定し,digitPushedをfalseにする共通の終了処理につなぎます.


デザイナでそれぞれの演算子ボタンから,Add OnClickedでイベントを追加し,以下の図のようにUpdate By Modeを呼び出した後にmodeを適宜設定するようにノードをつなぎます.


最後に,=を押した場合,stackに何かしらデータが入っていれば,Update By Modeを呼び出して,計算などを終わらせておき,stackの値をresultに戻し,stack,stackUsed,modeをリセットするようにします.

これで,電卓はいったん完成です.実行して,簡単な計算をしてみましょう.

正直なところ,電卓なんて簡単だろう,と思っていたのですが,結構色々と考えることがあって,ちゃんと作るとなると結構面倒でした.UMGの実践例としてはあまり良くなかったかな,という気もするのですが,無駄にハイスペックを要求する単なる電卓,という誘惑には勝てませんでした.

ここで作った電卓はあくまでも簡易的なものなので,もっとUMGを弄って色々な機能を追加してみてください.


明日というか今日は,@monsho1977さんで,何かしらネタになるマテリアルを作るそうです.
楽しみですね.