4

我正在阅读有关 DirectX 的所有 MS 教程,我注意到它们总是将世界、视图和投影矩阵传递给该技术,然后在顶点着色器中将它们相乘。

是否有理由这样做,而不是在绘制之前将矩阵相乘,然后将单个 WVP 矩阵传递给着色器?这样矩阵将每帧相乘一次,而不是每个顶点一次,对吧?

提前致谢。

编辑:使用示例代码更新

微软教程:

matrix World;
matrix View;
matrix Projection;

struct VS_INPUT
{
    float4 Pos : POSITION;
    float4 Color : COLOR;
};

struct VS_OUTPUT
{
    float4 Pos : SV_POSITION;
    float4 Color : COLOR;
};

PS_INPUT VS( VS_INPUT input )
{
    VS_OUTPUT output;
    output.Pos = mul( input.Pos, World );
    output.Pos = mul( output.Pos, View );
    output.Pos = mul( output.Pos, Projection );
    output.Color = input.Color;

    return output;
}

为什么不这样:

matrix WVP;

struct VS_INPUT
{
    float4 Pos : POSITION;
    float4 Color : COLOR;
};

struct VS_OUTPUT
{
    float4 Pos : SV_POSITION;
    float4 Color : COLOR;
};

PS_INPUT VS( VS_INPUT input )
{
    VS_OUTPUT output;
    output.Pos = mul( input.Pos, WVP );  
    output.Color = input.Color;

    return output;
}
4

4 回答 4

5

在此示例中,您对世界、视图和投影矩阵进行预乘的建议是有意义的,并且会更有效。对于这个简单的示例,我不确定为什么教程将它们分开。

有时将它们分开是有意义的(或者将世界矩阵分开并具有组合的视图投影矩阵)。例如,有时您可能希望在世界空间而不是对象空间中进行照明,因此您希望访问顶点着色器中的世界空间顶点位置。如果您正在执行某种实例化,您可能希望保持世界空间矩阵分开,并由 DeadMG 指出。在许多情况下,尽管您希望按照您的建议组合它们。

于 2012-11-24T00:58:39.830 回答
3

因为每个对象的 World 矩阵都会发生变化。如果您将 WVP 矩阵传递给着色器,则每次重新绘制时都必须更改该矩阵 - 效率非常低,并且您将在 CPU 上将其相乘,这也将非常慢。另一方面,您可以在硬件实例化缓冲区中一次将所有世界矩阵发送到 GPU,然后在 GPU 上将它们全部相乘,这在现代 GPU 的规模上真的没有什么,然后发出一个 Draw称呼。

简而言之,当您添加硬件实例时,在着色器中执行此操作会大大提高效率。

于 2012-11-22T23:56:40.140 回答
0

我认为每个矩阵都可以在每一帧中改变。除非您以相同的方式查看某些内容,否则如果您将相机视图放置在其他角度或坐标以观察世界/对象,则视图可能会发生变化。

于 2012-11-22T23:51:42.347 回答
0

这样矩阵将每帧相乘一次,而不是每个顶点一次,对吧?

术语“每帧”在这里没有意义,为什么我们称它为顶点着色器?因为它是每个顶点的过程,所以无论您将 3 矩阵乘以单个矩阵的位置(在着色器外部或内部),每个顶点都应在绘制之前应用于该单个矩阵。而GPU是此类任务的更好选择,例如矢量/矩阵计算和其他图形处理。

于 2012-11-23T01:11:01.953 回答