高度な検索
Developer Connection
Member Login ログイン | ご入会 ADC連絡先

Technote 1109

Optimizing QuickDraw3D 1.5.3 Applications For Maximum Performance


目次

はじめに

QD3D 1.5.3 アプリケーションで最高のパフォーマンスを発揮させる最適化テクニック

3D アクセラレータを使ってパフォーマンス向上させる方法

要約


QuickDraw3D (QD3D) のドキュメントには掲載されていませんが、デベロッパが QD3D の典型的なアプリケーションのパフォーマンスを向上させるテクニックはたくさんあります。この TECHNOTE では、パフォーマンスを向上させるテクニックを説明します。この TECHNOTE は、3D グラフィックの基本知識と『3D Graphics Programming With QuickDraw 3D』(Addison-Wesley 刊) にあるような QD3D のプログラミング知識が前提となっていることをご了承ください。


はじめに

3D ソフトウェアのデベロッパは、強力な機能をアプリケーションに追加し続けています。ところが、アプリケーションが複雑になるにしたがって、全体のパフォーマンスが犠牲になる可能性が出てきました。現在の QD3D のドキュメントには、典型的な QD3D アプリケーションでパフォーマンスを向上させる方法が説明されていません。この TECHNOTE では、その方法を紹介します。3D アクセラレータがアプリケーションのパフォーマンスに与える効果について説明も行います。


QD3D 1.5.3 アプリケーションで最高のパフォーマンスを発揮させる最適化テクニック

QD3D アプリケーションから最高のパフォーマンスを引き出すために、デベロッパにできることは以下のようにたくさんあります。

トライメッシュ・ジオメトリを使用すること

トライメッシュのパフォーマンス

トライメッシュ・ジオメトリが最初に取り入れられたのは、QD3D 1.5 です (Philip Schneider 氏のdevelop 28: New QuickDraw3D Geometries』と QD3D 1.5.3 SDK の「Trimesh.pdf」のトライメッシュの説明を参照してください)。QD3D 1.5.3 では、インタラクティブ・レンダラのイミーディエイト・モードでトライメッシュを使用する際のパフォーマンスは非常に優れています。速度に重点を置くならば、絶対にトライメッシュの使用を検討するべきです。用途によっては他の QD3D ジオメトリでも同程度に動作する場合もありますが、速度を上げたい場合は、トライメッシュを採用してください。QD3D の将来のバージョンでは、他のジオメトリのパフォーマンスも改善される予定です。

そして、トライメッシュを使用して最高のパフォーマンスを発揮させるには、正しい方法で使用してください。巨大なトライメッシュを作成して 10 の異なるテクスチャ属性を持たせるようなことをしてはいけません。それでは動きません (次のセクションのトライメッシュ・オブジェクトのマテリアルの説明を参照してください)。

1 つのトライメッシュ・オブジェクトに使用するテクスチャは 1 つだけにすること

一般に、トライメッシュ・オブジェクトに使うテクスチャを 1 つだけにすると、パフォーマンスが上がります。テクスチャ属性はトライメッシュデータの triMeshAttributeSet に置いてください。三角形や頂点の 1 つ 1 つにテクスチャを設定してはいけません。

トライメッシュにバウンディングボックスを設定すること

トライメッシュ・ジオメトリには、クリッピングやカリングの速度を上げるために、オプションのバウンディングボックス・パラメータがあります (TQ3TriMeshData データ構造体の bBox パラメータを参照してください)。パフォーマンスを向上させるには、トライメッシュ・ジオメトリの作成でバウンディングボックスを指定してください (バウンディングボックスの指定を正しく行わないとクラッシュする場合がありますので注意してください)。


頂点属性はノーマルおよび UV 座標のみを用いること


パフォーマンスを向上させたければ、オブジェクトに設定するのは次の頂点属性だけにしてください。それは、ノーマル (kQ3AttributeTypeNormal) と UV 座標 (kQ3AttributeTypeSurfaceUV および kQ3AttributeTypeShadingUV) です。

できるだけ多くの頂点を再利用すること

