2012-04-04 12 views
0

私はフィールド深度のポストプロセスを作成しようとしていますが、どこで開始するのかはわかりません(私が現在行っているレンダーデプスマップを除く)。 XNA3.1のチュートリアルはすべて、実際にあなたに説明や書籍の一部を提供していません。C#/ XNA/HLSL - 被写界深度を作成するには?

したがって、DOFのレンダリング方法の詳細なステップバイステップの手順を実行できますか?

答えて

8

ここでは、Reachプロファイル内でXNAによって提供される「すぐに使える」機能を使用して基本的な近似を達成する方法について説明します。

あなたが組み込みのものを使ってC#でそれを行う方法を学んだら、HLSLでそれを達成することはもう少し明らかになります。

また、Windows Phone 7用のゲームを制作したい場合は、ここではWindows Phone 7でカスタムシェーダーがサポートされていないため、どこから起動するのかが分かります。

まず私たちは表情を生成するために必要なこまごまとを保持するために、いくつかのインスタンス・レベルの変数を定義します:

BasicEffect effect; 
List<Matrix> projections; 
List<RenderTarget2D> renderTargets; 
SpriteBatch spriteBatch; 

次に、LoadContent()メソッドでは、我々は彼らをアップロードを開始します。

BasicEffectのインスタンスが続く
spriteBatch = new SpriteBatch(GraphicsDevice); 

:我々は最後のシーンをレンダリングするために使用しますよSpriteBatchを皮切り

effect = new BasicEffect(GraphicsDevice); 
effect.EnableDefaultLighting(); 
effect.DiffuseColor = Color.White.ToVector3(); 
effect.View = Matrix.CreateLookAt(
      Vector3.Backward * 9 + Vector3.Up * 9, 
      Vector3.Zero, 
      Vector3.Up); 
effect.World = Matrix.Identity; 

effect.Texture = Content.Load<Texture2D>("block"); 
effect.TextureEnabled = true; 
effect.EnableDefaultLighting(); 

基本エフェクトの設定方法の詳細はありませんここで重要です。単にレンダリングする効果があります。あなたが各突起の最後の2つのパラメータを調べると、あなたは我々が効果的にここでやっている世界を分割されているものに気づくでしょう

projections = new List<Matrix>() { 
     Matrix.CreatePerspectiveFieldOfView(
     MathHelper.ToRadians(60f), 
     GraphicsDevice.Viewport.AspectRatio, 
     9f, 
     200f), 
    Matrix.CreatePerspectiveFieldOfView(
     MathHelper.ToRadians(60f), 
     GraphicsDevice.Viewport.AspectRatio, 
     7f, 
     10f), 
    Matrix.CreatePerspectiveFieldOfView(
     MathHelper.ToRadians(60f), 
     GraphicsDevice.Viewport.AspectRatio, 
     0.2f, 
     8f)}; 

次は、我々はいくつかの投影行列を必要としています各塊がカメラからの異なる距離の範囲をカバーする「塊」になる。

9単位を超えたものから、カメラから7単位と10単位の間のもの、最後に8単位に近いものがあります。

(あなたはあなたのシーンに応じて、これらの距離を微調整する必要があります重複を少量ますのでご注意ください。)

次の我々はいくつかのレンダーターゲットを作成します:

var pp = GraphicsDevice.PresentationParameters; 

renderTargets = new List<RenderTarget2D>() 
{ 
    new RenderTarget2D(GraphicsDevice, 
     GraphicsDevice.Viewport.Width/8, 
     GraphicsDevice.Viewport.Height/8, 
     false, pp.BackBufferFormat, pp.DepthStencilFormat), 

     new RenderTarget2D(GraphicsDevice, 
     GraphicsDevice.Viewport.Width/4, 
     GraphicsDevice.Viewport.Height/4, 
     false, pp.BackBufferFormat, pp.DepthStencilFormat), 

    new RenderTarget2D(GraphicsDevice, 
     GraphicsDevice.Viewport.Width, 
     GraphicsDevice.Viewport.Height, 
     false, pp.BackBufferFormat, pp.DepthStencilFormat), 
}; 

それぞれがターゲット対応をレンダリング前述の「チャンク」に変換する。実際に単純化されたぼかし効果を達成するために、各レンダーターゲットは異なる解像度に設定され、「最も遠い」塊は低解像度であり、最も近い塊は高解像度である。

描くために()メソッドを飛び越える、私たちは私たちのシーンチャンクレンダリングすることができます。 を(必ず各チャンク内の背景を描画しないようにしている)

 effect.Projection = projections[0]; 
     GraphicsDevice.SetRenderTarget(renderTargets[0]); 
     GraphicsDevice.Clear(Color.Transparent); 
     // render scene here 

     effect.Projection = projections[1]; 
     GraphicsDevice.SetRenderTarget(renderTargets[1]); 
     GraphicsDevice.Clear(Color.Transparent); 
     // render scene here 

     effect.Projection = projections[2]; 
     GraphicsDevice.SetRenderTarget(renderTargets[2]); 
     GraphicsDevice.Clear(Color.Transparent); 
     // render scene here 

     GraphicsDevice.SetRenderTarget(null); 

はだから今我々が壊れて、私たちのシーンを持っています遠くまでぼやけてしまいました。残っているのは、最終的なイメージを作り直すためです。

まずステップ、(素晴らしい)バックグラウンドレンダリング:

GraphicsDevice.Clear(Color.CornflowerBlue); 

次はさらにから最も近いに、各チャンクをレンダリング:

spriteBatch.Begin(
     SpriteSortMode.Deferred, 
     BlendState.AlphaBlend, 
     SamplerState.AnisotropicClamp, 
     null, null); 

    spriteBatch.Draw(renderTargets[0], GraphicsDevice.Viewport.Bounds, Color.White); 
    spriteBatch.Draw(renderTargets[1], GraphicsDevice.Viewport.Bounds, Color.White); 
    spriteBatch.Draw(renderTargets[2], GraphicsDevice.Viewport.Bounds, Color.White); 

    spriteBatch.End(); 

とビオラを!私たちは、Dever Of Fieldの近似値の周りに少し粗いながらも、ある程度の値を持っています。

Reachプロファイルの範囲内にいる場合は、各チャンクを複数の解像度でレンダリングし、結果の画像をAdditive BlendStateなどを使って結合することで、ぼかし効果を向上させることができます。

一方、HiDefプロファイルでカスタムシェーダーを作成する場合は、概念はほぼ同じです。実行方法が変わるだけです。

たとえば、低解像度のレンダリングをより本格的なガウススタイルのぼかしに交換するか、または塊のコースグレインのアイデアをディッチし、奥行きマップに基づいて比較的細かいぼかしの方法に移動します。

関連する問題