Multisample & ShadowMap & PostProcess衝突解決 .

昨天早上,我爲了測試方便,把SettingDialog加入了F11快捷鍵,方便我快速的改變各種設備設定。
結果悲劇發生了...

看到SettingDialog後,我第一個打開的就是MSAA(多重採樣抗鋸齒),之後確定。畫面變成一片慘黑...
我料想可能是後期處理和陰影的問題,按下F3(後期處理開關),畫面亮了,但是效果依然悲劇,畫面結果表現的是深度和模板緩存失效了,最後畫的物體顯示在了畫面的最上面。如下圖

之後,我立即開始思考這個問題,我不由得想到了微軟官方的例子"PostProcess",這裏出問題了,看他的解決方法不就OK了嗎,隨即我打開官方的PostProcess...

第一步
開始,可以應用後期處理效果!

第二步
ChangeDevice,打開一個MSAA吧,MSAA4x, quality4

第三步
PostProcess也華麗的黑屏了  - -|||

 

這下好了,連微軟官方也忽視了這個問題。我開始上網搜索"高手"的解決方法。
無奈,國內似乎高手都無動於衷,可能這個問題都沒有拿出來給大家講。

GOOGLE搜索: 關鍵字Multisample PostProcess | Multisample Shadowmap | Multisample RenderTarget, 搜索到一些國外開發者論壇。

發現有同學和我差不多的問題,有畫面顯示深度錯誤的,也有一片慘黑的。看來老外們討論比較激烈啊!當然多數文章最後並未解決,有一篇文章有高手提議: 可能是(DS Surface)深度模板表面 和 RenderTarget使用了不同的MultiSample格式,因此導致深度錯誤。

我的ShadowMap錯誤和這個類似,因此我選擇試試他的提議,始終提供一個自己建立的無MultiSample格式的深度表面來繪製。果然,成功了,不再出錯,但是MSAA無論怎麼選擇,都和不開啓是一樣的。也就是說,這個解決辦法...行不通...

不過通過這個解決,我大致清楚了可能是由於我的RenderTarget沒有設置爲正確的MultiSample格式,而導致問題出現的,因爲默認的DS就是根據設置來設置MultiSample格式的。因此,我把精力集中在了RenderTarget的Surface上面。果然,RenderTarget的MultiSample格式在調試中仍舊爲none。但是,我應該怎麼改呢?這個surface完全是從texture的getSufaceLevel得來的。

繼續搜索,我發現DX10有一個新特性,支持textrue和surface的bind,完美的解決了這個問題。而DX9貌似還不能支持這個特性,繼續搜索,一個國外高手的一句話,精闢了!

Yes, you can create multisample render targets. But you can't set them as a texture.

Use IDirect3DDevice9::CreateRenderTarget to create a multisample render target. Then, create a regular texture. After rendering to your multisample render target, you'll need to StretchRect() the multisample render target to one of the surfaces in your regular texture.

原來,可以手工BIND上texture和surface。就是建立一個自己想要的屬性的surface,設置爲RT。繪製結束後,使用stretchRect方法複製到texture的surfaceLevel。就實現了一個手工綁定。

之後,有了想法,實現上其實比較簡單,經過一個小時的整理和編碼,終於得到了成功的MSAA結果。

下面放圖

開起MSAA 8x 後的效果,抗鋸齒相當棒了。

細節對比,差別太大了。


 

MSAA確實是必不可少的一環啊,可能MICROSOFT也只是拋磚引玉,所以沒有在PP那個例子上解決這個問題吧。
這個問題我在遇到,思考,求解的過程中,發現國內的相關信息確實比較少了,希望這篇文章能幫到需要幫助的人吧,希望我的TAG夠全面...

發佈了12 篇原創文章 · 獲贊 16 · 訪問量 19萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章