できるだけ多くの頂点を再利用してください。重複した座標を持つ頂点には別々のノーマルが割り当てられ、無駄な頂点を増やすことになります。このような場合は、ノーマルを平均化してダブリを取る方法があります。こうすると、ジオメトリの表面が平坦にはなりますが、実行速度は上がります。


三角形や面の属性にはフェイスノーマルを使用すること

QD3D 1.5.3 の現行バージョンでは、通常は三角形や面の属性にはフェイスノーマルを使用するのがよいですが、そうしないほうがよい場合もあります。フェイスノーマルを指定しないと、QD3D はレンダリングのたびに面の計算を行うことになります。ノーマルの計算は遅いので、たいていの場合 QD3D の速度は落ちます。しかし、データ量が多く、ノーマルの配列がレンダリングの間、L1 または L2 キャッシュに置かれることがない場合は、かえってフェイスノーマルを指定しない方が速い場合もあります。


キャッシュミスが起こると、QD3D にノーマルを再計算させるよりも、多くの時間がかかってしまいます。たいていの場合はフェースノーマルを指定するのがよいのですが、テストを行って、指定しない方がアプリケーションの実行が速いかどうか調べましょう。

また、各三角形の頂点を時計回りの逆順に保管するのが一番です。詳細については、QD3D 1.5.3 SDK の「Trimesh.pdf」ドキュメントを参照してください。

オブジェクトのカリングを独自に行うこと

オブジェクトのカリングを独自の方法で行うこともできます。QD3D はバウンディングボックスを用いてオブジェクトのカリングを行います。この方法はかなり正確で、QD3D のような汎用ライブラリが取ることのできる唯一の方法ですが、しかし非常に遅い方法です。球状のカリングを行う独自の関数を作成するのがよいでしょう。


また適切な場合には、閉じたオブジェクトのバックフェース・カリングを使ってください。このレンダリング方式は他のバックフェース・スタイル (詳細については、『3D Graphics Programming With QuickDraw 3D』の第 6 章を参照してください) よりもかなり速いからです。

レンダリング中は他の処理を最小限に抑えること

レンダリング中に、シーンのワイヤフレーム・ビューを別のウインドウに描いたり、ジオメトリの座標を更新したり、QD3D 以外の構造体を更新するなど、他の作業を行うアプリケーションがあります。こうした処理はすべてレンダリングに影響を与える可能性があります。レンダリングの際にこうした処理に費やす時間を減らせば、アプリケーションのパフォーマンスは改善されます。

バックグラウンドのアプリケーションに与える時間を最小限にすること

多くのアプリケーションが、レンダリング中にもかかわらず、バックグラウンドのアプリケーションに (WaitNextEvent 関数を使って) 時間を与え過ぎています。この状態では、どんな QD3D アクセラレーションを使おうとも、レンダリング中の再描画の間には必ず空き時間が生じてしまいます。バックグラウンドのアプリケーションに与える時間を最小限にできれば、アプリケーションの速度は大幅に改善されます。

グループオブジェクトを使用する際には注意すること

QD3D のグループオブジェクトはオブジェクトの保管と管理に便利な機能です。しかし、各グループが実行時にグラフィックス・ステートのプッシュとポップを行うことに気づいていないデベロッパがたくさんいます。というのは、グループのインラインフラグ (kQ3DisplayGroupStateMaskIsInline) がデフォルトではオフだからです (詳細については、『3D Graphics Programming With QuickDraw 3D』の第 10 章を参照してください)。グループオブジェクトごとにグラフィックス・ステートのプッシュとポップが実行時に起こることになり、パフォーマンスにかなり悪影響を与えます。

グラフィックス・ステートのプッシュとポップを自分で行う必要がある場合は、Q3Push_SubmitQ3Pop_Submit 関数を使用してください。大量のオブジェクトの管理を、独自のデータ構造体を作成して行う方法もあります。

リテイン・モードとイミーディエイト・モード

用途によっては、イミーディエイト・モード (即時モード) を使う方がリテイン・モード (保持モード) を使うよりも速いことがあります。例えば、固定のサブディビジョン・スタイル群を持つ、球または円錐のジオメトリを扱う場合、おそらくイミーディエイト・モードを使った方がパフォーマンスが上がります。

