2015/12/16

VirtualBoxにUbuntuをインストールしてnode.jsを立ち上げるまでのメモ

こんにちは.@rootxです.

所要でubuntuを使いたくなったので,VirutalBoxで環境を整えます.

環境

  • Win7 Pro 64bit
  • CPU i7-6700
  • MEM 16GB (pc3-12800)
  • GPU GeForce970

手順


1. VirutalBoxをインストール

ここから. https://www.virtualbox.org/wiki/Downloads

VirtualBox 5.0.10 for Windows hosts

> VirtualBox 5.0.10 Oracle VM VirtualBox Extension Pack All supported platforms
の両方をダウンロード.
前者はVirtualBox本体.後者は物理的なPCのデバイスサポートみたいなイメージ.(Support for USB 2.0 and USB 3.0 devices, VirtualBox RDP and PXE boot for Intel cards. )

VirtualBox-5.X.XX-XXXXX-Win.exeを実行して,デフォルトでインストール.
起動だけ確認して一旦終了.
# 日本語化されているんですね.少し驚き.

続いて,
Oracle_VM_VirtualBox_Extension_Pack-5.0.10-104061.vbox-extpackをダブルクリックするとVirtualBoxが起動され,「機能拡張パッケージをインストールする?」と聞かれるのでダイアログにしたがって進める.
「インストールに成功しました」などとダイアログが出ればOK.


2. VirtualBoxにubuntuをインストール

ubuntuのISOイメージからインストールする手段もありますが,
ubuntu JapaneseTeamで仮想ハードディスクイメージが公開されているので,それを使います.
(少しバージョンが古いですが)

https://www.ubuntulinux.jp/download/ja-remix-vhd から,「Ubuntu 14.04 LTS - 2019年4月までサポート」にある「ubuntu-ja-14.04-desktop-amd64-vhd.zip 」

手順もそこにある通りだが,linux 32bitしかメニューから選択でてきませんでした.
BIOSが怪しいのかな?と思いましたが,一旦windowsを再起動したら,出てくるようになりました(謎).


ハードディスクで「すでにある仮想ハードディスクファイルを使用する」から,先ほどダウンロードしたZIP,を解凍して作成されたvhdファイルを指定.(100GB指定)

起動すると,ubuntuの初回セットアップが始まるので適当に進める.


さくっと動作できたので一旦VMシャットダウン.

設定を変更
* システム>プロセッサ:2コア
* システム>マザーボード>メインメモリー:1GB
* ディスプレイ> スクリーン>ビデオメモリー:128MB
* ディスプレイ> スクリーン>アクセラレーション:3Dアクセラレーションを有効化をON


再度起動して,(なにかエラーが出ましたが無視して),ウィンドウの「デバイス」メニューを開き、「Guest Additions のCDイメージを挿入」を選択 (これは忘れがち)


あとは,ubuntuのソフトウェアアップデートがあるはずなので,適宜適用する.
左のメニューの一番上から,updateと入力して,「ソフトウェアの更新」を実行.
終わるまで結構時間がかかるので,一服してから再開します.





3. node.jsを起動する



 でわでわ.

2015/09/30

Unityでレイトレ

こんにちは.@rootxです.

Unityをアセット管理として用いたレイトレプログラムを書いてみましょう.

Unity5でレイトレーシング

はじめに

なぜUnityで行うか?

先日から少しだけUnityを操作しているのですが,最近のゲームエンジンらしく物理ベースマテリアルに対応している上に,いろんなローダやアセットがたくさんあって,自分で書くよりこれでいいじゃん,と思ったところが始まりです.
ベタのレンダラを書いたことのある人はお分かりかと思いますが,最初に絵を出力するまでに,レンダリング以外の処理を書くのがすごく大変です.例えば,ファイルの読み込みや,画像として保存する,テクスチャに対応する,などなどです.ちょっとプレビューしたいと思ったり,それにGUIを付けたいと思っても,なんだかよくわからないことを,たくさんたくさん調べて書く必要があります.

そこで,

本論の目的は,初学者(私も含め)向けにレンダラの本質(と思われるところ)に焦点を
また,高速化や多くのテクニックの必要性を体験してもらうことです.

なお他のアプローチとしては,任意のフレームをobj等に出力して,自作あるいは既存のレンダラでレンダリングする,という方法もあります.

開発環境

