2012/01/15
■Screen Space Fake Omnidirectional Shadow
deferred shading なら、光源位置→ピクセル位置に向かってレイを飛ばして、途中の位置バッファの Z がレイより手前の箇所があったらライティング処理中断すれば、ポストエフェクトで超高速に影を出せるんじゃね?と思いついてやってみた図。
光源位置→ピクセル位置 間を 10 回サンプリング。120 FPS 出ていました。
遮蔽されてたら即中断ではなく、減衰させるようにすればソフトシャドウっぽくなるんじゃね?と思いついてやってみた図。
ぱっと見かなり良い感じに見える絵が出てるんじゃないかと思いますが、問題が 2 つあります。
・位置バッファには一番手前のピクセルしか情報が残っていないため、立体交差を表現できない (そのピクセルは手前から奥まで全部遮蔽されてることになってしまう)
・画面外のオブジェクトの影は出せない (上の動画でも右端とかがたまにおかしくなっている)
後者に関しては、カメラの視錐台に入ってないライトはフェードアウトさせる、とかごまかしようがある気がしますが、前者が致命的です。手前にパーティクルが一粒来ただけでその光源は消失してしまいます。
今作のような、見下ろし視点で光源盛りだくさんゲーならこのままでも実用に耐えそうですが、今後を考えてスマートにポストエフェクト影を実現する方法が欲しいところです。以下、実装までは行ってませんが、思いついたアイデア群。
・裏面描画した位置バッファも作っておき、表面に遮蔽されている && 裏面に遮蔽されていないとき遮蔽と見做す
裏面の位置バッファを作る負担がでかい上、1 オブジェクト分しか交差を表現できない。
・モデルが全部立方体or球という前提の元、全ピクセルに描画元の立方体/球データを持たせて、その形状データと内外判定する
このゲームでしか使えない手法。裏面描画と同等の結果を 1 パスの GBuffer 生成で得られるはず。しかしやっぱり 1 オブジェクト分しか交差を表現できない。
・上記の案の発展。モデル群を Z 座標でソートして奥→手前の順で描画し、DirectX11 で加わった機能である StructuredBuffer で、描画された形状データをピクセル毎にリンクリストで記録。その形状データ群と内外判定する
立体交差も完璧に表現できるはず!ただしこのゲームでしか使えない。
・最初の案の発展。裏面描画、表面描画別々に StructuredBuffer に Z をリンクリストで記録。表面に遮蔽されてる数 != 裏面に遮蔽されてる数 なら遮蔽されていると見做す
2 パス必要なものの、任意の形状の立体交差を表現できる?
StructuredBuffer をまだ使ったことがないのでほんとに実現できるかわからんのですが、Order Independent Transparency みたいな使い方ができるそうなので行けそうな雰囲気はあります。
2012/01/09
■shading blood
SPH (流体シム) を deferred shading でレンダリングしているゲームというのは商用ゲームを見渡してもまだほとんど例がないため、独自性を出す余地がありそうです。なので、描画周りも色々模索中。ただしモデルは全部立方体の集合という縛りで。
面白そうなテーマだったので、血っぽい液体を再現してみました。その経過の記録。 ちなみに deferred shading については、西川善司氏の Killzone2 記事に詳しいです。
まず法線を強引に球面化 ( normalize(ピクセル位置 - インスタンス位置) ) します。
SPH で濃度というパラメータが求まり、これが文字通り密度の高い領域ほど高い数値になっているため、位置データと一緒に CUDA 側から OpenGL 側に転送。高濃度の領域は暗い赤に、低濃度の領域は鮮やかな赤になるように調整 (wikipedia:血液に丁度いい例があったのでそれと睨めっこしつつ)。ハイライトはごく普通に Phong shading。 これだけで割とそれっぽい見た目になってくれました。
ここまで来ると当然剛体が血に濡れて赤く染まるのも再現してみたくなります。
deferred shading のポイントライトは、位置や法線などの GBuffer を参照しつつ影響範囲内のピクセルを参照してライティングしていくわけですが、同じ考え方で、流体が当たった位置に球のモデルを置いて、影響範囲内のカラーバッファを赤で上書きすればそれっぽい効果が出せそうです。
やってみた図。
(カラーバッファの a 要素は shininess にしていて、これも上書きしているので、濡れた箇所のハイライトが鋭くなっています)
当たった箇所全部に球を置いたら重くて死ぬので、実際は適当に間引いています。(上の動画だと 128 衝突に 1 個置くという処理)
球置きっぱなしにしていても重くて死ぬので、時間経過で球を縮小させて消すようにしています。
アップで見ると球置いてるのがバレバレで美しくないですが、初見の人に「おっ」と思わせられる効果は得られるんじゃないかと思います。
本格的にやる場合、剛体毎に血痕用テクスチャを用意して、血痕の球はそちらに描画、とかになりそうですが、めんどくさそうなので今回はここまで。
*追記 2012/01/10
最初の法線を強引に球面化するところで、位置バッファの z も書き換えて、length(pos.xy)>radius な領域を discard することで完璧な球に見せかけることができるのに気づきました。
demoscene でよく使われる技法の応用。
2012/01/02
■atomic C81 preview+
コミックマーケット 81、参加した方々、お疲れ様でした。スペースへ足を運んでくださった方々、ありがとうございました。
事前の告知に従い、コミケ版に若干手を加えたものを公開します。
・現状 8000 系以上の GeForce でしか動きません。Radeon では動きません。快適動作には GeForce 500 系が必要なようです
・自機が行えることは移動のみです (十字キーで通常移動、通常移動中に 1 ボタンでダッシュ)
・自機を追いかけてくる流体を敵にぶつけて倒す、というのがゲームプレイの根幹です
・倒した敵は崩れ落ちて流体となり、攻撃力に転化します
・現状無限に出てくる敵を倒し続けるだけの内容です
・ソースコード同梱。そこそこ簡単にビルドできるように整えてます。Game/Entity/Level.cpp あたりを超頑張って弄ればたぶん独自ステージ作成も可能です
・サウンドは exception に続き、カワノさんが担当しています
ゲーム内容は C81 版と全く同じですが、ソースのリファクタリング、バグ修正、最適化が入っています。パーティクルの増減を高速に行う方法をコミケの後に思いついて、1 割くらい早くなりました。
(ハッシュグリッド構築用のハッシュの上位 1 bit に生存/死亡フラグを持たせることで、一回のソートでグリッド構築と生存/死亡判別を同時に行うという方法)
自分で見てて楽しくて手応えを感じるので、完成品まで持っていきたいところです。
ただ、やはり要求スペックが相当敷居が高い様子。あと Radeon 対応は必須だなあと。
GPGPU 調査のために GeForce GTX 560 Ti の現作業マシンと同価格帯の Radeon マシンを買いまでしたんですが、断然 GeForce の方が GPGPU 性能いいし、CUDA での開発も容易なので、今回は Radeon を切り捨てたという経緯があります。Radeon で GPGPU はなかなか修羅道のようですが、やらねばならんようです。
2011 年は初 GDC や震災や転職で動乱の一年でした。今年も色々ありそうですが、最近は以前に比べると精神的余裕が出てきていて、プライベートの活動も絶やさず続けていきたいところです。
2011/12/27
■現状報告&告知
流体と剛体キャラをとりあえず出してインタラクションさせるところまでできましたよという状況。
流体を誘導して敵にぶつけるゲームになる予定です。まだ未実装要素が多すぎて全然ゲームになってませんが、時間の都合により上の動画がもうちょっとマシになった程度のものが出展内容になりそうです。たぶんコミケ直前でもう一回動画上げます。
3日目東ヒ-20b primitive、CD-R で 100 円頒布、ソースコード同梱。たぶんコミケ版に近いバージョンを後日 web で無料公開します。
GPGPU により、計算パワー酷使ゲーの表現の幅が大幅に広がるもんと期待してたんですが、意外とそこまで余裕はないことが判明し、試行錯誤を重ねてる期間で大分時間を食ってしまいました。
流体の挙動そのものの計算もさることながら、生死判定してソートして増減させたりする部分が予想外に遅かったり。当初は剛体もパーティクルの集合で表現しようとしてたものの、それではあまりに重いと分かり、見た目がパーティクルなだけで内部的には geometric に計算するように変えたり、その見た目のパーティクルの位置も CPU 側で計算するように変えたり。当然ながら描画で重いことやると GPGPU に使える時間はほとんどなくなってしまったり。「もう重い計算は全部 GPU にやらせればいいんじゃね?」とか思っていた時期もありましたが、逆に CPU も依然重要なのだと実感させられました。
他にも、ノートパソコンは最新のドライバを入れられないことが多いため CUDA 4 使ってる今作は動かせないケースがあることが判明したり、そもそも 6 万パーティクルとかになってくると非モバイルの GeForce 500 系じゃないと厳しいことが判明したり、まだ GPGPU をゲームプレイに活かすのは時期尚早なんじゃないかと思わされました。まあそういう時期だからこそチャレンジする価値も大きいと思われます。
夏コミあたりを目標に完成品に仕上げてみたいところです。




