我正在尝试使用 DirectCompute 对顶点进行蒙皮。所采用的蒙皮方法是,您可以拥有影响每个顶点的可变权重(例如,Md5 网格以这种方式定义)。
基本上计算着色器的输入是。
JointsBuffer { float4 orientation, float4 position } Structured buffer SRV
WeightsBuffer { float3 normal, float4 position, float bias, uint jointIndex } Structured buffer SRV
VerticesBuffer { float2 texcoords, uint weightIndex, uint numWeights } Structured buffer SRV
输出是
SkinnedVerticesBuffer { float3 normal, float4 position, float2 texcoord } Structured buffer UAV
现在计算着色器应该在顶点缓冲区中的每个元素运行一次,并使用 SV_DispatchThreadID 着色器尝试为 VerticesBuffer 中的每个顶点填充 SkinnedVerticesBuffer 中的相应 SkinnedVertex(1:1 对应)。
所以问题是许多网格有超过 65535 个顶点,而 DispatchThreadID 命令只允许在每个维度上调度那么多线程。现在我理论上可以写一些东西,将很多数字分成小于 65535 的三个因子的组合,但我不可能对素数这样做。
因此,例如,当一些具有 71993 (质数)顶点的网格出现时,我想不出一种方法来处理它。
我不能用 context->Dispatch( 36000, 2, 0 ) 过度调度说 72000 个线程,因为这样 DispatchThreadID 将用完我的缓冲区边界。
现在我倾向于一个保持顶点数量的恒定缓冲区,然后过度调度到最接近的 2 次方,然后简单地做
if( SV_DispatchThreadID > numVertices ) return;
这是我唯一的选择吗?其他任何人都会遇到这个障碍。