我已经成功地将Marching Cubes的实现从CPU移植到了OpenGL计算着色器中,但是我还没有解决法线问题,并且想知道实现该目标的最佳方法。使用二进制值字段(我正在尝试对尚没有距离估计器的3D分形函数进行建模),因此渐变和正向差异方法将不起作用。我有共享的顶点在工作,我的CPU实现使用此处描述的Quilez方法将面法线累积到每个相邻的顶点上。

我可以将此实现移植到另一个着色器上,但是我看到的问题是是需要的大量原子。因为我们只能在标量整数类型上使用原子,并且我想不出一种以可加方式将3个有符号的int打包为1的方法,所以这意味着3个轴* 3个顶点= 9个原子每次着色器添加。它们当然会散布在整个内存中,所以这不像是击中一个原子计数器9次,但看起来仍然像是个地狱。

另一种选择是在每个对象上运行着色器调用-polygon并构建人脸法线列表(我可能会用这种方式打包到x10y10z10),然后使用每个顶点的着色器累积相邻人脸的所有法线。尽管这将是一个巨大的内存消耗,面部索引的存储空间每个顶点需要12 int才能处理最坏的情况。还有一个问题,如何在不再次使用原子的情况下写入该存储中,就可以算出已经向特定顶点写入了多少张面。

#1 楼

对于仅nVidia的解决方案,您可以使用浮点原子添加内部函数(例如NvInterlockedAddFp32)来解锁HLSL中的GPU内部函数。 NVIDIA Developer

我在80.000个顶点网格上进行了尝试,而且速度非常快(如果我没记错的话,在GTX980M上大约是1或2 ms)

请当心编译您的为使内部函数起作用而发布的着色器(由于nvidia错误/局限性)

也要提防顶点分裂(例如,由于UV不连续性),您必须处理它们,否则您会在UV接缝处有多余的硬边缘。

评论


$ \ begingroup $
因为问题很旧,所以我会问你:-)因为我的理解是,仅了解每个顶点的邻接信息不足以胜任鲁斯?
$ \ endgroup $
–安德烈亚斯(Andreas)
17年9月19日在15:34

$ \ begingroup $
这是去年为我的论文项目准备的,最终我只用了愚蠢的方法,使用了整数原子加法,按比例放大以最大化精度,然后将其归一化为浮点向量。无法找到一种方法来列出每个顶点周围的面,而又不分配最坏情况的空间并使用原子计数器来构建列表。这可能效率不高,但从CPU版本和一流的标记来看,我仍然获得了几个数量级的提速,因此我对此非常满意:)
$ \ endgroup $
– russ
17/09/26'7:23

$ \ begingroup $
“请谨防在发布中编译着色器以使内部函数起作用(由于nvidia错误/限制)”,您救了我的一天,谢谢。
$ \ endgroup $
– iMineLink
20年6月1日,9:06