Yakiimo3D

Mostly DirectX 11 Programming

DX11 Temporal AA Without Manual Blending

はじめに

前回リリースしたTemporal AAデモに手動ブレンドを行わないTemporal AAの実装を追加しました。海外の技術系3Dフォーラムを読んでいるとTemporal AAだからスクリーンショットだとアンチの効果が見えないよというコメントを見かけますが、前回の自分のリリースしたjitterしたフレームを自分でブレンドする実装だとTemporal AAの効果はscreenshotに普通にでます。ただし、自分でAA用のblendingを行わない実装も可能ですし、その場合はTemporal AAの効果がスクリーンショットでは確認できないです。今回は自分でAA用blendを行わないタイプのTemporal AAを実装してみました。

プログラムのソースとバイナリがDLできるCodePlexリンクは記事の最後の方に貼っています。

関連リンク集

1) http://en.wikipedia.org/wiki/Radeon_R420
Radeon X700-X850 シリーズでは今回の手動blendを行わないTemporal AAが実装されていたみたいです。自分のHD5750とCatalyst 10.10ではオプションが表示されないので、最近は機能として用意されていないみたいです。

2) http://techreport.com/articles.x/6672/22
Tech Reportの記事にRadeonでのTemporal AA実装に関する情報がのっています。違うマルチサンプル・パターンを交互に利用する実装のようですが、vsyncが有効で60fpsでアプリが動作する場合は、手動でblendingを行わなくても、脳が自動的にフレーム間の補間を行ってくれ、実際のサンプル数より高品質なAAに見えるらしい。Temporal AAを使用した2x MSAAは4x AAと同等な品質に見えるらしいです。

3) http://forum.beyond3d.com/showthread.php?t=46241
Beyond3Dの”List of Rendering Resolutions + basics on hardware scaling, MSAA, framebuffers”スレでは手動blendingを行う実装と、行わない実装の両方が話題として取り上げられています。

4) http://www.yakiimo3d.com/ja/2010/09/29/dx11-perspective-matrix-jittering-temporal-aa-2/
前回の手動でBlendingを行う自分のTemporal AA実装です。Reprojectionは行わない簡単な実装なので、ghosting/blurringが出ちゃいます。

実装の詳細

jitteringに関してなど実装の詳細は前回のTemporal AA実装から基本的に変わってないです。前回と違う点は、AA用の前フレームとのblendingを自分では行わずに、ユーザーの目、脳による自動的な補間に任せている所です。今回の実装からvsyncの設定を変更できるcomboboxを追加しましたが、vsync-onの60fps以外の、vsync-offの60+fps、vsync-onの30fps、vsync-onの20fpsは全部、シーンのチラツキがひどいので、vsync-onで安定した60fpsが今回の手法にとっては必須みたいです。前回の手動でblendingを行う場合はblurring/ghostingが問題となり、今回の手動で行わない場合は画面のチラツキが問題となるみたいです。

Radeonでの実装とは違い、MSAAパターンではなく、jitterされたシーンを交互に描画しているので、品質的には前回のTemporal AAと同じく、2x SSAAと同等なはずです。実際リリースしたデモでは今回のTemporal AAはsub-pixel offsetを0.25から0.15に弱めたので、前回のTemporal AAと比較して、若干AAのきき具合が弱くなっています。自分の単純な実装だとvsync-onの60fpsでも時々画面のチラツキが気になるので、offsetを小さくしました。

デモ

Source Code & Binary
http://yakiimo3d.codeplex.com/releases/view/56973

フルスクリーンモードの方がfpsが安定して、チラつく事が少ないので、フルスクリーンモードで実行することをお薦めします。前回のtexture mipmap設定バグを修正し、anisotropic filterを16xに設定しました。この設定でも、ほんの僅かですが、シーンの所々でtexture aliasingが改善されているようです(SSAAによるtexture blurringも特にないと思います)。ただし、texture filterの設定にバグがあった自分の実装と説明が駄目駄目なのは変わらないですが。

DirectXサンプルから借用している背景データのサイズがでかいので、デモのzipファイルのファイルサイズが今回もでかいです。前回のTemporal AA実装と同じく、機能的にはDX11は必要ないですが、趣味プログラムはDX11を使うことにしているので、DX11必須となります。

最後の一言

前回のTemporal AAのデモのリリースでは、Nao_uさんのTemporal AA実験でTemporal AAがtexture aliasingにはあんまり効果がでなかった事を教えてもらっていたのに関わらず、自分のデモのバグに気がつけなかったですが、今回は前回のように大きなバグはないはずです。修正報告を色んな所にするのが、結構大変なので、そうであって欲しいです。。。

