サクサク読めて、アプリ限定の機能も多数!
トップへ戻る
デスク環境を整える
i-saint.hatenablog.com
ここしばらく DCC ツール上のモデルをリアルタイムに Unity に同期する、MeshSync というツールを開発しています。その Blender 対応にとても苦労したので情報を残しておこうと思います。 なお、Blender の世界ではプラグインは "add-on" と呼ぶことが多いようですが、本記事では "プラグイン" で統一します。 Blender は Maya や 3ds Max のような、総合型の 3DCG の DCC ツールです。競合するツールはいくつかありますが、主要な DCC ツールの中で Blender は唯一オープンソースなフリーソフトウェアなのが最もユニークな点だと思います。 Blender の大部分は C で書かれています。C++ ではなく、C です!Blender はコア部分以外は基本 python で機能を拡張していく構造になっています。UI や各種編集機能、f
ここ数ヶ月仕事で Alembic を扱ってきたので、Alembic に関してここまで得られた知見を書き残しておこうと思います。 想定しているシチュエーションは主に、Alembic のライブラリを用いて alembic ファイル (.abc) を読み込み、そのデータを D3D11 などのグラフィックス API に流し込んで描画する、というようなものです。 Alembic はゲームに使うのは難しいと思われますが、例えば VR コンテンツには使い出がありますし、近年のゲームエンジンを使った映像制作でも重要な役割を担う可能性があります。また、Alembic は書き込みも簡単にできるため、プレイ中のゲームのシーンを Alembic で 3D 録画し、それを映像制作などに利用、といった応用も考えられます。 Alembic 概要 http://www.alembic.io/ 過去にも軽く触れましたが、A
夏コミ版 exception reboot で用いた、オブジェクトスペースでレイマーチする手法について解説してみます。(ここで言うレイマーチは厳密には sphere tracing のことですが、面倒なのでレイマーチで統一します) アイデア自体は特に新しくも難しくもなく、シーン内に単純なポリゴンモデルを配置し、そのモデルの中でレイマーチを行うというものです。レイマーチにより G-Buffer を生成し、あとは通常通りライティングを行います。 レイマーチについては過去にこの blog でも簡単な入門を書きました。最近では日本語でも結構情報が出てくるくらい知名度が上がってきているように見受けられます。 raymarching for games - primitive: blog レイマーチで G-Buffer を生成する手法もしばらく前にこの blog で紹介しました。 rendering
C88 で頒布する exception reboot 開発途中版の PV です。R23b でお待ちしております。 今回も体験版です…。前回同様 100 円でソースコード (Unity プロジェクト一式) 同梱です。カワノさんによる新曲も追加されています。 残念ながらゲーム内容は冬コミ版とほとんど変わっていません。しかしグラフィックは大きく変わりました。見ての通りだいぶん派手になっています。相応に重くもなっていますが、もう低スペックは切り捨てて全力で自分の目指す絵を追求する方向に舵を切りました。ただ、冬コミ版は非 D3D11 環境では色がおかしかったりパーティクルが出なかったりしたのが、今回は一応一通り機能するようになっています。 Unity 5 移行に伴い、レンダリングに絡む処理は全て書き直しています。このせいでえらい手間取ってしまいましたが、標準レンダリングパイプラインで描画するように変
Unity4 の時に書いた自作 deferred shading 用の機能を Unity5 用に再実装しています。その経過の記録です。成果物はこちら https://github.com/i-saint/Unity5Effects Screen Space Boolean ステンシルや ZTest Greater の組み合わせでスクリーンスペースでブーリアン演算をやるというトリック。以前解説したものですが、Unity5 でこれをやるのは苦労しました。 実装の方針として、ブーリアン演算の段階では depth だけを出力し、実際に G-Buffer を書き出す段階では ZTest Equal を使用するように変更を加えた Standard Shader を用います。これは後述のステンシルの制限の回避や、必要なシェーダのバリエーションを最小限にするためです。代償として drawcall の数が増
最近作ったもの紹介。全て Unity から使う前提で作ってはいますが、BatchRenderer 以外は Unity 依存度は低く、一応他のプログラムから使うこともできるはずです。また、全て MIT ライセンスか CC BY ライセンスなので、ソースレベルで切り貼りして使うのも問題ないようになっています。 PatchLibrary https://github.com/i-saint/PatchLibrary 実行中のプログラムにロードされている dll を強引に更新するツールです。プラグイン開発などの際、VisualStudio ビルド後イベントでこれを呼び、実行中のホストプログラムを再起動することなく更新する、というような使い方を想定しています。 以前作った DynamicPatcher の簡易版的なもので、dllexport されている関数のテーブルを書き換えて新しい dll の関数
Unite 2015 Tokyo の講演で詳細を話せなかったのが心残りだったので、大量のオブジェクトの更新処理についてこの場で書いてみます。 主に C++ で、簡単なパーティクルエンジンを作り、それを SIMD を用いて高速化する手順を解説します。 話を簡単にするため、以下の前提を設けます。 ・x86 環境のみ考慮 ・パーティクルは位置と速度のみを保持 ・パーティクル同士の相互衝突は総当たりで計算 総当たりなので超遅いですが、実装は容易で SIMD による恩恵を受けやすく、題材として手頃です。 この記事の中で引用されているソースの元は こちら、ビルド結果 (上のスクリーンショットのデモプログラム) は こちら になります。 相互衝突するパーティクルを実装する場合、お互いの距離を計算し、当たっていたらめり込み具合に応じて押し返す、というのがよくある実装だと思います。まずはそれをストレートに
Unity ユーザー向け開発者イベント、Unite 2015 Tokyo で公演しました。上はそのスライドになります。タイトルの通り、基本的にこの blog の過去の検証記事をまとめた内容になっています。 Unite に来る人でこういう内容を求めている人はそんなにいない (シェーダー書く Unity ユーザーの割合はかなり少ない) のがわかっていたので、資料作りにはかなり悩みました。最終的に、あまり深くなり過ぎない程度にレンダリングとアップデート両方を解説した…つもりです。なので、実装について詳しく知りたい場合は元となったこの blog の検証記事とソースを見た方がいいでしょう。(これ これ これ) 少なくともデモはそれなりにインパクトがあったのが見て取れたので、Unity でプログラミングやゲーム開発を始めたような層がこういう領域に興味を持つきっかけになればいいなあ…という感じです。 そ
Unity5 になってレンダリング機能の柔軟性が大きく増しました。 新たに追加された CommandBuffer により、Unity のレンダリングパスのほとんど任意のタイミングに任意の描画コマンドを差し込むことができるようになりました。また、deferred shading レンダリングパスが新たに追加されました。Unity4 にあったのは deferred lighting でしたが、今度のはリッチな G-Buffer を持ったちゃんとした deferred shading です。 CommandBuffer と deferred shading を併用することにより、Unity のレンダリングパスで用いられている G-Buffer を加工したり、ライティングを独自処理に差し替えたりといったことができるようになります。試しにこれらを用いてフラクタル図形をレンダリングしてみました。 ht
webplayer: http://primitive-games.jp/Unity/blue_impulse/ source: https://github.com/i-saint/BlueImpulse TokyoDemoFest2015 にて PC demo を発表しました。その映像、バイナリ、ソース一式を公開します。 今回も Unity 製です。会場のマシン (Windows & GeForce GTX 780) で動けばいいやという想定で作ってるので相当重いです。Direct3D11 必須。 今まで積み上げてきたリソースを組み合わせて短期間で映像作品に仕立ててみよう、というチャレンジのもとに制作に挑みました。水面やポストエフェクトの追加などレンダリングエンジンへの機能追加に約 1 週間、シーンデータの作成に約 1 週間で、製作期間は 2 週間くらいです。 今回もサウンドは カワノ
Unity で大量のオブジェクトを描画するスクリプトを書きました。 https://github.com/i-saint/BatchRenderer 簡単な使用例 いつも通り弾幕やらパーティクルやらを描くのを想定した代物ですが、割と簡単に使えてポータブルな作りになっています。Windows で D3D11, D3D9, OpenGL モードでいずれも動作。Android でも動作を確認しています。 スクリプトの使い方については上記ページを参照していただくとして、この記事ではこのスクリプトを作る過程で得られた (バッド) ノウハウ群を書き残しておこうと思います。過去の記事と内容が被ってる部分が多くありますが、その多くは本記事でより洗練されています。 まずこれを作った背景。 OpenGL や Direct3D では、大量のオブジェクトを描画するにはインスタンシング描画を用いるのが一般的です。U
C87、スペースに立ち寄ってくださった方々、ありがとうございました。 exception reboot 体験版ですが、Visual Studio 2013 ランタイムが入ってないとパーティクルや背景が出ないというミスをやらかしてしまいました…。同現象に見舞われている方はこちらをインストールしてお試しください。 http://www.microsoft.com/ja-JP/download/details.aspx?id=40784 (vcredist_x86.exe の方) また、ビデオカードによってはエフェクトが正常に出ないようです。今後調査して直していきます。 今回 1 ステージだけなので意識的に難しめにしています、が、ちょっとやりすぎたかもしれません…。コントローラ対応が中途半端だったり、自機を見失いやすいなどのプレイアビリティに関しては追々改善していきます。 最終的に売り物にしつつ
以前 検証した Unity で大量の cube を描く方法の続きです。あれからまたいくつか検証を重ねてきたのでまとめておこうと思います。 まず前提として、今回解説する方法は全て Graphics.DrawProcedual() を使うアプローチです。以前の記事を書いた時点では気づいていなかったのですが、Graphics.DrawProcedual() を使うと instancing 描画ができます。 残念ながらこの API、現状 OpenGL 系のプラットフォームでは使えません。つまり Android & iOS では使えず、PC でも Windows のみとなってしまいます。しかし近い将来いろんなプラットフォームでサポートされていくはずです。(近年のモバイルデバイスはハードウェア的には既に instancing 描画をサポートしています) この Graphics.DrawProcedua
Temporal Screen Space Reflection 以前諦めた真面目なスクリーンスペース反射の実装に再挑戦して、今回は割といい成果を出せました。 この成果に至る過程が長く苦しくもおもしろかったので書き残しておこうと思います。 スクリーンスペース反射はその名の通り、スクリーンスペースで反射の映り込みを実現するもので、G-Buffer の法線と深度を見てレイマーチでトラバースすることで実現します。 画面内にあるものしか映せないという致命的な欠点こそあるものの、本来レイトレが必要なはずの任意面反射を破格のコストで実現することができ、Crysis2 が採用して以降、近年の大型タイトルではもはやデファクトスタンダードとなっています。 まずは素朴な実装で、G-Buffer の深度と法線から、カメラ -> pixel 位置に対する反射ベクトルを求め、深度バッファをレイマーチしてみました。
mono の API を使って C++ から直接 Unity の C# のオブジェクトを触る、という実験を最近やっていたので、その成果を書き残しておきます。 mono を使うことで pinning や marshalling などの余計な処理を介さず C# と C++ を連携させよう、という趣旨です。Unity のプラグインから使う前提で書いていますが、Unreal Engine の場合でもあてはまることは多いと思われます。 mono の組み込みは公式に入門ドキュメントが用意されており、これがいいとっかかりになってくれました。 http://www.mono-project.com/docs/advanced/embedding/ また、突っ込んだことをやろうとするとソースを読む根性が必要になると思われます。Unity の mono はカスタムが入ったものになっています。 https://
CEDEC 2014 で "Live Coding in C++" と題して講演を行いました。以前の予告の通り、この blog に書いてきたことをまとめた内容になっています。上はその発表資料です。 予想に反して聴講しに来てくれた方は多く、この領域の情報を求めていた人まだこんなにいたんだ!と勇気づけられました。講演後も鋭い質問があったり (後にその方は web 上で面識があった方だと判明)、「"C++ は動的言語" で胸が熱くなりました!」とアツい声援を受けたり、楽しい一時でした。 正直話についてこれなかった方も数多くいるんじゃないかと思いますが、そういう方にも何かしらアイデアは示せたんじゃないかと思います。 内容に関して、State Save が最後まで満足行くレベルに到達できなくて、ここらへんはとても悔いが残る結果になってしまいました。ビデオカードのドライバやサウンド系のスレッドでたまに
Unity は標準で deferred rendering をサポートしていますが、これは light pre-pass とか deferred lighting と呼ばれるもので、deferred shading とはちょっと違います。私が必要としているのは deferred shading の方なので、これを Unity で実装してみました。 https://github.com/i-saint/DeferredShading deferred shading 自体の詳しい解説はここでは省略しますが、 大雑把には render target を複数用意し、ポリゴン描画パスではそれらに法線、位置、diffuse 色などシェーディングに使う情報を格納 (これらは geometry buffer、略して G-Buffer と呼ばれます)、その後 G-Buffer を利用してポストエフェクト的
MassParticle パーティクルエンジンを Unity のプラグインとして再実装しています。 まだまだ発展途上ではあるものの、そこそこの物量と速度と使い勝手を両立できる目処が立ってきたので、いずれ Asset Store で公開しようと考えています。ソースに関しては今もこれからも github で公開中です。 実装にあたり、シミュレーションのコアは以前 ISPC で書いたのをそのまま利用。他オブジェクトとのインタラクションは、C# スクリプトからプラグイン側に Collider 情報を渡し、パーティクルデータを unsafe のポインタで返して衝突しているパーティクルから AddForce()、ですぐに実装できたのですが、描画処理が相当なクセモノで苦労させられました。 以下は Unity で大量の cube を描くためにこれまで辿った道筋です。想定しているゴールは、私のマシン (i7
プロセスの内部状態を保存して後で復元したい、ということがゲーム開発ではよくあります (いわゆる state save)。チェックポイントから再開みたいな機能の実現の他、あると開発中何かと役に立ちます。定期的に state save しつつ、気になったところがあったら巻き戻して Alcantarea の実行時コード編集で改良、という TAS みたいなやりかたが最近の私の開発スタイルです。 通常は boost::serialization とかを使って必要なデータを serialize する処理を書いてタイトル毎に実装しますが、これをもっと簡単に、汎用的に、できれば既存のプログラムに外部から適用できる形で実現する方法はないか、と夢見た方も多いんじゃないかと思います。これを実現できるかもしれない方法を思いついて、ある程度のところまで成果を出せたので経過を書き残します。 (Virtual Mach
C++ ソースの変更を実行中のプログラムに反映させる Visual Studio アドインをリリースしました。 Alcantarea - A Visual Studio Add-In for Runtime C++ Code Editing これは DynamicPatcher に改良を加えつつ Visual Studio のアドイン化したもので、既存のプログラムを前準備なしに実行時編集可能にします。Edit and Continue と比べていくつか制限はあるものの、x64 でも最適化が有効なプログラムでも機能するのはゲーム開発で強力に威力を発揮するはずです。 Visual Studio 2013 が x64 の Edit and Continue に対応する、という情報が出て世界中のゲーム開発者が沸き立ち、その後実は .Net しか対応してないことが判明して世界中のゲーム開発者をガッカ
demoscene の世界では近年 raymarching というレンダリング手法がよく用いられています。ポリゴンモデルは使わず、モデルデータは数式の図形としてシェーダコードの中で表現し、pixel shader で図形との距離を求めて可視化していく、というものです。 demoscene (4k/64k intro) の厳しい容量制限の中綺麗な絵を出すために生み出された手法ですが、従来のポリゴンベースの手法では難しい独特の絵を出すことができるという副次的効果があります。 raymarching の代表的な作品群 この手法は PS4 世代以降、小規模ゲーム開発チーム向けの有用なツールになるんじゃないかと考えていて、atomic では試しに背景にこの手法を用いています。以下はその過程や考察です。 まず、raymarching の基本については demoscene.jp の人たちが素晴らしい解説
ここ数ヶ月でいろんな関数 hook を試したのでメモ。Windows でしか試していませんが、x86/64 であれば他のプラットフォームでも同等のことができるはずです。 関数 hook と dll injection は解析/デバッグツールやら動画キャプチャツールの類を作るための基礎技術になります。 ・vftable Swapping (sample code) vftable をすり替えることで virtual 関数を hook する方法。vftable の構造がコンパイラ依存ではあるものの、OS の API などを必要とせずお手軽です。 interface class のみが提供され、実装が dll にある場合 (DirectX とか) この方法が役立ちます。 D3D11 のリソースリークチェッカの実装に用いました。 ・vftable Override (sample code) vf
WebController ブラウザからゲームを操作するツールをしばらく前に作りました。主にモバイル機器から Wii U コントローラ的にゲームを操作するのを目的としたものです。 上の動画は Nexus7 から REVOLVER360 RE:ACTOR (C83) を遠隔操作しているところ。見ての通り既存のゲームをソースレベルの変更なしで操作できています。 やってることは、対象ゲームのプロセスに dll を注入して HTTP サーバーを立て、入力 API を乗っ取ってブラウザから送られて来た入力データで結果を差し替える、というものです。 HTTP サーバーはいつも通り Poco のおかげでとても楽に実装できました。 dll の注入については 過去 に書いた CreateRemoteThread() で LoadLibraryA() 呼ばせる方法そのままです。プロセス起動直後に注入する必要が
[2013/12/25 追記] この DynamicPatcher をさらに改良し、Visual Studio のアドインとして実装した Alcantarea をリリースしました DynamicObjLoader を改良し、実用に耐えそうな実行時 C++ コード編集機能を実装しました。 C++ コードを編集してそれをリアルタイムに反映させることができます。 DynamicPatcher https://github.com/i-saint/DynamicPatcher (bin) DynamicObjLoader の時点で一応は同等機能を実現していたのですが、更新したい関数を事前にマクロで包む必要があったり、virtual 関数を持つ class はシリアライズが必要だったりと、運用上色々面倒な点がありました。 今回はそのへんが大きく改良されています。 ・前準備なしに既存のほぼ全ての関数を
ゲーム屋の間ではおなじみのデバッグメニューをブラウザで実装してみました。 WebDebugMenu デバッグメニューとは、変数や関数を事前に登録しておき、後でメニューから値を書き換えたり関数を呼んだりできるようにする代物で、周囲の人間の話を聞くにコンソールゲーム屋の間では国内外問わずどこでも開発中こういう機能を入れていて、ほぼ共通認識になっているようです。 通常ゲーム内の 2D レンダリング機能やら UI 機能やらを使って実装するのですが、ブラウザで実装すればそれらとの依存を断てるので汎用性を高められそうです。サーバープログラムのようなグラフィック表示がないプログラムへの応用も考えられますし、ブラウザは超強力な UI エンジンでもあるので、一般的なデバッグメニューでは難しい複雑な編集機能も実装できそうです。(STL などのコンテナの中身を弄るとか、スクリプトやシェーダコードを編集できるよう
最近書いた雑多な実験コードのまとめ。 ・GetThisOfCaller() 現在の関数の呼び出し元がメンバ関数であればその this を返すというもの。 スタックフレームをさかのぼり、デバッグ情報を使って該当スコープの変数を巡回して this が見つかればそれを返す、ということをやっています。(たまたま今回 this が欲しかっただけで、それ以外の変数も可能です) 非 Debug ビルドの時はよくデタラメな値が返ってくるため、使いものにならないですが、Debug で限定的な状況で役立つ可能性が無きにしもあらずです。 ・メンバ関数の中と外で違う処理を行うマクロ VisualC++ の拡張 __if_exits, __is_not_exits を使って this の有無で違う処理をさせるというもの。 __if_exits は指定シンボルの有無で分岐するという代物で、主にメタプログラングに使われ
しばらく前にやったことですが、ネタとして面白い気がするのでサルベージ。 DynamicObjLoader を使って C++ で eval() を実装しました。 C++er が夢に見たり見なかったりしたこういうコードが動きます。 #include "DynamicObjLoader.h" class Hoge { public: Hoge() : m_value(100) {} void doSomething() { printf("Hoge::doSomething(): %d\n", m_value); } private: int m_value; }; void* CreateAnyClass(const char *class_name) { volatile void *obj = NULL; std::string source = std::string("obj = ne
以前作ったメモリリーク検出器がとても役立っていて、今も機能追加を加えつつ使っています。 最近大きな改良を加えたので再掲。 MemoryLeakBuster 実行時にイミディエイトウィンドウから呼ぶデバッグ機能を追加したのが主な変更で、以下のようなことができるようになりました。 ・範囲指定リークチェック デバッガで止めて範囲指定することで、そこで確保されたまま開放されなかった領域のコールスタックを出します。 ・指定アドレスの確保時のコールスタック出力 近隣領域も表示し、stack 領域か static 領域か判別する機能も備わっています。デバッグの強力な手助けになっています。 ・アロケーションカウント リークチェックではなく、単純に HeapAlloc() が呼ばれた回数をコールスタックと共に出力します。プロファイリングのお供に。 ちなみに、デバッガをつないでいる時は HeapAlloc()
[2013/06/06 追記] DynamicObjLoader の後継として DynamicPatcher が作られました。こちらの方がより強力です。 .obj ファイルを実行時にロードして自力でリンクを行い、中にある関数を実行できるようにする、という代物を作ってみました。 https://github.com/i-saint/DynamicObjLoader (一括ダウンロード) 上の動画はこれを使って C++ コードを書き換えてリアルタイムでパーティクルの挙動を変えているところ。 UnrealEngine4 がスクリプト言語を撤廃し、代わりに C++ ソースを編集したらリアルタイムでそれが反映される機能を搭載してきて以降、一部のゲーム屋で C++er な人たちの間で実行時コード生成/ロード系ネタが盛り上がってるような気がします。 該当機能の一番素直で礼儀正しいと思われる実装方法は R
次のページ
このページを最初にブックマークしてみませんか?
『primitive: blog』の新着エントリーを見る
j次のブックマーク
k前のブックマーク
lあとで読む
eコメント一覧を開く
oページを開く