一段时间以来,我一直在尝试使用 OpenCL 内核将我的 Marching Cubes 算法从 CPU 转移到 GPU。
我遇到的问题是我的内核中的一个函数返回了奇怪的值,所以我编写了一个测试用例,在其中我指定了一个包含 12 个 float3 的数组中的可能返回值,其中 float3 分量为 0、0.5 和 1(请参见下面的代码)
出于某种原因,我得到了非常大的数字,例如,“11”的 edgeIndex 返回 float3: (-145085952., 6.600e-43#DEN, 0) 而它应该是 (1, 0, 0.5)。虽然据我所知,y 坐标基本上是 0,所以这不是问题,但是 x 坐标让我头疼。
起初我认为 OpenCL 在将给定值转换为 float3 时可能会出现问题,所以我用“.f”指定它们(例如 (float3)(0.f, 0.5f, 0.f))。这只会导致更奇怪和不同的结果,这让我觉得我必须在某个地方犯错。我对 OpenCL 还很陌生(这是我第一个使用它的真正项目),而且我也没有长时间编程,所以我希望我不会在这里犯一些新手错误,但我试图解决这个问题和相关问题几天来,我找不到解决方案。
我尽可能地缩小了问题的范围,并测试了代码是否在执行它应该执行的每个步骤。直到“CalculateEdgePos”的函数调用,一切似乎都很好,我得到了预期的结果。我剥离了所有不必要代码的功能(因此您可以忽略“值”参数,因为它现在没有被使用)但现在我已经束手无策了。
返回奇怪结果的函数:
float3 CalculateEdgePos(int edgeIndex, __global int* values)
{
if(edgeIndex == -1)
{
return (float3)(-1,-1,-1);
}
float3 EdgePositions[12] = {(float3)(0, 0.5, 0), (float3)(0.5, 1, 0), (float3)(1, 0.5, 0), (float3)(0.5, 0, 0), (float3)(0, 0.5, 1), (float3)(0.5, 1, 1), (float3)(1, 0.5, 1), (float3)(0.5, 0, 1), (float3)(0, 0, 0.5), (float3)(0, 1, 0.5), (float3)(1, 1, 0.5), (float3)(1, 0, 0.5)};
return EdgePositions[edgeIndex];
}
and the part of the kernel with the function call and the result getting send back to the CPU
(edgeIndex is calculated fine beforehand):
__kernel void MarchCubes(__global float* outVertices, __global int* values, __global int* edges)
{
.
.
.
float3 vertexPos = CalculateEdgePos(edgeIndex, values);
float coords[3] = {vertexPos.x, vertexPos.y, vertexPos.z};
outVertices[get_global_id(0)] = coords[coordIndex];
}
如果你们中的任何人有任何提示或帮助,我将不胜感激。如果您需要更多代码片段,请告诉我,但我认为这应该就足够了,因为它只是指定的函数行为怪异。
亲切的问候,美食家