どちらのモードが適しているかは実際に試してみる必要があります。普通、モデルの大部分がフレームごとに変化しない場合は、モデルの作成と描画にリテイン・モードのイメージングを使うのがよいでしょう。しかし、モデルの多くの部分がフレームごとに変化する場合は、イミーディエイト・モードのイメージングを使用し、モデルをシェイプ単位で作成しレンダリングするのがよいでしょう。もちろん、リテイン・モードとイミーディエイト・モードのイメージングを組み合わせて使うこともできます。つまり、モデルの静的部分にはリテイン・モードのオブジェクトを作成し、頻繁に変化するオブジェクトはイミーディエイト・モードで描画するわけです。リテイン・モードとイミーディエイト・モードの説明については、『3D Graphics Programming With QuickDraw3D』の第 1 章を参照してください。

必要な場合以外は Q3View_Sync や TQ3ViewEndFrameMethod を使わないこと

インタラクティブレンダラの使用中は、Q3View_SyncTQ3ViewEndFrameMethod 関数は、必要な場合以外は絶対に使わないでください。これらの関数はレンダラを同期モードにしてしまいます。そのような関数を使うことは避けてください。その方がパフォーマンスがすぐれています。


3D アクセラレータを使ってパフォーマンス向上させる方法

QD3D をサポートする 3D グラフィックス・アクセラレータボードが最近増えてきました。こうしたアクセラレータはほとんどの QD3D アプリケーションのパフォーマンスも改善するよう設計されています。ところが、デベロッパは自分のシステムにこうしたボードをインストールしても、あまりパフォーマンスが上がらないことに失望することが多いようです。この理由の 1 つは、これまでのセクションで説明してきた、QD3D アプリケーションで最大のパフォーマンスを発揮するためのテクニックを使っていないデベロッパが多いからです。

3D アクセラレータの性能を考える際、ほとんどのカードが改善するのは、3D グラフィックスのラスタ処理であることを理解するのが大切です。ご存じの通り、ラスタ処理はレンダリング工程の (通常、最後の方の) プロセスの 1 つです。つまり、プログラムで、NURB ジオメトリのような計算の負荷が高いジオメトリを使用していて、他の処理のコードやジオメトリの計算に多大な時間を費やしている場合は、アクセラレータが「即座に」多角形をレンダリングしても、プログラム全体としてはあまりスピードが向上しません。

また、アプリケーション、ジオメトリ、処理の複雑さが一定のポイントに達すると、ソフトウェアのレンダラーを使用しても、3D アクセラレータを使用しても、アプリケーションのパフォーマンスが同じになってしまう場合があります。デベロッパはテストを行って、このトレードオフが起こるポイントを見極めてください。

例えば、高品質の (トライリニア・ミップマップ) テクスチャ貼り付け、透過、CSG オペレーションなどを追加して、ラスタ処理を「重く」した場合、ソフトウェアレンダラを使用する場合と比較すると、パフォーマンスと品質が大幅に向上します (もちろん、これは使用する 3D アクセラレータカードによっても違います)。3D アクセラレータカードを最大限に利用するには、カード固有の機能を利用できるようにアプリケーションを修正する必要があります。

ほとんどのカードは、程度こそ違え、QD3D アプリケーションの速度を向上させ、しばしばテクスチャの外観をかなり改善します。しかし、汎用のアプリケーションがシーンで生成するものをすべて適切に処理できるわけではなく、性能向上が得られない場合もあります。


要約

以上のガイドラインにしたがえば、大幅に QD3D のパフォーマンスを向上させることができるでしょう。疑わしいと思ったり、上記のテクニックでどの程度アプリケーションの速度が上がるのかを知りたい方には、Pangea Software (http://www.realtime.net/~pangea) の「3DMF Optimizer」という製品があります。この製品は、ここで説明した多くのテクニックを使い、アプリケーション速度の大幅な向上を果たしています。3DMF Optimizer のデモ版が上記の URL で入手可能です。

参考文献
『3D Graphics Programming With QuickDraw 3D』(Addison-Wesley 刊)
develop 28: New QuickDraw3D Geometries』(Philip Schneider 氏)
Pangea Software 社の「3D Optimizer」

更新日: 1997 年 10 月 31 日