os x 10.10
Unity 5.2.0f3
UnityScript (C#)

開発指針

レイキャスト,古典的レイトレ,パストレの流れを追う.
マテリアルはstandard shaderの設定を使う.
テクスチャ対応.
高速化手段はあまり考えない.
MMDモデルのレンダリングくらいまで.

ここから

準備(適当に)

新規プロジェクトを作成.
適当なオブジェクトの配置.
カメラの設定.
スクリプトを作成.
カメラに,作成したスクリプトをアタッチ.

とりあえず,こんな感じにしてみました.
Unity inital scene

絵を出す(モノクロから)

レイトレーシングの基本的な考え方は,視点(カメラ)からたくさんの視線(レイ)を飛ばして,当たったオブジェクトの位置に基づいていろいろ計算して,色を決定します.

Unityでは便利なAPIがたくさん用意されているのでそれを使って,色の決定の部分を書いていく,という感じで進めます.

レンダリング結果を保持するキャンバスを用意して画面に表示する

レンダリング結果は,テクスチャに描画します.

最初にテクスチャを用意します.今回は,スクリーンサイズと同じサイズのテクスチャをStart()で確保し,レンダリングのためのRendering()を呼びだします,


全画素について処理を行うため,横方向(width)と縦方向(height)の2重ループとなります.
レイトレースを行うには,各ピクセルにおいて,カメラから発するその画素位置を向いたレイを生成し,その結果に応じて色を計算します.

この時点では,まず単純な背景色(黒)をテクスチャへ書き込み,そして画面への表示を行うだけの処理にします.
UnityのColorは不透明度を持っているので,黒の場合は (0.0f, 0.0f, 0.0f, 1.0f)とします.
また,数値で場合は必ずfloat精度として記述してください.うっかり new Color(0.0, 0.0, 0.0 1.0)のように記述すると,コンパイルに失敗してUnityがエラーとなってしまいます.
すべてのピクセルに色を設定したら,テクスチャのApply()で反映することを忘れないようにしてください.
描画した内容を画面に表示するために,OnGUI()コールバックを用意して,テクスチャを画面を覆うような領域に描画します.


https://gist.github.com/cslroot/c66ebadf2ad3651bcab3
この状態で実行すると,真っ黒になると思います.
背景色として指定したbackgroundColorの値をいろいろ変えて,指定した色になることを確認してみましょう.
ここまでできれば,各ピクセルの色をどのように決定するか,という部分に集中して取り組むことができるでしょう.

レイを飛ばして,当たったところを表示する

Unityでは,Physics.Raycast()という大変便利な関数が用意されています.このAPIは,任意の位置(座標)と指定の方向(ベクトル)を指定することで,その半直線の交差情報を取得することができます.
交差情報は,単純に当たった/当たっていないだけではなく,どの物体(シーン内のGameObject)にあたったか,その位置,法線,uv座標なども取得することが可能です.

注意:当たったかどうか,はCollider(コライダ)と呼ばれるコンポーネントで判定されます.Colliderがアタッチされていない要素には当たり判定がないため,Raycast()では無視されてしまいます.

これを使うには,各ピクセルに対しするレイの位置と方向を算出する必要がありますが,Unityにはその計算を自動的に行なってくれるAPIが用意されています:

mainCamera.ScreenPointToRay(Vector3(w, h, 0));



それではまず,当たった場合に白,当たらない場合に黒で表示するように改造してみます.
https://gist.github.com/cslroot/4eb475710a11f87f174e


オブジェクトの色を表示する

物体が表示されましたが,陰影もなく色もない状態です.
そこで,当たった点の情報を利用して物体色を反映させたいと思います,
現時点では2つの物体(CubeとSphere)に材質情報がありませんので,まずはマテリアルを用意します.

Unity上の操作
プロジェクトビューから,新規のマテリアルを作成します(Create > Material).
それぞれの物体に別々のマテリアルを持たせるので2つ作成しておきましょう(MatCube, MatSphere).
それらのマテリアルを選択して,Albedoの色を指定します.とりあえず赤と青にしておきます.
マテリアルを,Hierarchy内のCubeとSphereにそれぞれドラッグ&ドロップしてアタッチします.

ここまでの操作で,Unity上の物体に色が反映されたと思います.



ScriptからAlbedoカラーの取得
色を取得するには,レイと交差した物体のマテリアルを参照する必要があります.
これは,Raycast()のout引数であるRaycastHit構造体から,collider経由で取得します.

https://gist.github.com/cslroot/ce44b752bedce904c6ac

テクスチャマッピングを有効にする

マテリアルが取得できればテクスチャも簡単に習得できます.
テクスチャが設定されている場合は,Material.mainTextureプロパティでアクセスできます.
また,レイと交差した箇所のテクスチャ座標は,RaycastHit.textureCoordに格納されています.


https://gist.github.com/cslroot/ddcff7c39476e19da582

テクスチャを使うときに重要な点が1つあります.
スクリプトからテクスチャの値を取得する場合は,テクスチャの設定で「Read/Write Enble」を変更しなければなりません.これをしない場合,実行時にエラーが発生します.
テクスチャを選択「Texture Type > Advanced」にして「Read/Write Enable」をONにしてください.


今回はこのへんでー.

参考文献





 でわでわ.


2015/09/13

Unityの画面を動画にする

こんにちは.@rootxです.

前回の続きで,Unityで遊んでいます.
今回は,Unity画面を連番キャプチャして

きっと他の開発者の方が作られていると思いますが,Unityスクリプトの勉強として作成しています.

まずは連番出力
かるく調べた感じですと,3つの方法がありそうです:

  1. 「Application.CaptureScreenShot」というそのまんまなAPIを使う方法
  2. RenderTextureを使う方法
  3. Texture2DのReadPixelsを使う方法



今回は任意のサイズで保存したかったので,3番目の方法を採用します.
ちなみに,1番目の方法は遅い,とのこと.

とりあえずザクッと書いてみました.


連番画像を動画にする

ffmpegで簡単に作成できます.

30と書いた箇所は,指定したFrameRate(出力時のフレームレート)と同じにしてください.


参考文献

http://blog.almostlogical.com/2009/12/11/render-to-texture-unity3d/
http://answers.unity3d.com/questions/22954/how-to-save-a-picture-take-screenshot-from-a-camer.html


 でわでわ.

2015/09/12

はじめてのUnityプロジェクト:MMDを動かす

こんにちは.@rootxです.

はじめに

とあるところで「主婦ゆに」(サイン入り)を手に入れました!
Unityにはあまり興味がなかったのですが,せっかくなので触ってみようと思います.

とりあえずはお手本通りに,MMDモデル(PMD, VMD)を読み込み,踊ってもらおうと思います.

なお,Unity5のインストール,アカウント作成を完了したところからスタートとします.

環境

MacBook (Retina, 12-inch, Early 2015)
OS X 10.10  Yosemite
Unity 5.2.0f3





プロジェクトの作成

Newで新規プロジェクトを作成
3Dを選択
アセットはあとから追加できるので,Asset Packagesは特に変更なし
Create Project

とりあえずシーンを保存する
シーンは,ゲーム開発でいう"レベル"に相当.
Save Scene
Asset直下はいろいろなアセットが増えていくのでScenesフォルダを作ってそこに保存.

MMDファイルの読込み

MMD4Mecanim.unitypackageをダブルクリックしてインポート.

各種MMDファイル(pmd, vmd)をアセットに追加(Projectタブにドラッグ&ドロップ)
〜〜.pmdファイルの対応する箇所に,〜〜.MMD4Mecanimが生成されているので選択
Inspectorウィンドウに利用条件が出てくるので確認し,チェックONで右下の「同意する」を押す
Inspectorをロックしておく
モーション(*.vmdファイル)をVMD欄にドラッグ&ドロップする.
Processボタンを押す
#変換処理が完了するまで暫く待つ.
pmdと同フォルダにfbxファイルができているので,それをHierarchy(またはScene)にドラッグ&ドロップ.

動かす

空のAnimator Controllerを追加(Create > Animator Controller)
作成したAnimator Controllerをシーンに配置したMMDモデルのinspectorのAnimator > Controllerにドラッグ&ドロップで設定
作成したAnimator ControllerをダブルクリックしてAnimatorウィンドウを開く
プロジェクト内のモデルデータを(三角形を押して)展開し,読込み時に指定した*.vmdファイルをAnimatorウィンドウにドラッグ&ドロップする

ここまでで,再生を押すと踊るよ.
でも残念な感じのカメラなので調整しましょう.

カメラを自動追従に変更する

既存のMainCameraは削除.
メニューの Assets > Import Package > Cameras をインポート
ProjectウィンドウのAssetからHandheldCamera(Standard Assets > Cameras > Prefab)をシーンに追加
カメラの向きがいまいちなので,適当に位置合わせ 
  Position > X: 0 / Y: 0.5 / Z: 2.0
  Rotation > X: -10 / Y: 180 / Z: 0
デフォルトのクリッピングを 変更 Clipping Planes > Near: 0.1 / Far: 100
FOVも気に入らないので変更 Field of view: 50
追従するように設定 Hand Held Cam (Script) > Target: 適当なジョイント(67.joint_Neck)
再生して確認
→ あまりにも激しく動いて良いそうなので,カメラの追従速度を調整する
  Following Speed: 0.5
  FOV: 35
  Position: Y: 1
  Rotation: 355



でわでわ.

2015/08/10

Xcodeでも「上の行に改行」したい!

こんにちは.@rootxです.

普段はWindowsのVisual Studioを使っていたりいなかったりするのだけれど,
VSでよく使うショートカットの1つに「CTRL + ENTER」があります.

これはエディタ上で,「1つ上の行に改行を入れる」という操作を

例えば,コード補完等によって,次のような状態担っているとします(★印がカーソル位置).
-------------
if (false) {
}★
-------------
ここでおもむろに「CTRL+ENTER」を押下すると,
-------------
if (false) {
   
}
-------------
こんなふうになります.


先にフローの構造を作ってから編集する,という思考ルーチンなのでこの手順が極めて大切なのです.

xcodeにもそれっぽいのがあるはず!と思っていましたが,
どうやらなさそうなので,Karabinar(旧 KeyRemap4MacBook)で独自ショートカットを定義しました.
gistに置いときます.
https://gist.github.com/cslroot/376f6ac7724e9f1ff705





これで開発効率が5%くらいアップしたはず!



 でわでわ.

GUI付きのビューアをつくりたいのでocornut/imguiを使ってみた

こんにちは.@rootxです.

レイトレした結果をどう確認していますか?

PNGファイル出力をしていますが,毎回開くのも嫌だし,
入力ファイル指定や途中経過などなどをGUIから行いたいです.

でサクッとビューアをつくろうと思って,
過去に使ったことのあるGLUIを使おうと思いましたが,今回はGLFWを使ってウィンドウ表示するため使えません.

そこで最近のGUIライブラリを調べつつ,ImGuiというライブラリを使うことにしました.

試したGUI

見た目も良さげでhomebrewでインストールできたので試してみましたが,
osxのretinaディスプレイに対応しておらず,描画は可能なもののマウス位置と整合性がとれておらず使用を断念しました.

GWEN(https://github.com/garrynewman/GWEN)

1年くらい更新されていないのと,osx対応されていなさそうなのでやめ.
見た目は一番好みだったのだけれど.

CEGUI

ヘビィそうなのでやめとく.

AdrienHerubel/imgui (https://github.com/AdrienHerubel/imgui)

かなり良さそうだったけれど,あまりにもコミットが少なくメンテされてなさそうなのでNG.

blendish

blender-likeすぎて辛い.あと依存関係がヘビィ.


ocornut/imgui


ハマりポイント

1. 文字がちっちゃい=全体が小さい

retinaに完全対応していないのか,文字が極めて小さく表示されてしまいました.
ボタン等はちゃんとマウス位置に反応しているので,次の2通りの方法のどちらかで,暫定的に回避できました.

フォント読み込み時に,フォントサイズを大きくする.

  io.Fonts->AddFontFromFileTTF("resource/uzura.ttf"16.0fNULL, io.Fonts->GetGlyphRangesJapanese());
→ "16.0f""32.0f" にするとか.

※ README.mdの文字列サンプルは間違ってるので注意.第3引数にNULLを指定する必要があります.

グローバルスケールなるパラメータを2倍にする
次のようにウィンドウサイズとフレームバッファサイズを比べて掛けとく.
    {
        // osx retina 2x
        int w, h;
        glfwGetWindowSize(window, &w, &h);
        int ww, hh;
        glfwGetFramebufferSize(window, &ww, &hh);
        io.FontGlobalScale = ww / w;
        fprintf(stderr, "window(%d, %d) : frameBuffer(%d, %d)\n", w, h, ww, hh);
        
        io.UserData = &input;
    }


2.  2フレーム目から描画されない;

描画は次のような感じで行けますが,適当に拾ってきたModernなOpenGLサンプルでテクスチャ付き四角形を描画していたら,2フレーム目から描画されませんでした.

  while (!glfwWindowShouldClose(window))
    {
        //----- ImGui のセットアップ ----
        ImGuiIO& io = ImGui::GetIO();
        ImGui_ImplGlfwGL3_NewFrame();
        { // 〜〜 ImGuiのメニューなど
        }

        
        // ここら辺に自分の描画したいコードを書く

        ImGui::Render();
        glfwSwapBuffers(window);
        glfwPollEvents();

    }

かなり悩ましい問題でしたが,GUIコントロールのレンダリング時に glEnable(GL_BLEND)されているためでした.
まあそういうこともあるよね.



あまり使用実績がないので,ググってもあまり情報が出てこないのが辛いかな.
コンパクトにいろんな機能が用意されていることと,活発に更新されていることが優位な点なので,今後もウォッチしていきます.

でわでわ.

2015/08/02

買った本

こんにちは.@rootxです.



昨日のお昼くらいにポチったのですが,約8時間で受け取れました.
お急ぎ便は早いな!

 でわでわ.

2015/08/01

読んだ

最近読んだもの。


The comprehensive PBR guide

基礎基礎の確認に丁度いいです。
ただし、エンジニアというよりモデラーとかそっちの人向けかな。
Substanceを開発してる企業。

日本語版も公開されている方がいます.
http://www.slideshare.net/nyaakobayashi/pbr-guide-vol1jp
http://www.slideshare.net/nyaakobayashi/70100srgb180255

(ボーンデジタルでも配布していたけれど,認証が必要でしたので未確認)




2015/07/25

とりま

こんにちは.@rootxです.






> RenderTime: 28171.4
いけてなさすぎる.

 でわでわ.

メモ

レイトレ系の話は,別のblogに書いてたのだけれど,
bloggerがエラーを出して死んでしまったのでこちらに移植しました.

何が行けなかったんだろう….
独自ドメインで動かそうとしたからかなあ.
でも設定自体は済んでて,ちゃんと独自ドメインでアクセスできるようになってたのに.

ううん.

XCodeのLLVM(clang)でOpenMPを使おう(解決)

こんにちは.@rootxです.

高速化って大切ですよね.
結果が出るまで待てない,AWSに余計なお金を払いたくない,などなど,進化した計算機といえどもCPU資源を使いきって高速に処理する需要はなくなることはありません.

CPU自体の進化も,クロックの高速化競争の集結を迎え,シングルスレッド性能は頭打ちになってきています.
この背景には,半導体プロセス微細化によるリーク電流や,数GHzを超えると電子の移動速度も際どくなる等が要因として挙げられていたと記憶しています.
# 消費電力あたりの性能,という指標は個人的には好きではありません….

そのため,現在のCPUではマルチコア,ハイパースレッド等の技術によって,処理を複数同時に実行できることでCPU全体としての性能向上を維持しています.


プログラミング技術においてもその方向に進んでいて,いかに並列処理をするか,というのが現代的なプログラムの重要なポイントの1つとなっています.


様々な並列処理手法がありますが,C++で開発する際に,お手軽に並列化する方法の1つにOpenMPというライブラリがあります.
このOpenMPは,名前がちょっとOpenGLに似ていますが全然関係なくて,並列処理を簡易的に実装する

しかも最近のVisual Studio(VS2010以降?)では標準的に使えるようになっていて,
プロジェクト設定をちょいちょいと変えてあげるだけで有効になる,とってもとっても便利なライブラリで,特にレイトレのような並列化の容易なアプリケーションでは,たった1行追加するだけでバリバリ並列化できちゃう夢のような仕組みです.


しかし残念なことに,OSX上のXCodeで開発している場合は,VSほど簡単に有効にすることはできないようです.これはXcodeの標準コンパイラがLLVM clang3.5であり(MacOS 10.9.5 Xcode6.2時点),ちゃんと対応されていないバージョンのためです.
そのうち標準対応されるのではないか,と想像していますが,現時点では望めません.

# 10.10の環境は未調査.今のところ,あのフォルダアイコンのださいOSをメイン環境として使う気がないため.


ということで,自前でスレッド処理するが,gccに切り替えて使うべきか,いっそのことWindowで開発するか,といった悩ましい問題が目の前に立ちはだかっているのです.

いろいろ探していましたが,OpenMPを有効化したclang-ompが配布されていたので導入す


ここから本題です.


Xcodeで clang-omp の使い方



  1. homebrew でclang-ompをインストール: brew install clang-omp
  2. Xcodeプロジェクトを作成
  3. ビルドセッティング(Build Setting)で:
    1. 新しいユーザ定義設定 CC を次の値で作成:/usr/local/bin/clang-omp
    2. -fopenmpOther C Flagsに追加
    3. /usr/local/includeHeader Search Pathsに追加
    4. Enable Modules (C and Objective-C)Noにセット
  4. ビルドフェーズ(Build Phases)で:
    1. /usr/local/lib/libiopm5.dylibLink Binary With Librarianに追加
  5. (*)/usr/local/binにhomebrewでインストールされたclang-omp++というエイリアスがあるので,clang++-ompに名前を変更


これで完了.あとは #include <libiomp/omp.h>して,#pragma omp〜〜を使うだけ?.

注意

なぜかビルドできませんでしたが,上記手順の5を追加することで上手く動くようになりました.
どうやらXcodeは,C++のコンパイル時にCCに定義されたものを自動的に置換しているようです.その際に,末尾に++を追加するのではなく,clangをclang++に置換するようです.(途中のバージョンで仕様が変わったのかな…)

ということで,暫定的な対策ですが,clang-omp++の名前をclang++-ompにすることで,上手くそれを使ってくれるようにできました.




補足

glmがコンパイラを認識できずに次のエラーを出しましたので対応しました.
/usr/local/include/glm/detail/setup.hpp:287:2: error: "GLM_COMPILER undefined, your compiler may not be supported by GLM. Add #define GLM_COMPILER 0 to ignore this message."#error "GLM_COMPILER undefined, your compiler may not be supported by GLM. Add #define GLM_COMPILER 0 to ignore this message." ^1 error generated.Command /usr/local/bin/clang-omp failed with exit code 1

TODO

後日,効果を検証します.
なんかビルド時のエラーの出かたが変化した気がする…


でわでわ.

1024 x 768 with 20 path /subpx and 2x2 subpixel

こんにちは.@rootxです.



うーん遅い.

でわでわ.

遅いのでAABBを導入してちょっとだけ早くする

こんにちは.@rootxです.

簡単なレイトレができましたが,単純なシーンの割に遅いです.
先ほどの偽コーネルボックス(640x480)のレイキャストで約1.0秒もかかっています.
これは由々しき事態です!

というわけで,本筋としてはBVHなどの高速な衝突検出(O(log(n))を使うべきですが,
とりあえずAABBを導入します.

AABBとは,Axis Aligned Bounding Boxの略で,要するに当たり判定用のBOXです.
ポイントはXYZ軸に沿っていることですね.そのため,斜め方向を向いている細長い物体だと,大きくなりすぎる問題もあります.
物体の向きに関係なく,任意方向の境界BOXであるOBB(Oriented Bounding Box)というものもありますが,OBB算出が面倒なのとシーンが複雑になった時の構築時間が増えてしまうので,今回は後々の拡張も考慮してAABBを採用します.


AABBの実装は簡単で,プリミティブの最小最大座標をx,y,zそれぞれ求めて上げればOKです.
現在,プリミティブとして用意しているのは,三角形と球なのでちょいちょいと求めてあげます.

メッシュ(モデル)毎にもAABB持たせてあげましょう.
メッシュを構成する全プリミティブのAABBをガッチャンコします.
MergeAABBみたいな関数を用意すると便利ですね.


次はAABBとレイとの衝突判定を実装します.

とりあえずこれを参考にします.

ゲームプログラミングのためのリアルタイム衝突判定



サンプルコードがここ(http://www.borndigital.co.jp/book/164.html) からダウンロードできるので買わなくてもいいけれど,一冊持っていると良いと思います.
ちなみに,この本は学生の時にお世話になりました.
その当時は日本語版がなくて,英語を読むのに苦労した覚えがあります……;



でわでわ.

単純なレイキャスティング

こんにちは.@rootxです.

とりあえず,単純なレイキャスティングを行うプログラムを書いてみました.




シーンがしょぼいのと,光源を設定していないので陰影も出てませんが;

でわでわ.

使うライブラリ

こんにちは.@rootxです.

今回はレイトレ作るのに使いそうなライブラリを選んでみたよ.
あ,C++です.


glm OpenGL Mathematics (http://glm.g-truc.net/)

ベクトルとかマトリクスとか,いつも出てくる子たちですね.
普段ならフルスクラッチで書くこともあるけれど,今回はこのglmというライブラリを利用してみます.
特徴としては,ヘッダオンリライブラリで,GLSL風の機能が備わっていること.OpenGL系と
あんまり早くは無いはず.


stb single-file public domain libraries for C/C++ (https://github.com/nothings/stb)

いろんなファイルフォーマットに対応したヘッダオンリライブラリ.
画像出力(PNG)に使うつもり.
読込みもできるので,テクスチャロードもできるかな.
# でもglmの開発者の作っているgliも良さそうなんですよね.


assimp : Open Asset Import Library (http://assimp.sourceforge.net/)

いろんなアセットを読込みたいときに使えるよ.
基本的なフォーマット(collada, obj, stl, ply)でエクスポートもできるみたい.


とりあえずここまで.
他に使えそうなライブラリがあったら追加するよ.



でわでわ.

レイトレはじめます

こんにちは。@rootxです。

先日、ドワンゴがとっても興味深い人材募集を始めましたね。

新しい時代のエンジニアについて
http://info.dwango.co.jp/recruit/beyondtheweb/index.html


【新規事業】3DCGエンジニア(正社員)


具体的には次のような条件が示されてるよ。

> <必須条件>
> • プログラマブルシェーダの実装経験者
> • SIGGRAPHなどで発表された論文を元に実装をしたことのある方
> • 3DCGの分野で何か研究したいテーマを持っている方

> <歓迎条件>
> • SIGGRAPHなどにおけるCG関連論文の発表経験者
> • 物理ベースのオフラインレンダリングを研究開発できる人
> • リアルタイムへの自動リトポロジーアルゴリズムや光学エフェクトの研究開発ができる人

ドワンゴというと、やっぱりニコニコ動画のイメージが先行してるので、まさかこんなにガチな人材を求めるとは思っていなかった、というのが正直なところです。
3DCG関連でいうと、短期的には、WebGLやunityみたいなネットと相性の良いテクノロジを志向するかと考えていました。実際、ニコニ立体でそちら方面は手を出しているし。


そんなわけで、普段は興味分野と関係ないお仕事をしてるから、グッときちゃったね。

でも、全然実績がないから、どうしようかなと思ってたけど、折角なので今から実績を作れるか挑戦してみようと思います。



でわでわ。

2015/06/20

GLFW: Oculus Rift ガイド 日本語訳

GLFW: Oculus Rift ガイド


Oculus Rift guide の日本語訳です.途中.
http://www.glfw.org/docs/latest/rift.html


このガイドは,Oculus PC SDK ドキュメントと GLFWのドキュメントとの間にあるギャップを埋めることを目的にしていて,それらを置き換えるものではありません.ネイティブアクセス(native access)の使用が必要で,LibOVR,プラットフォーム固有API,利用する開発環境に関してある程度慣れ親しんでいることを前提としています.
GLFWはLibOVRを明示的にはサポートしていませんが,テストはされていて,LibOVRとの相互運用についても実施中です(While GLFW has no explicit support for LibOVR, it is tested with and tries to interoperate well with it).

Note
Oculus SDKの開発速度によって,このガイドは次の(GLFWの)リリース前に時代遅れになっていると思います. もしこのドキュメントがローカルにコピーされたものなら,最新の情報をGLFWウェブサイトでチェックしてください.ガイドのこの版は,Oculus SDK のバージョン0.4.4を対象として記述されています.

LibOVRとGLFWヘッダファイルのインクルード

OpneGL LibOVRヘッダとGLFWのネイティブヘッダの両方で,ビルドしようとしているOSが何かを伝えるマクロが必要です.LibOVRは主要なデスクトッププラットフォームだけをサポートしているため,標準的な事前定義マクロで解決できます.

#if defined(_WIN32)
#define GLFW_EXPOSE_NATIVE_WIN32
#define GLFW_EXPOSE_NATIVE_WGL
#define OVR_OS_WIN32
#elif defined(__APPLE__)
#define GLFW_EXPOSE_NATIVE_COCOA
#define GLFW_EXPOSE_NATIVE_NSGL
#define OVR_OS_MAC
#elif defined(__linux__)
#define GLFW_EXPOSE_NATIVE_X11
#define GLFW_EXPOSE_NATIVE_GLX
#define OVR_OS_LINUX
#endif
#include <GLFW/glfw3.h>
#include <GLFW/glfw3native.h>
#include <OVR_CAPI_GL.h>

GLFWとLibOVRのヘッダ両方は,デフォルトで標準のOpenGL  GL/gl.h ヘッダ (OpenGL/gl.h on OS X)のインクルードを試みます.もし異なる標準ヘッダやGL拡張ロードライブラリを使いたい場合は,これらの記述の前にインクルードしてください.

LibOVRとGLFWの初期化

LibOVRはGLFWより前に初期化される必要があります.つまり少なくとも ovr_InitializeovrHmd_CreateovrHmd_ConfigureTracking をglfwInit より前に呼び出すことを意味します.同様に,GLFWより後にLibOVRを終了しければなりません.
これは,ovrHmd_Destroy, ovr_Shutdown を glfwTerminateの後に呼ぶことを意味します.

Direct HMD モード

Direct HMDモードは,新しいアプリケーションで推奨されている表示モードですが,Oculus Riftランタイムは現在(2015年1月時点)Windowsだけがこのモードをサポートしています.Direct HMDモードでは,HMDはGLFWモニターとして検出されません.

ウィンドウとコンテキストの作成

もし、HMDがダイレクトモードならフルスクリーンモードかウィンドウモードのどちらかを使用できますが、フルスクリーンはHMDの解像度をサポートしている場合だけ推奨されます。
LibOVRの制限のため、ウィンドウのクライアントエリアのサイズとHMDの解像度は必ず一致してなければなりません。
もしHMDの解像度が通常のモニタ解像度より大きい場合、

If the resolution of the HMD is much larger than the regular monitor, the window may be resized by the window manager on creation. One way to avoid this is to make it undecorated with the GLFW_DECORATED window hint.

HMDへのウィンドウのアタッチ

Once you have created the window and context, you need to attach the native handle of the GLFW window to the HMD.
ovrHmd_AttachToWindow(hmd, glfwGetWin32Window(window), NULL, NULL);

拡張デスクトップ(Extend Desktop) モード

拡張デスクトップモードは旧来の表示モードですが,OS XやLinux上では,技術的な理由でDirect HMDモードをサポートされていないため,このモードだけが利用可能です(2015年1月時点).Windows機でも同様に.

GLFWでHMDを検出する

HMDが拡張デスクトップモードになっている場合,どちらのGLFWモニタがHMDと一致しているかを推定して,そのモニタにフルスクリーンウィンドウを作成します.
Windowsでは,GLFWモニタのネイティブデバイス名は,検出されたHDMのディスプレイデバイス名と対応しています(ovrHmdDescのDisplayDeviceNameメンバに保持されています).
OSX上では,GLFWモニタのネイティブディスプレイIDが検出されたHMDのディスプレイIDに対応しています(ofovrHmdDescのDisplayIdメンバに保持されています).

執筆時点(2015年1月)で,Oculus SDKはどちらのモニタがHMDなのかをちゃんとした方法で検出する方法はサポートしていませんが,
HMDが適切にセットアップと回転されている限り,LibOVRによって提供されるスクリーン位置と解像度を通じて発見することができます.
この方法はHMDをミラリングしている他のモニタを見つけてしまうかもしれませんが,もしそのビデオモードを変更使用としている場合にだけ問題となります.

int i, count;
GLFWmonitor** monitors = glfwGetMonitors(&count);
for (i = 0; i < count; i++)
{
#if defined(_WIN32)
if (strcmp(glfwGetWin32Monitor(monitors[i]), hmd->DisplayDeviceName) == 0)
return monitors[i];
#elif defined(__APPLE__)
if (glfwGetCocoaMonitor(monitors[i]) == hmd->DisplayId)
return monitors[i];
#elif defined(__linux__)
int xpos, ypos;
const GLFWvidmode* mode = glfwGetVideoMode(monitors[i]);
glfwGetMonitorPos(monitors[i], &xpos, &ypos);
if (hmd->WindowsPos.x == xpos &&
hmd->WindowsPos.y == ypos &&
hmd->Resolution.w == mode->width &&
hmd->Resolution.h == mode->height)
{
return monitors[i];
}
#endif
}

ウィンドウとコンテキストの作成

検出されたモニタ上に通常のフルスクリーンウィンドウとして,ウィンドウが作成されます.HMDが正しいビデオモードに既に設定されている場合には,windowed full screenウィンドウを作成することは通常良いアイディアです.しかし,拡張デスクトップモードは通常のモニタとして振る舞い,いくつかのサポートされているビデオモードの受付け可能です.
もし他のモニタだがHDMをミラリングしていて,異なるビデオモードをリクエストしている場合,すべてのミラリング設定されているモニタは新しいビデオモードになります.

HMDへのレンダリング

SDK歪曲レンダリング

もしSDK歪曲(ディストーション)レンダリングを使おうとするなら,レンダラを設定するためにGLFWからいくつかの情報を取り出す必要があります.
GLFWから情報を埋める必要のある ovrGLConfig ユニオンの一部を示します.
他のフィールドも ovrHmd_ConfigureRenderingのために設定する必要があることに注意してください.
SDKディストーションレンダリングを設定する前に,あなたのコンテキストをカレントにしてください.

int width, height;
union ovrGLConfig config;
glfwGetFramebufferSize(window, &width, &height);
config.OGL.Header.BackBufferSize.w = width;
config.OGL.Header.BackBufferSize.h = height;
#if defined(_WIN32)
config.OGL.Window = glfwGetWin32Window(window);
#elif defined(__APPLE__)
#elif defined(__linux__)
config.OGL.Disp = glfwGetX11Display();
#endif

SDKディストーションレンダリングを使う場合,ovrHmd_EndFrameによってHMDが更新されたときに,自分でバッファスワップをしてはいけません.

クライアント歪曲レンダリング

クライアント側で歪曲レンダリングするときは,HMDのコンテンツを完全な制御下におき,通常のレンダリングとバッファスワップを実施します.