0

固定シェーダー パイプラインまたはプログラム可能なシェーダー パイプラインのどちらを使用する場合でも、一般的な頂点パイプラインは、次の行列乗算 (カスタム コードまたはバックグラウンド) で構成されます。

Projection * Modelview * Position

Modelview多くのチュートリアルでは、オブジェクトの回転などの項目をマトリックスに入れる必要があることに注意しています。

度に基づいて標準の回転行列関数を作成し、角度パラメーターに適切な 90 の倍数を追加して、画面の自動回転方向を考慮しました。動作します。

さまざまな画面サイズ (画面のさまざまなピクセル幅と高さ) の場合、マトリックスにこれらの多くを組み込むScaleことができるように、そこに乗数を考慮することもできます。Modelview

しかし、私が落ち着いたのは、はるかに冗長な行列計算です。私はこのようなことに慣れていないので、これが賢明かどうかについてフィードバックをいただければ幸いです。

スケールや回転などのオブジェクト操作に加えて、画面サイズのスケーリングと画面の向きに独立したマトリックスを追加するだけです。私はこれで終わります:

Projection * ScreenRotation * ScreenScale * Translate * Rotate * Scale * Position

これらのいくつかは、交換可能な順序であり、交換Rotate可能Scaleであることがわかりました。

これにより、より微調整された制御とコードの分離が可能になるため、たとえば、画面の向きを同時に考えることなく、オブジェクトの回転だけに集中できます。

これは、行列計算を適切に整理するための一般的または許容可能な戦略ですか? うまく機能しているように見えますが、そのような冗長性には落とし穴がありますか?

4

1 に答える 1

3

このような冗長性の主な問題は、GPU で実行すると貴重な計算サイクルが無駄になることです。各マトリックスはユニフォームとして提供されるため、GPU はすべての頂点の計算を強制されますが、実際にはシェーダー全体で定数になります。行列の良いところは、単一の行列が一連の変換全体を保持でき、単一のベクトルと行列の乗算で変換を実行できることです。

典型的なスタンザ

Projection · Modelview · Position

2 つの行列を使用するということは、通常、Modelview · Positionいくつかの計算の中間結果が必要になることに由来します。理論的には、全体を次のように縮小できます。

ProjectionViewModel · Position

今、あなたはこの行列式を提案しています

Projection * ScreenRotation * ScreenScale * Translate * Rotate * Scale * Position

うーん… このすべてが柔軟性のなさの頂点です。柔軟性が欲しいですか?これはリジッドです。すでに回転したジオメトリに不均一なスケーリングを適用したい場合はどうでしょうか。行列演算では演算の順序が重要であり、それらを自由に混在させることはできません。球を描いていると仮定します

Rotate(45, 0, 0, 1) · Scale(1,2,1) · SphereVertex

~とは全く違うように見える

Scale(1,2,1) · Rotate(45, 0, 0, 1) · SphereVertex

画面のスケールと回転は、追加のマトリックスを必要とせずに、Projection マトリックスに直接適用できます。重要な理解は、すべての線形変換チェーンを単一のマトリックスに構成できるということです。また、実用的な理由から、チェーンの最後のステップとしてスクリーン ピクセル アスペクト スケーリングを適用し、チェーンの最後から 2 番目のステップとしてスクリーンの回転を適用する必要があります。

したがって、シェーダーではなく、ディスプレイ ルーチンのフレーム セットアップ コードで射影行列を構築できます。私のlinmath.hを使用していると仮定すると、次のようになります

mat4x4 projection;
mat4x4_set_identity(projection);
mat4x4_mul_scale_aniso(projection, …);
mat4x4_mul_rotate_Z(projection, …);
if(using_perspective)
    mat4x4_mul_frustum(projection, …);
else
    mat4x4_mul_ortho(projection, …);

結果の行列projectionは、射影行列一様として設定します。

于 2013-01-11T11:08:25.257 に答える