HEXA BLOG

研究・開発

HEXA BLOGその他研究・開発2009.7.17

高品位な被写界深度レンダリング

こんにちは、イワサキですわーい(嬉しい顔)
前回はリアルタイムフォトンマッピングのデモを作成してみましたがいかがだったでしょうか?目
DirectX9でもまだまだ活用の余地はありますよねパンチ
今回のお題は『高品位な被写界深度レンダリング』です。
これを前回と同じくDirectX9で実現してみます。
今回は下記のGPU機能と技法を複合して活用しています。
ひらめきハードウェアインスタンシング(Hardware Instancing)
ひらめき頂点テクスチャフェッチ(Vertex-shader texture fetch (VTF))
ひらめきリアルタイムレイトレーシング(Realtime ray tracing)
ひらめきHDRレンダリング(High dynamic range rendering)
今回のアイデアはCEDEC2007, 2008にて講演された川瀬正樹氏の発表内容・技法に基づいた実装となります。
そのため、技術内容の紹介の原典は川瀬氏の発表資料がベースとなっていますので元の資料の補助としてこの実装デモを見ていただけたらと思います。
■4Gamer.net ― [CEDEC 2007]写真光学技術を取り込んだレンダリングについて
http://www.4gamer.net/games/000/G000000/20071001016/
初めて見るという人のために講演の内容を私なりに簡易版で少し紹介してみたいと思います。
まず、カメラレンズの仕組みですが、
カメラとは外からやってくる光を受けて一点に焦点を合わせて、そのピントが合うところにCCDやCMOSなどの撮像素子・センサーフィルムを配置しておき記録するものです。
2009-07-17-lens1.png
レンズで光を屈折させて一点に光を集めることになりますので焦点で合焦した光は再び遠ざかりながら拡散します。
このときに光の位置関係は反転しますので写像も逆転したものになります。
理科の実験でやったようなピンホールカメラで映像が反転した経験のある方も居るのではないでしょうか。
2009-07-17-lens2.png
実際のカメラはこれに「絞り」が付いており、絞りの隙間をピンホールカメラのように通過させて、その光をレンズで一点に集めています。
2009-07-17-lens3.png
2009-07-17-lens4.png
上記のようにピントの合わないところはボケてしまうことになります。
絞りを通過する際に絞りの羽根の形状でシルエットが出来上がり、そこを通ってくる光で描き出されるイメージはその絞り形状が積層されたようなイメージになります。
2009-07-17-lens5.png
下記は実際の絞り形状で描き出される撮影結果の実際の例です。
2009-07-17-bokeh02.jpg2009-07-17-bokeh03.jpg
2009-07-17-bokeh05.jpg2009-07-17-bokeh04.jpg
広角レンズなどは光を拾ってくる角度が非常に広く120度近くまで拾うことができます。
その場合は一番外周の場所からレンズへ入ってくる光の入射角も角度がついて入射するわけですが、ここでレンズユニット本体のフードや鏡筒そのものに光が遮蔽されてしまい、届かない光が出てきます。
その欠けた部分が月の蝕のように半月のようなケラレを発生させます。
この写真では外周部の光の丸い形状が欠けたようになっているのが確認できます。
2009-07-17-bokeh01.jpg
では実際にこれをどのようにDirect3Dで実現させるかについてですが、今回の実装のポイントは「1パス多段LODレンダリング」と「スキャッタベースの描画をハードウェアインスタンシングで実装」です。
DirectX9での実現方法についてですが
絞り形状の粒子生成にShaderModel3.0のハードウェアインスタンシングで約23万個(!)のパーティクルを生成するようにしています。
これをすべてのピクセルに並べてピントやケラレに応じて形状をリアルタイムで変化させています。
頂点シェーダー内で深度テクスチャ参照を行ないピントを計測し、その場でスプライト形状を決定しています。
又、今回の独自のアルゴリズムとして1パス多段LODを実現するために複数のテクスチャを1枚に格納できるように最終イメージサイズよりも大きいアキュームレーションバッファとしてレンダーターゲットを作成し、頂点シェーダー内でXY座標をずらすことでLOD切り替えレンダリングを実現しています。
これによって1枚のテクスチャ内に複数枚のLODイメージが1パスで生成できます。DirextX9の既存の機能で実現可能になります。
この生成結果は実際のデモを実行して確認することができます。
2009-07-17-hexa00.jpg
さらにこの複数枚数の縮小バッファを多層合成して最終イメージを生成しています。
パーティクルの形状に今回は5枚羽根の絞りを想定して5角形を使用しています。
6枚羽根、8枚羽根も対応してみましたが点対称な形状ですので後ボケ・前ボケの差が分からないということで非点対象の5角形を選択してみました。
2009-07-17-hexa03.jpg
前ボケ・後ボケの形状も頂点シェーダー内で決定しています。
ボケた部分に絞り形状が出ているのが確認できます。
ケラレの鏡筒との口径蝕衝突判定はピクセルシェーダー内で行なっています。
画面の外周部にカマボコ形・レモン型のケラレの入ったボケが発生しています。
私が実際に所有している10mm-20mm広角レンズもカマボコ型のケラレが発生していましたのでそれに近い見栄えに調整してみました。
2009-07-17-hexa04.jpg


