2009-07-11 7 views
1

D3D9に3Dモデリングアプリケーションを作成していますが、これは可能な限り広く互換性を持たせたいと考えています。これは、ハードウェア依存の特徴、すなわちマルチサンプリングをほとんど使用しないことを意味する。しかし、リアルタイムレンダリングは完璧なものである必要はありませんが、マルチサンプリングを行わなくても、エイリアスや貧弱に見える素敵な画面キャプチャを提供する必要があります。D3D9でのアンチエイリアス/マルチサンプリング

スクリーンキャプチャを作成するには、一時的なサーフェスをメモリに作成し、そのシーンを一度レンダリングしてファイルに保存します。私がアンチエイリアス処理をどのように達成できるかについての最初の考えは、オフスクリーンのステンシル面をマルチサンプルとして作成することでしたが、DX自体はD3DMULTISAMPLE_NONEで初期化されていたため、DXでは許されません。

まず、スクリーンキャプチャの作成方法のサンプルを紹介します。既にレンダリングされたフレームのバックバッファを保存する方が簡単だとわかっていますが、実際のレンダリングウィンドウとは異なる次元のイメージを保存する必要があります。ここでは簡潔にするために、エラーチェック、状態復元コード、およびリソース解放を省略しています。 m_d3ddevは私のLPDIRECT3DDEVICE9です。

//Get the current pp 
LPDIRECT3DSWAPCHAIN9 sc; 
D3DPRESENT_PARAMETERS pp; 
m_d3ddev->GetSwapChain(0, &sc); 
sc->GetPresentParameters(&pp); 

//Create a new surface to which we'll render 
LPDIRECT3DSURFACE9 ScreenShotSurface= NULL; 
LPDIRECT3DSURFACE9 newDepthStencil = NULL; 
LPDIRECT3DTEXTURE9 pRenderTexture = NULL; 
m_d3ddev->CreateDepthStencilSurface(_Width, _Height, pp.AutoDepthStencilFormat, pp.MultiSampleType, pp.MultiSampleQuality, FALSE, &newDepthStencil, NULL); 
m_d3ddev->SetDepthStencilSurface(newDepthStencil); 
m_d3ddev->CreateTexture(_Width, _Height, 1, D3DUSAGE_RENDERTARGET, pp.BackBufferFormat, D3DPOOL_DEFAULT, &pRenderTexture, NULL); 
pRenderTexture->GetSurfaceLevel(0,&ScreenShotSurface); 

//Render the scene to the new surface 
m_d3ddev->SetRenderTarget(0, ScreenShotSurface); 
RenderFrame(); 

//Save the surface to a file 
D3DXSaveSurfaceToFile(_OutFile, D3DXIFF_JPG, ScreenShotSurface, NULL, NULL); 

あなたは、私がすなわちD3DMULTISAMPLE_4_SAMPLESでpp.MultiSampleTypeを置き換えることができますが、それはうまくいきませんでした期待していたところであるCreateDepthStencilSurface()への呼び出しを、見ることができます。

次に、D3DDEVTYPE_REFという全く異なるLPDIRECT3DDEVICE9を作成しました。これは常にD3DMULTISAMPLE_4_SAMPLES(ビデオカードに関係なく)をサポートしています。しかし、私のリソース(メッシュ、テクスチャ)はすべて私のHALデバイスのm_d3ddevにロードされています。したがって、REFデバイスの下でシーンをレンダリングするためには使用できませんでした。 Direct3d9ex(Vista)ではデバイス間でリソースを共有できますが、私はXPで作業しています。リソースが非常に多いので、この1つのフレームをレンダリングするためにすべてをリロードしてからアンロードすると、アプリケーションには時間がかかりません。

画像のキャプチャ後の画像(つまり3x3ぼかしフィルタ)をアンチエイリアスするための他のオプションを検討しましたが、それらはすべてかなり虚偽の結果を生成しましたので、可能であればD3Dから正しくアンチエイリアス処理されたシーンを取得してみたい....

任意の知恵やポインタをいただければ幸いです...

ありがとう!

+0

マルチサンプル機能を検出し、使用可能な場所でのみ使用します(パフォーマンスを無効にするオプションを使用することもできます)。あなたがやろうとしていることをやって、互換性を改善しているようなものではないということです。 – U62

