WPF の 3D パフォーマンスの最大化
Windows Presentation Foundation (WPF) を使用して 3D コントロールを構築し、アプリケーションに 3D シーンを含める場合は、パフォーマンスの最適化を検討することが重要です。このトピックでは、アプリケーションのパフォーマンスに影響を及ぼす可能性がある 3D クラスおよびプロパティを、使用する際のパフォーマンスの最適化に関する推奨事項と共に一覧にして示します。
このトピックは、Windows Presentation Foundation (WPF) の 3D 機能に関する高度な専門知識があることを前提としています。 ここでの推奨事項は "描画層 2" に適用されます。これは、ピクセル シェーダーの Version 2.0 と頂点シェーダーの Version 2.0 をサポートするハードウェアとして大まかに定義されています。 詳細については、「グラフィックスの描画層」を参照してください。
パフォーマンスへの影響 : 高
プロパティ |
推奨事項 |
ブラシの処理速度 (最高から最低への順): DrawingBrush (キャッシュ済み) VisualBrush (キャッシュ済み) DrawingBrush (未キャッシュ) VisualBrush (未キャッシュ) |
|
Windows Presentation Foundation (WPF) で Viewport3D のコンテンツを Viewport3D の四角形に明示的にクリップする必要がない場合は、Viewport3D.ClipToBounds を false に設定します。Windows Presentation Foundation (WPF) のアンチエイリアス クリッピングは非常に低速になることがあり、ClipToBounds は Viewport3D に対して既定で有効 (低速) です。 |
|
マウス ヒット テストを実行する際、Windows Presentation Foundation (WPF) で Viewport3D のコンテンツを検討する必要がない場合は、Viewport3D.IsHitTestVisible を false に設定します。3D コンテンツのヒット テストはソフトウェアで行われ、メッシュが多いと低速になります。IsHitTestVisible は Viewport3D において既定で有効 (低速) です。 |
|
異なる素材または変換が必要な場合にのみ、異なるモデルを作成します。 それ以外の場合は、同じ素材や変換を使用する多数の GeometryModel3D インスタンスを少ない数の GeometryModel3D インスタンスや MeshGeometry3D インスタンスにまとめます。 |
|
メッシュ アニメーションでは、メッシュの個々の頂点がフレームごとに変更されますが、これは Windows Presentation Foundation (WPF) では必ずしも効率的ではありません。各頂点が変更されるときの変更通知によるパフォーマンスへの影響を最小限に抑えるには、頂点ごとの変更が行われる前に、メッシュを仮想ツリーから切断します。メッシュの変更が完了したら、再び仮想ツリーに接続します。また、この方法でアニメーション化されるメッシュのサイズができるだけ小さくなるようにしてください。 |
|
3D アンチエイリアシング |
描画速度を向上させるには、EdgeMode 添付プロパティを Aliased に設定することで、Viewport3D に対するマルチサンプリングを無効にします。 3D アンチエイリアシングは、Microsoft Windows XP では既定で無効になっており、Windows Vista では 4 サンプル/ピクセルで有効になっています。 |
テキスト |
3D シーンでのライブ テキスト (ライブである理由はそれが DrawingBrush または VisualBrush に含まれているため) は低速になる可能性があります。 テキストが変化しないのであれば、テキストのイメージを使用するようにしてください (RenderTargetBitmap を使用)。 |
ブラシのコンテンツが静的ではないことが理由で、3D シーンで VisualBrush または DrawingBrush を使用する場合は、ブラシをキャッシュしてみてください (CachingHint 添付プロパティを Cache に設定)。 最小および最大スケールの無効化しきい値を設定することで (CacheInvalidationThresholdMinimum 添付プロパティと CacheInvalidationThresholdMaximum 添付プロパティを使用)、キャッシュされたブラシが頻繁に再生成されないようにすると同時に、望ましい品質レベルを維持します。 既定では DrawingBrush と VisualBrush はキャッシュされません。これは、そのブラシで何かが描画されるたびに、ブラシのコンテンツ全体がまず中間表面に再描画される必要があることを意味します。 |
|
BitmapEffect は、影響を受けるすべてのコンテンツが、ハードウェア アクセラレータなしで描画されることを強制します。 パフォーマンスを最適にするためには、BitmapEffect を使用しないでください。 |
パフォーマンスへの影響 : 中
プロパティ |
推奨事項 |
メッシュが頂点を共有して隣り合う三角形として定義されており、その頂点が同じ位置座標、標準座標、およびテクスチャ座標を持っている場合は、共有される各頂点を 1 回だけ定義し、三角形の定義には TriangleIndices を持つインデックスを使用します。 |
|
サイズを明示的にコントロールできる場合は (RenderTargetBitmap や ImageBrush を使用している場合)、テクスチャ サイズをできるだけ小さくします。 テクスチャの解像度が低いと表示画質が低下するので、画質とパフォーマンスのバランスが適切になるようにしてください。 |
|
Opacity |
半透明の 3D コンテンツ (リフレクションなど) を描画するときは、Viewport3D.Opacity を 1 未満の値に設定して半透明 Viewport3D を別に作成するのではなく、ブラシや素材の不透明度プロパティを (Opacity または Color を介して) 使用します。 |
シーンで使用する Viewport3D オブジェクトの数を最小限に抑えます。 モデルごとに別個の Viewport3D を作成するのではなく、1 つの Viewport3D に多数の 3D モデルを組み込みます。 |
|
通常は、MeshGeometry3D、GeometryModel3D、Brush、および Material を再利用することをお勧めします。 どれも Freezable から派生しており、マルチペアレント可能です。 |
|
Freezable のプロパティがアプリケーションで変更されない場合は、Freezable に対して Freeze を呼び出します。 フリーズさせることにより、作業セットが減り、処理速度が向上します。 |
|
ブラシのコンテンツが変化しない場合は、VisualBrush や DrawingBrush ではなく、ImageBrush を使用します。 2D コンテンツは、RenderTargetBitmap を使用して Image に変換してから ImageBrush で使用します。 |
|
GeometryModel3D の背面を表示する必要が実際に発生しない限り、BackMaterial は使用しないでください。 |
|
光源の処理速度 (最高から最低への順): |
|
メッシュ サイズが次の制限を常に下回るようにしてください。 Positions: 20,001 Point3D インスタンス TriangleIndices: 60,003 Int32 インスタンス |
|
素材の処理速度 (最高から最低への順): |
|
Windows Presentation Foundation (WPF) 3D は、非表示のブラシ (黒のアンビエント ブラシ、クリア ブラシなど) をすべて同じように除外するわけではありません。これらについては、シーンで省略することを検討してください。 |
|
MaterialGroup の各 Material により他のレンダリングが発生するので、素材を多数含めると、それがシンプルなものであったとしても、GPU の塗りつぶし要求が大幅に増加する可能性があります。 MaterialGroup に含まれる素材の数を最小限に抑えてください。 |
パフォーマンスへの影響 : 低
プロパティ |
推奨事項 |
アニメーションまたはデータ バインディングが不要の場合は、変換を複数含む変換グループを使用する代わりに、MatrixTransform3D を 1 つだけ使用し、変換グループ内では個別に存在するすべての変換の積になるように設定します。 |
|
シーンに含まれる光源の数を最小限に抑えてください。 シーンに光源が多いと、Windows Presentation Foundation (WPF) はソフトウェアによる描画を使用します。制限は、およそ 110 DirectionalLight オブジェクト、70 PointLight オブジェクト、または 40 SpotLight オブジェクトです。 |
|
移動するオブジェクトと静的オブジェクトは、別々の ModelVisual3D インスタンスに含めて分離します。 ModelVisual3D は GeometryModel3D より "重い" のですが、その理由は変換された境界をキャッシュするからです。 GeometryModel3D はモデル用に最適化されています。ModelVisual3D はシーン ノード用に最適化されています。 GeometryModel3D の共有インスタンスをシーンに追加するには ModelVisual3D を使用します。 |
|
シーンに含まれる光源の数を変更する回数を最小限に抑えてください。 光源の数を変更するたびに、シェーダーが再生成され、再コンパイルされます。ただし、この構成が前に終了されている (したがってシェーダーがキャッシュされている) 場合を除きます。 |
|
Light |
黒い光は見えませんが、描画時間には加算されるので、省略することを検討してください。 |
MeshGeometry3D の Positions、Normals、TextureCoordinates、および TriangleIndices など、Windows Presentation Foundation (WPF) に含まれる大規模なコレクションの構築時間を最小限に抑えるには、値を読み込む前に、コレクションのサイズを事前に指定します。 可能であれば、コレクションのコンストラクターに、List の配列など、事前に読み込まれているデータ構造体を渡します。 |