このデモは以下からダウンロードすることができます。
◎動作可能な環境
 <動作条件>
 WindowsXP以降、DirectX9.0c
 シェーダーモデル3.0以降
 頂点テクスチャフェッチ(VTF)対応GPU
VTFを使用している関係でRadeonはHD2000シリーズ以降でのみ動作します。
GeForce 6000シリーズ以降
Radeon HD2000シリーズ以降

特殊なレンダリング手法を用いていますのでドライバの不具合などで一部動作しない環境があるかもしれません。
なるべく最新のデバイスドライバで実行してください。
Download
HexaDOF.zip (約7.84MB)
【動作確認済ハードウェア】
nVIDIA GeForce9800GT
AMD RadeonHD4350
2009-07-17-hexa05.jpg2009-07-17-hexa06.jpg
2009-07-17-hexa07.jpg2009-07-17-hexa08.jpg
【操作方法】
画面左クリック&ドラッグ    視点を回転
    1パス多段LODバッファ表示 ON/OFF


実行環境を持っていない方のために動画を用意しました。
HD解像度で閲覧可能です。


今回のデモは「被写界深度」のためのデモということで、かなり被写界深度を浅い設定にして強くかかるようにしてあります。
スキャッターベースのレンダリングは従来までのガウスぼかしとは違った美しく鮮やかなビジュアルを得ることができます。実際の光学理論に沿った形で忠実に実装することでより本物に近くなったと言えますよね。
CEDEC2007/’08でこの技法の講演をされた川瀬正樹氏にこの場を借りてお礼申し上げます。
前回のリアルタイムフォトンマッピングひらめきも、このスキャッターベースの概念の応用で実装しています。
私は個人的に一眼レフカメラを趣味にしていましたので、実際にゲームCGでこのようなシミュレートができることがとても新鮮で、作っている最中がとても楽しかったですわーい(嬉しい顔)
何事も楽しまないと!ですねるんるん
ちなみに海外でもピントのボケのことを”bokeh”と呼び、日本語がそのままその意味を表す言葉になっています。
味覚の旨みを表す言葉も”umami”だったり、文化の中に日本語も広がっているのですねぴかぴか(新しい)

■関連リンク
【川瀬正樹氏のホームページの講演資料】
◎CEDEC 2007 - Imagire Day
『レンダリストのためのカメラ(光学)理論とポストエフェクト』
http://www.daionet.gr.jp/~masa/column/2007-10-01.html
今回のデモの実装アイデアの元となった講演資料です。

◎GDC 2003 Presentation

http://www.daionet.gr.jp/~masa/column/2003-03-21.html
今回のデモにはStarGlareとCEDEC2004のときのMultipleGaussianFilterを実装しています。
この資料にあるGhostも組み込むとさらにレンズの説得力が増します。

ヘキサドライブでは自社内製ゲームエンジン「ヘキサエンジン」を開発しています。
いろいろな技術を取り込んでゲーム開発を力強く加速させてみませんか?
新卒・中途ともにご応募お待ちしています。
皆さんに会えることを心待ちにしています手(パー)ぴかぴか(新しい)ぴかぴか(新しい)ぴかぴか(新しい)

RECRUIT

大阪・東京共にスタッフを募集しています。
特にキャリア採用のプログラマー・アーティストに興味がある方は下のボタンをクリックしてください

RECRUIT SITE 

NEWS