zoukankan      html  css  js  c++  java
  • D3D11 IASetVertexBuffers 函数与顶点数据的两种组织方式

    D3D11中的 IASetVertexBuffers 函数用来向GPU传递顶点数据。
    一般情况下,我都是传入一个buff,也即在0号slot上绑定了一个buff,其他slot都没有绑定buff。
    我传入的这个buff,是一个存储了顶点结构体数据的数组,每个顶点结构体中都有Position成员,Color成员,UV成员等等。
    用术语来描述我这种做法,就是“交错的顶点数据”,英文称呼有这些 Interleaved Vertex Data , an array of structs 。

    相对应的,另外一种做法就是“非交错的顶点数据”“分离的顶点数据”,英文称呼有这些 Non-Interleaved Vertex Data , De-Interleaved Vertex Data , separate Vertex Data , a struct of arrays 。

    这种做法的具体方案是,把顶点的所有的Position成员填充到buff0中,把所有的Color成员填充到buff1中,把所有的UV成员填充到buff2中,等等。

    当执行 IASetVertexBuffers 函数时,0号slot绑定buff0,1号slot绑定buff1,2号slot绑定buff2,等等。

    需要注意的是,当为顶点数据创建 InputLayout 时,
    如果是交错的顶点数据,示例如下:
      D3D11_INPUT_ELEMENT_DESC vertexDesc[] =
      {
        {"POSITION",    0, DXGI_FORMAT_R32G32B32_FLOAT,        0, 0,                                                               D3D11_INPUT_PER_VERTEX_DATA, 0},
        {"COLOR",         0, DXGI_FORMAT_R32G32B32A32_FLOAT,  0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0},
        {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT,               0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0},
      };
    如果是分离的顶点数据,要为每个成员设置正确的slot序号,示例如下:
      D3D11_INPUT_ELEMENT_DESC vertexDesc[] =
      {
        {"POSITION",     0, DXGI_FORMAT_R32G32B32_FLOAT,        0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
        {"COLOR",         0, DXGI_FORMAT_R32G32B32A32_FLOAT,   1, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
        {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT,                2, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
      };

    很多编程教材里面都是使用“交错的顶点数据”这种做法,我也长期使用这种做法。
    最近上网查询了一下,很多人都提倡使用“分离的顶点数据”这种做法,优点如下:
    1,一个模型有Position成员,Color成员,UV成员。在某些情况下可能只需要向GPU中传递一类成员或者两类成员,本做法能够节省带宽。
         例子1,绘制ShadowMap时,只需要传递Position成员。
         例子2,做插值的骨骼动画时,在slot0中传递上一帧的Position和Normal,在slot1中传递当前帧的Position和Normal,在slot2中传递其他的顶点数据成员。
    2,一个模型有Position成员,Color成员,UV成员。其中某一类成员的值需要频繁的发生变化,本做法能够降低内存拷贝的大小。例如,Position成员在每帧都要发生变化,那么只需要更改它的buff。
    3,模型1和模型2有相同的Color成员,那么模型1和模型2就可以共用一个Color buff。本做法能够节省内存。
    4,在GPU渲染时,当GPU需要若干个Position成员时,只需要从Position buff中读取若干个Position成员,需要多少就读多少,没有浪费,本做法能够提升GPU的工作流水线的效率。如果是交错的顶点数据,GPU必须读取若干个顶点结构体,才能拿到若干个Position成员。

    参考链接

    https://developer.apple.com/library/archive/documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/TechniquesforWorkingwithVertexData/TechniquesforWorkingwithVertexData.html
    https://anteru.net/blog/2016/storing-vertex-data-to-interleave-or-not-to-interleave/
    https://gamedev.stackexchange.com/questions/66545/vertex-buffers-interleaved-or-separate
    https://stackoverflow.com/questions/19822102/non-interleaved-vertex-buffers-directx11

  • 相关阅读:
    IDEA导入jar包
    怎么在idea中新建package包,只有directory选项
    Python在自动化运维时经常会用到的方法
    SocketServer 网络服务框架
    导入自定义包
    socket编程
    在线安全清空慢查询日志slowlog
    OS X中微信双开
    OS X中crt中文乱码
    谈谈TCP中的TIME_WAIT
  • 原文地址:https://www.cnblogs.com/oilcode/p/10451785.html
Copyright © 2011-2022 走看看