C++ 在Direct3D中将世界、视图和投影矩阵传递给着色器

C++ 在Direct3D中将世界、视图和投影矩阵传递给着色器,c++,matrix,directx,shader,direct3d,C++,Matrix,Directx,Shader,Direct3d,我正在浏览DirectX上的所有MS教程,我注意到它们总是将世界、视图和投影矩阵传递给该技术,然后在顶点着色器中将它们相乘 是否有理由这样做,而不是在绘制之前将矩阵相乘,然后将单个WVP矩阵传递给着色器?这样矩阵就可以每帧相乘一次,而不是每顶点相乘一次,对吗 提前谢谢 编辑:使用示例代码更新 MS教程: matrix World; matrix View; matrix Projection; struct VS_INPUT { float4 Pos : POSITION; f

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

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

提前谢谢

编辑:使用示例代码更新

MS教程:

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;
}

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

因为每个对象的世界矩阵都会更改。如果将WVP矩阵传递给着色器,则每次重新绘制时都必须更改该矩阵-效率非常低,而且在CPU上进行乘法运算也非常缓慢。另一方面,您可以在硬件实例缓冲区中一次性将所有世界矩阵发送到GPU,然后在GPU上将它们全部相乘,这在现代GPU的规模上根本算不上什么,然后发出一个Draw调用

简而言之,当添加硬件实例时,在着色器中执行该操作的效率要高得多

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


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

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


有时,将它们分开(或将世界矩阵分开并使用组合视图投影矩阵)是有意义的。例如,有时您可能希望在世界空间而不是对象空间中进行照明,以便在顶点着色器中访问世界空间顶点位置。如果您正在进行某种实例化,您可能希望像DeadMG所指出的那样保持世界空间矩阵的分离。在许多情况下,您可能希望按照您的建议将它们组合起来。

那么,您是说在CPU上每帧将这三个矩阵相乘一次的效率低于在GPU上每顶点相乘一次(因此每帧可能有数千次)?无论如何,CPU上的世界矩阵每帧都会更新一次。什么?不可以。你在GPU上传递每个实例的世界矩阵,在CPU上乘以VP矩阵一次,然后在GPU上乘以世界和VP。顶点总是只在第一种情况下相乘三次,在第二种情况下相乘一次。我在问题中添加了示例代码。我想我最初误解了你,我以为你说的是顶点和矩阵乘法,实际上,你指的只是矩阵乘法。对不起。