顶点着色器或CPU内的DirectX 11矩阵转换

时间:2017-09-30 13:36:38

标签: directx-11 vertex-shader vertex

CPP: https://github.com/walbourn/directx-sdk-samples/blob/master/Direct3D11TutorialsDXUT/Tutorial08/Tutorial08.cpp

HLSL: https://github.com/walbourn/directx-sdk-samples/blob/master/Direct3D11TutorialsDXUT/Tutorial08/Tutorial08.fx

在DirectX示例(教程8)中,他们正在用局部坐标初始化顶点(我想,不确定正确的术语)

// Create vertex buffer
    SimpleVertex vertices[] =
    {
        { XMFLOAT3( -1.0f, 1.0f, -1.0f ), XMFLOAT2( 1.0f, 0.0f ) },
        { XMFLOAT3( 1.0f, 1.0f, -1.0f ), XMFLOAT2( 0.0f, 0.0f ) },
        { XMFLOAT3( 1.0f, 1.0f, 1.0f ), XMFLOAT2( 0.0f, 1.0f ) },
        { XMFLOAT3( -1.0f, 1.0f, 1.0f ), XMFLOAT2( 1.0f, 1.0f ) },

        { XMFLOAT3( -1.0f, -1.0f, -1.0f ), XMFLOAT2( 0.0f, 0.0f ) },
        { XMFLOAT3( 1.0f, -1.0f, -1.0f ), XMFLOAT2( 1.0f, 0.0f ) },
        { XMFLOAT3( 1.0f, -1.0f, 1.0f ), XMFLOAT2( 1.0f, 1.0f ) },
        { XMFLOAT3( -1.0f, -1.0f, 1.0f ), XMFLOAT2( 0.0f, 1.0f ) },

        { XMFLOAT3( -1.0f, -1.0f, 1.0f ), XMFLOAT2( 0.0f, 1.0f ) },
        { XMFLOAT3( -1.0f, -1.0f, -1.0f ), XMFLOAT2( 1.0f, 1.0f ) },
        { XMFLOAT3( -1.0f, 1.0f, -1.0f ), XMFLOAT2( 1.0f, 0.0f ) },
        { XMFLOAT3( -1.0f, 1.0f, 1.0f ), XMFLOAT2( 0.0f, 0.0f ) },

        { XMFLOAT3( 1.0f, -1.0f, 1.0f ), XMFLOAT2( 1.0f, 1.0f ) },
        { XMFLOAT3( 1.0f, -1.0f, -1.0f ), XMFLOAT2( 0.0f, 1.0f ) },
        { XMFLOAT3( 1.0f, 1.0f, -1.0f ), XMFLOAT2( 0.0f, 0.0f ) },
        { XMFLOAT3( 1.0f, 1.0f, 1.0f ), XMFLOAT2( 1.0f, 0.0f ) },

        { XMFLOAT3( -1.0f, -1.0f, -1.0f ), XMFLOAT2( 0.0f, 1.0f ) },
        { XMFLOAT3( 1.0f, -1.0f, -1.0f ), XMFLOAT2( 1.0f, 1.0f ) },
        { XMFLOAT3( 1.0f, 1.0f, -1.0f ), XMFLOAT2( 1.0f, 0.0f ) },
        { XMFLOAT3( -1.0f, 1.0f, -1.0f ), XMFLOAT2( 0.0f, 0.0f ) },

        { XMFLOAT3( -1.0f, -1.0f, 1.0f ), XMFLOAT2( 1.0f, 1.0f ) },
        { XMFLOAT3( 1.0f, -1.0f, 1.0f ), XMFLOAT2( 0.0f, 1.0f ) },
        { XMFLOAT3( 1.0f, 1.0f, 1.0f ), XMFLOAT2( 0.0f, 0.0f ) },
        { XMFLOAT3( -1.0f, 1.0f, 1.0f ), XMFLOAT2( 1.0f, 0.0f ) },
    };

然后他们通过顶点着色器翻译位置:

XMMATRIX mWorldViewProjection = g_World * g_View * g_Projection;

我的问题是:

1:如果这是一个静态对象(不移动/动画),你还想翻译世界位置(不确定正确的术语),还是想要将对象放在正确的3D空间/场景中?初始化顶点,例如:

{ XMFLOAT3( CorrectWorldX, CorrectWorldY, CorrectWorldZ ), XMFLOAT2( 1.0f, 0.0f ) },

一个完美的例子就是随机生成的等级/地形。

2:如果您使用着色器将位置放置在正确的3d世界空间中而不是仅仅在初始化顶点时执行此操作,会有什么性能影响?

3:对于动画,这是角色动画骨骼转换的首选方法吗?

4:构建关卡时(放置对象)我猜你别无选择,只能通过着色器进行翻译,但是你也可以保存最终位置。

希望这很清楚,因为我正在学习DirectX 11并正确练习!

1 个答案:

答案 0 :(得分:1)

  1. 如果静态对象没有重用,那么它们应该只放在真实世界的坐标中。然后是它的正好几何,但最佳实践是传递平移矩阵以将对象从局部空间定位/定向到世界空间。例如,您将多次使用的树将各自具有指定的旋转,缩放和平移矩阵。你不仅会使用这种技术,还会使用"实例"缓冲区可以快速将矩阵输入GPU并确保每次放置模型时GPU都没有停顿(使用常量缓冲区会引入轻微的停顿,因此在许多模型中使用它们确实会成为命中)。

    < / LI>
  2. GPU中的性能低于在CPU中执行的性能。很少,GPU中的矩阵数学就是它的面包和黄油。显然,在加载到GPU之前,需要通过代码准备缩放/旋转/平移矩阵。 GPU会迅速将顶点从局部空间乘以世界空间(如果要进行曲面细分,则在顶点着色器或域着色器中)。

  3. 动画涉及一些事情,例如骨骼上每个顶点的权重和影响。如果顶点受到多个骨点的影响,则需要在2之间进行冲刺。但是,是的,GPU最适合这样做。计算着色器流式传输到顶点着色器使用的实例缓冲区是计算此更完整和最快速的方法。

  4. 如果你想计算一次,那么CPU就可以了,但最好只保留每个模型的矩阵实例,让GPU围绕顶点计算进行工作。我不愿意尝试保存这些数据,因为内存使用量会快速增长,而且你不会在性能上节省很多。实际上,它可能会更糟糕,因为您每次都必须将这些数据加载到GPU中,并且您也不会从缓存中获益。

  5. 祝你好运