DirectX11 Tessellation Tutorial Presentation

http://xtunt.com/?p=11
IX Brazilian Symposium on Computer Games and Digital Entertainmentで発表された、DirectX11 Tessellationに関するTutorial Presentationのようです。

http://www.xtunt.com/samples
Presentationのpdfでは上記URLでソースコードが公開されると書かれていました。(2010/11/21時点ではまだ未公開のようです。)

http://xtunt.com/?p=29
ソースコードが別URLでリリースされたみたいです。(2010/11/27追記)

http://www.youtube.com/user/xxnunes
作者のGustavoさんのyoutubeページに自作のDX11 Tessellation実装の動画がアップされています。

作者の人のTwitterでのつぶやきから上記プレゼンテーションの事を知りました。 プレゼンテーションでは簡単なQuad Tessellation、簡単なTriangle Tessellation、最後にTessellatorを利用したパラメトリック曲面の生成が説明されています。ざっと目を通した感じだと、丁寧で分かりやすい内容ですし、DirectX11 Tessellationを勉強するにあたって、良いtutorialだと思います。

Temporal AA Texture Mipmap Settings

http://www.gamedev.net/community/forums/topic.asp?topic_id=583617

gamedev.netのImage of the DayにTemporal AAの画像を投稿してみましたが、通常のテクスチャ・フィルタリングでテクスチャのaliasingを取り除けるはずだというつっこみをもらいました。何かミスっているのかなと思って自分のコードをチェックしてみたら、サンプラーのMaxLodが正しく設定されていなかったみたいです。コードを修正して、mipmapとtrilinear filteringを有効にしたら、texture内のaliasingが大幅に改善されました。Anisotropic Filteringを有効にすると更に画像のぼけている箇所も改善されます。


DX11 Perspective Matrix Jittering Temporal AA

はじめに

