ワールドマトリックスを使用する必要がありますか?


8

質問の画像参照:

オブジェクト空間とワールド空間

CGチュートリアルから画像)

D3D9 APIは、世界の行列に慣れました。

ただし、ワールドマトリックスを使用する場合は、シェーダーで追加のマトリックス乗算を行う必要があります(これは、多くの頂点で同じになります)。

したがって、モデリングとビューのマトリックスを1つのマトリックスに連結するOpenGLの規則(GL_MODELVIEWMATRIX = View * World)。

何が良いのか、そしてその理由は?

回答:


7

いいえ。シェーダーに明示的なワールドマトリックスがあることはありません。

理由の詳細な説明はここにありますが、短いバージョンは非常にシンプルです。これが必要になることはなく、浮動小数点の精度が失われる可能性があります。

ワールドスペースが大きすぎる場合は、原点から遠いカメラが浮動小数点の精度の問題を引き起こす可能性があります。

すべてのワールド空間は、モデル空間とカメラ空間の仲介にすぎません。カメラと他のすべてのオブジェクトを同じ空間で表現できる場所です。しかし、それを使用するのは、ワールドからカメラへの行列を生成することだけです。それをモデルからワールドへの行列すべてに適用して、モデルからカメラへの行列を作成します。

行列計算に浮動小数点数の代わりにdoubleを使用することにより、C ++での精度の問題に対処できます。これらをシェーダーにアップロードする前に、これらをフロートに戻すことができます。

では、なぜシェーダーで明示的なワールドスペーストランスフォームが必要になるのでしょうか。あなたのソースコードでは、はい。しかし、シェーダーでは?カメラスペースではできないことをどうすればよいでしょうか。

照明は、ワールドスペースと同じくらい簡単にカメラスペースで行うことができます。あなたがしなければならないすべてはあなたのライトの位置/方向をカメラ空間に変換することです。結局のところ、カメラ空間はワールド空間と同じスケールです。この変換は、フレームごと、ライトごとに1回行います。CPUでもパフォーマンスの負荷はほとんどありません。

したがって、シェーダーを明示的なワールドスペーストランスフォームに公開しても意味がありません。これは、マトリックスに折りたたむ中間ステップにすぎません。


1

シェーダーで追加の行列乗算を行うことはありません。トリックは、CPUでフレームごとに1回行列の乗算を行い、最終結果を頂点シェーダーにアップロードすることです。これにより、ワールドとビューが別々に表示されているか連結されているかに関係なく、頂点ごとの行列乗算によって1つの位置が得られます。


0

多くの場合、とにかく、他の目的のために、頂点シェーダーでワールド位置を設定する必要があります。たとえば、鏡面反射光を評価するためにピクセルシェーダーに渡すには、ビューベクトルを計算する必要があります。

local-to-worldマトリックスは、タンジェントベクトルと法線ベクトル[1]をワールドスペースにシェーディングするために変換するためにも必要です。別の行列のセット)。

したがって、IMOには、ローカルから世界へ、およびワールドからクリップへの2つのマトリックスがあることは理にかなっています。後者は、ビューマトリックスと投影マトリックスの積です。両方を頂点シェーダーに渡し、次のような乗算を行います。

posWorld = mul(posLocal, matLocalToWorld)
posClip = mul(posWorld, matWorldToClip)

[1](不均一なスケーリングがない限り。その場合、法線はローカルからワールドへの行列の逆転置によって変換する必要があります。)



@NicolBolas:良い点。ワールドスペースのシェーディングには精度の問題があります。カメラスペースを使用する必要があるという意味ではありません。私の仕事では、「カメラ中心のワールドスペース」を実際に使用しています。軸にワールドアラインがあると、ワールドスペースに格納されているキューブマップを適用しやすくなります。
ネイサンリード
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.