0

Assimp を使用して 3D モデルをインポートし、法線マップのタンジェントとバイタンジェントを提供していますが、頂点シェーダーでタンジェントとバイタンジェントのベクトルを乗算するために使用されるマトリックスがどのように見えるかわかりません。 WorldViewProjection マトリックスまたはその他の特別な目的の「通常のマトリックス」?

更新:私の頂点シェーダー

const std::string gVertexShader =   "#version 330                                                                                       \n \
                                                                                                                \n \
                                        layout(std140) uniform;                                                 \n \
                                                                                                                \n \
                                        uniform UnifTransform                                                   \n \
                                        {                                                                       \n \
                                            mat4 mWVPMatrix;                                                    \n \
                                            mat4 mWorldMatrix;                                                  \n \
                                            float mTextureTilingFactor;                                         \n \
                                        } Transform;                                                            \n \
                                                                                                                \n \
                                        layout(location = 0) in vec3 vert_position;                                             \n \
                                        layout(location = 1) in vec3 vert_normal;                                                   \n \
                                        layout(location = 2) in vec2 vert_texcoord;                                                 \n \
                                        layout(location = 3) in vec3 vert_tangent;                                                 \n \
                                        layout(location = 4) in vec3 vert_bitangent;                                                 \n \
                                                                                                                \n \
                                        out vec3 frag_position;                                                 \n \
                                        out vec3 frag_normal;                                                   \n \
                                        out vec2 frag_texcoord;                                                 \n \
                                        out vec3 frag_tangent;                                                 \n \
                                        out vec3 frag_bitangent;                                                 \n \
                                                                                                                \n \
                                        void main()                                                                                                 \n \
                                        {                                                                                                                   \n \
                                            gl_Position   = Transform.mWVPMatrix * vec4(vert_position, 1.0);    \n \
                                                                                                                \n \
                                            vec4 position = Transform.mWorldMatrix * vec4(vert_position, 1.0);  \n \
                                            vec4 normal   = Transform.mWorldMatrix * vec4(vert_normal, 0.0);    \n \
                                            vec4 tangent = Transform.mWorldMatrix * vec4(vert_tangent, 0.0);   // correct matrix?   \n \
                                            vec4 bitangent = Transform.mWorldMatrix * vec4(vert_bitangent, 0.0);    \n \
                                                                                                                \n \
                                            frag_position = position.xyz;                                       \n \
                                            frag_normal   = normal.xyz;                                         \n \
                                            frag_tangent   = tangent.xyz;                                         \n \
                                            frag_bitangent = bitangent.xyz;                                         \n \
                                            frag_texcoord = Transform.mTextureTilingFactor * vert_texcoord;     \n \
4

2 に答える 2

4

TBN (Tangent, Bitangent, Normal) マトリックス (3x3) は通常、接線空間からオブジェクト空間に移動するために使用されます。法線をこれで乗算して変換できます。法線は本質的に方向性があることに注意してください。そのため、通常扱うほとんどの変換マトリックスとは異なり、これvec3を行うには 3x3 マトリックスのみが必要です。私の考えでは、それがこの特定のマトリックスを「特別な」ものにしているのです。このマトリックスの使用方法に応じて、ライト ベクトルを接線空間に変換するか、法線マップをオブジェクト空間に変換できます。

ただし、一般に、タンジェント、バイタンジェント、および法線ベクトルを個別に乗算することはありません。これらはベクトル空間の基礎を定義するものであり、そのままにしておく必要があります。このベクトル空間に出入りする変換に使用される行列は、これらの 3 つのベクトルから導出されます。


これを実行して、接線空間からオブジェクト空間に変換する行列を作成します (疑似コード)。

mat3 (Tangent, Bitangent, Normal);

もちろん、逆を使用してオブジェクト空間から接線空間に移動できます。Assimp はおそらく (大まかに) 正規直交基底ベクトルを生成するため、逆行列が存在することが保証され、この場合は転置として表すことができます。

ただし、接線と従接線が直交することは保証されていません。テクスチャのシアリングが存在する可能性があり、どちらも法線に対して必ずしも垂直であるとは限りません。一部のモデル インポート ソフトウェアは、TBN ベクトルを出力するときに後処理ステップとして直交化を実行します。ほとんどのチュートリアルでは、この関係が常に存在することを想定しているようです。

于 2013-10-30T22:49:18.093 に答える
3

タンジェントとバイタンジェント (従法線とも呼ばれます) は、法線と同じ規則に従います。実際、接線、従法線、および法線は、3×3 行列で表すことができる表面ローカル空間のベースを形成します。この空間は、モデル ビュー マトリックス (通常のマトリックスとも呼ばれます) の逆転置によって変換されます。

于 2013-10-30T21:19:27.473 に答える