Temporal AAアルゴリズムは前フレームに描画された情報をサンプルとして利用する、時間方向でのスーパーサンプリング・アンチエイリアス・アルゴリズムです。Temporal AAの実装方法自体は幾つかあるみたいですが、前フレームと現在フレームの透視投影変換行列をジッタさせ、ブレンドして表示するという単純なアルゴリズムを自分は実装しました。この種類のTemporal AAはBeyond3Dのフォーラムでも話題になっています(http://forum.beyond3d.com/showthread.php?t=46241)。

Nao_uさんもTemporal AAを実装されています。http://game.g.hatena.ne.jp/Nao_u/20100924でNao_uさんのTemporal AA実装のスクリーンキャプチャーや冷静で的確な考察が読めます。

いつものようにプログラムのバイナリとソースが置かれているCodePlexページへのリンクを記事の最後の方に貼っています。

Halo: Reach Temporal AA

http://www.eurogamer.net/articles/digitalfoundry-halo-reach-tech-analysis-article (AAはページ3で取り上げられています。)
Digital Foundryが最近Halo: ReachをTech Analysisで取り上げました。いつもように自社がメディアや開発者に販売している機材を利用して、Halo: Reachを解析していますが、ゲーム内でのアンチエイリアスの特性から、Halo: Reachでのアンチエイリアスは何らかのTemporal AAだと話題にされています。

http://d.hatena.ne.jp/yakiimo02/20100920/1284950755
Digital Foundryの記事に関する自分の日記です

http://d.hatena.ne.jp/yakiimo02/20100923/1285230579
Halo: Reachを実際に購入してプレイした自分のアンチエイリアスに対する感想です。

CryEngine3 Temporal AA

http://advances.realtimerendering.com/s2010/index.html
Siggraph 2010の「Advances in Real-Time Rendering in 3D Graphics and Games」コースの「CryENGINE 3: Reaching the Speed of Light」でCryEngine3でのAA実装についての紹介がありました。CryEngine3では手前の物体と遠方の物体に別々のAAアルゴリズムが適用されるハイブリッドな手法を採用しているそうです。手前の物体に関してはEdge検出ベースのポストプロセスAAが適用され、遠方の物体に関してはTemporal AA(the temporal reprojection with cache miss手法)が適用されるそうです。

Crytekの公開資料でtemporal reprojectionのレファレンスとして下の二つのペーパーが上げられていました。

Accelerating Real-Time Shading with Reverse Reprojection Caching (ACM SIGGRAPH Symposium on Graphics Hardware 2007)
http://www.cse.ust.hk/~psander/
http://www.cse.ust.hk/~psander/docs/reproj2.pdf (pdf)
and
Spatio-Temporal Upsampling on the GPU (I3D 2010)
http://www.mpi-inf.mpg.de/~rherzog/
http://www.mpi-inf.mpg.de/~rherzog/Papers/spatioTemporalUpsampling_preprintI3D2010.pdf (pdf)

http://d.hatena.ne.jp/yakiimo02/20100921/1285088322
CryEngine3 Temporal AAに関する自分のはてな日記記事です。

スクリーンショット


No AA

MSAA 2x

MSAA 4x

Temporal AA 2x

スクリーンショットに対してのコメント

(2010/10/02追加)
http://www.yakiimo3d.com/ja/2010/10/02/temporal-aa-texture-mipmap-settings-2/
上の画像をキャプチャーした時、texture filteringのコードに設定ミスがあったみたいです。texture filteringが正しく適用された場合は、texture内のaliasingがなくなります。Mipmapが普通に適用されている場合はtextureのaliasingに関してはtemporal AAの効果は余りないみたいです。

自分の今回実装したTemporal AAは2サンプルなので、2サンプルのSSAAと同じくらいのクオリティーのはずです。アンチエイリアスの比較用に、ハードウェアのMSAA 2xとMSAA 4xも実装しました。上記スクリーンショットをみて分かると思いますが、長いエッジに関してはMSAA 2xとTemporal AA 2xは同じぐらいのアンチの効き具合です。MSAA 4xの方がTemporal AA 2xとMSAA 2xより長いエッジに関してはジャギーが少なく、綺麗だと思います。テクスチャの内部を見た場合だと、MSAA 2x、MSAA 4xは余り効果がないのに対して、Temporal AA 2xの方は直線がつながり、全体的にaliasingが軽減されているみたいです。Temporal AAは一種のsupersamplingなのでedgeのjaggyだけでなく、ポリゴン表面上のaliasingも軽減してくれます。ただし上記画像のようにtexture aliasingに関してはhardwareのtexture filterがaliasingを軽減してくれるので、簡単に大きい改善を見つける事は難しいようです。ポリゴン表面上のPixel shader aliasingをサンプルと用意した方がよかったです。

自分の日記に格子状パターンのテクスチャの場合の各アルゴリズムのスクリーンショットをアップしました。MSAA 2x、4xはどちらも余り効果がないのに対して、テクスチャ内部のディテールが多い、高周波なテクスチャに関してはTemporal AAは効果が大きいみたいです。http://d.hatena.ne.jp/yakiimo02/20100926/1285523408

MSAAはpixel shaderの描画結果のサンプルは1個しか使用しないですが、SSAA的なTemporal AAでは複数個のpixel shaderサンプルが使用されます。Temporal AAの場合だとある意味画面サイズより高い解像度で実行されているので、細かいディテールに対してアンチエイリアスがかかります。

今回実装したTemporal AAは処理負荷が軽く、静止画には対しては効果バツグンですが、カメラが動き始めると(特に横方向移動)、画面がぼやけてしまう欠点があります。前フレームと現在フレームの差分が大きくなると、ブレンドした時にアンチがかかるというより、残像がかかる風になってしまうみたいです。

実装の詳細

http://glprogramming.com/red/chapter10.html
OpenGL赤本の第10章にaccumulation buffer AAアルゴリズムが説明されています。
http://www.cse.msu.edu/~cse872/tutorial5.html
OpenGL赤本のaccumulation buffer AAアルゴリズムの説明はMichigan State大学のCSE 872 Advanced Computer Graphics授業の上記チュートリアルを読んで知りました。

OpenGL赤本に透視投影変換行列のジッタとOpenGL accumulation bufferを使用した、アンチエイリアスの実装方法の説明が書かれています。アルゴリズムの手順としては、シーンをn-sample回再描画し、毎回の描画時に透視投影変換行列をsubpixel分だけジッタし、結果をaccumulation bufferにブレンドします。ジッタしたsubpixelをn-sample分ブレンドしているので、結果の画像にはSSAA相当なアンチエイリアスがかかりますが、1フレーム内にシーンをn-sample回再描画する必要がある為、多くのリアルタイムアプリにとっては処理負荷が高すぎる手法だと思います。

今回のTemporal AAの実装の考え方はOpenGL accumulation bufferを使用した透視投影変換行列をジッタするアンチと同じですが、処理負荷を軽減する為に、1パス内では1回のシーン描画におさえ、前フレームのサンプルを流用するようにします。自分のTemporal AA実装は前フレームのサンプルと現在フレームのサンプルの2サンプルを使用したAAです。メモリ的には前フレームのカラーバッファを保持するために、フレームバッファと同じサイズのレンダーターゲットが一つ余分に必要となります(現在フレームのレンダーターゲットがすでに必要で無料と考えた場合)。偶数と奇数フレームで違うsubpixelジッタ量を利用して、シーンを描画し、前フレームと現在フレームの描画結果をフルスクリーンのポストプロセスパスでブレンドします。OpenGLのaccumulation buffer AAと同じようにTemporal AA 2xはSSAA 2xと同等な描画結果のはずです。今回の実装で自分が悩んだ点としては、どのようにして透視投影変換行列を加工すればscreen space座標系でのsubpixelのジッタが表現できるのかという事でしたが、下にその計算を行う関数のコードを貼っておきます(ソースを落としてもらえれば、実装は全部みれますが。)

// From temporalAA.cpp
/**
    Based on the OpenGL Red Book Chapter 10.
    http://glprogramming.com/red/chapter10.html
*/

D3DXMATRIX TemporalAA::JitteredFrustum(float left, float right, float bottom,
    float top, float fNear, float fFar, float pixdx,
    float pixdy, float eyedx, float eyedy, float focus, const CameraInfo& cameraInfo) const
{
    float xwsize, ywsize;
    float dx, dy;

    xwsize = right - left;
    ywsize = top - bottom;
    // translate the screen space jitter distances into near clipping plane distances
    dx = -(pixdx*xwsize/cameraInfo.fBackBufferW +
            eyedx*fNear/focus);
    dy = -(pixdy*ywsize/cameraInfo.fBackBufferH +
            eyedy*fNear/focus);

    D3DXMATRIX mPerspective;

    D3DXMatrixPerspectiveOffCenterLH( &mPerspective, left + dx, right + dx, bottom + dy, top + dy, fNear, fFar );

    return mPerspective;
}

Perspective Matrix Jittering Temporal AA Demo

今回のデモではDirectX June 2010 SDKの「powerplant」 sdkmeshモデルを使用しています。DX11 Cascaded Shadowmapsのデモで使用されているモデルです。

デモ中にカメラを移動させていたら描画ががたつく時があります。DXUTのCFirstPersonCameraを使用していますが、Cascaded Shadowmapsデモでも同じような現象が発生します。自分の実装のどこかに問題があるのかもしれませんが、Temporal AAのアルゴリズムの問題ではないです。

Source Code & Binary
http://yakiimo3d.codeplex.com/releases/view/53001

最後に

今回実装したTemporal AAでは実装が比較的容易で、軽い処理負荷でSSAA 2x同等のアンチエイリアスが実現できました。しかし、カメラが動き始めると画面がぼやけてしまい、移動中はTemporal AAを切るなりなどをしないと実用的ではないです。Crytekが採用しているTemporal Reprojectionを使用したTemporal AAは未実装なので、そちらも実装して今回の実装と比較してみるといいかもしれないと思いました。

DirectCompute Cloth Sample Included In Bullet Physics 2.77

http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=5681
先日リリースされたBullet Physics 2.77にAMD提供のOpenCLとDirectCompute版のClothサンプルが追加されたみたいです。

http://channel9.msdn.com/Blogs/gclassy/DirectCompute-Lecture-Series-230-GPU-Accelerated-Physics
上記のErwin Coumansさんのフォーラムアナウンスで紹介されていますが、ATI/AMDのLee Howesさんによる今回のDirectCompute Cloth実装に関するプレゼン動画をMSDNのサイトで見ることが可能みたいです。動画のプレゼン資料も動画のページからDLできるみたいです。

早速Bullet Physics 2.77をDLしてDX11 DirectCompute Clothサンプルを実行してみました。自分のHD5750だとリリースビルドで、5枚のクロスが揺らぐシーンで310-350fpsぐらいの実行速度でした。フォーラムアナウンスでも書かれていましたが、衝突判定が未実装な為、Clothの一部が自分自身を貫通したりしますが、全体的にはいい感じです。

http://cedec.cesa.or.jp/2010/program/PG/C10_P0206.html
今年のCEDEC 2010でのAMD DirectComputeセッションで今回のBulletにインテグレートされたCloth Simulationサンプルがトピックとして取り上げられたみたいです。今年はCEDECの幾つかのセッションに行かせてもらいましたが、AMDのDirectComputeセッションには行っていないです。