+0

これは私の最後の手段ですが、本当にやりたいことは、ビデオカードの機能に関係なく、アンチエイリアス処理された画像を提供できることです。私はリアルタイムレンダリングの品質についてあまり気にしません (これは間違いなく互換性を向上させるでしょう - 参照デバイス_always_はマルチサンプリングをサポートするので、そのタイプのデバイスを使ってスクリーンショットをレンダリングすることができますしかし、まだ上記の問題があるので、私はいくつかの他の解決策を期待していた...) – Metal450

答えて

3

大きなバッファにレンダリングし、ジッタバッファを縮小または結合することによる超サンプリングは、おそらく最善の策です。複数のジッタバッファを組み合わせることで、一定の数のサンプルに対して最高の品質を得ることができます(解像度と倍率の倍数で同等の数のサンプルをレンダリングするだけで、通常のグリッドよりも優れています)が、複数のレンダリングパスの余分なオーバーヘッドがあります。あなたのレンダリングターゲットの最大サポートサイズによって制限されないという利点があります。また、AAの任意のレベルをかなり選択することができます(多くのジッタバッファを組み合わせた場合、精密な問題に注意する必要があります)。

opengl.orgの「Antialiasing with Accumulation Buffer」の記事では、ジッタサンプリング(OpenGLでも基本的に同じです)のための投影行列を変更する方法について説明しています。 Alexander KellerとWolfgang Heidrichの論文「Interleaved Sampling」では、より多くのレンダリングパスを犠牲にしてより良いサンプリングパターンを提供するテクニックの拡張について語っています。リンクを提供できないことについて申し訳ありません。新しいユーザーとして、回答ごとに1つのリンクしか投稿できません。 Googleはそれらをあなたのために見つけるはずです。

レンダリングのルートをより大きなバッファおよびダウンサンプリングにしたいが、最大許容レンダリングターゲットサイズによって制限されることを望まない場合、hereのように中心から離れた投影行列を使用してタイル画像を生成することができます。

+0

これは役に立ちました!ありがとうございました!私は間違いなくこれを調べます:) – Metal450

1

いつでも、幅と高さの2倍(つまり4倍のサイズ)のテクスチャにレンダリングし、それをスーパーサンプリングすることができます。カードがバックバッファのサイズ4倍のテクスチャを作成することができない場合

確かにあなたはまだ

編集...問題を取得したい:心に来る別の方法があります。

小さいジッタでフレームをビューマトリックスに繰り返していくと、好きなだけ多くの画像を生成することができ、後で一緒に追加して非常に高いアンチエイリアス画像を形成することができます。ボーナスは、イメージをレンダリングできるすべてのマシンで動作します。それは明らかに、しかし、遅いです。これを行うと256xAAは本当によく見えます!

+0

+1:これは私がGPUサポートなしで行うことができる唯一の事です。私はビューの行列を変更することについてはよく分かりません。私はあなたが視点の変化のために他のアーティファクトを得ると思っています。しかし、何が起こるかは興味深いでしょう。私はレンダリングされているシーンに依存していると思います。 – gatorfax

+0

ええと...私もこれについて考えていましたが、それは私が行かなければならない方法かもしれません。どういうわけか、MULTISAMPLEによって広くサポートされていた組み込みの機能がないということはちょっと変わったように思えました。これは、私が試したラップトップの半分以上では利用できませんでした! – Metal450

+0

ローエンドのキットには、本当に必要のないハードウェアに費やされる金額(ITはいいですが、必要ではない)はなぜですか? – Goz

0

この記事http://msdn.microsoft.com/en-us/library/bb172266(VS.85).aspxは、レンダリング状態フラグD3DRS_MULTISAMPLEANTIALIASを使用してこれを制御できることを暗示しているようです。アンチエイリアスを有効にしてデバイスを作成できますが、このレンダリング状態フラグを使用してスクリーンレンダリングとオフスクリーンレンダリングをオフにすることはできますか?

私はこれを試していません。

+0

これは私が話しているビデオカード依存のメカニズムです... D3DPRESENT_PARAMETERS.MultiSampleTypeがウィンドウを初期化するときにD3DMULTISAMPLE_NONE以外に設定されていないかぎり、そのレンダステートを有効にしても効果がありません – Metal450

関連する問題