Vulkan Raytracing:未对命中三角形的距离进行排序
Vulkan Raytracing: Distances to hitted triangle aren't sorted
我的光线追踪着色器有一些问题,无法修复。我正在使用 vulkan 和 glsl。
到基元的距离没有排序。这意味着,光线似乎首先击中了一个比另一个更远的颤音。这是正常行为还是我做错了什么?
我用 matlab 验证了这个数据,这意味着,对于我图像中的每个像素,我 return 基元和距离进行进一步计算(最大 40)。但是在结果数据中,(你可以在下面看到)距离没有排序,这导致重新排序的计算时间很长。
在这里你可以看到任意命中着色器:
#version 460
#extension GL_NV_ray_tracing : require
#extension GL_EXT_nonuniform_qualifier : enable
layout(binding = 4, set = 0) buffer primitiveProperties
{
float ids[];
} primitives;
layout(binding = 6, set = 0) buffer distanceProperties
{
float values[];
} distances;
struct RayPayload {
uint outputId;
uint hitCounter;
};
layout(location = 0) rayPayloadInNV RayPayload rayPayload;
hitAttributeNV vec3 attribs;
void main()
{
uint outputIdCurrentTriangle = rayPayload.outputId + rayPayload.hitCounter++;
primitives.ids[outputIdCurrentTriangle] = gl_PrimitiveID + 1;
distances.values[outputIdCurrentTriangle] = gl_HitTNV;
ignoreIntersectionNV();
}
并且光线正常产生:
traceNV(topLevelAS, rayFlags, cullMask, 0, 0, 0, origin.xyz, tmin, direction.xyz, tmax, 0);
但结果看起来像:
[像素的距离][1]
[1]: https://i.stack.imgur.com/FCDhl.png
数据形式:
0.83021832
0.83021832
0.84927511
0.84927511
0.94443458
0.94443458
0.94811541
0.94811541
1.0063932
1.0063932
0.97728723
0.97728723
0.98426312
0.98426312
而且里面可能还有更多的错误。
所以我的问题又来了:发生这种情况正常吗?
感谢您的每一次帮助!
这是完全正常的预期行为。
你的 any-hit-shader 被设计为在 GPU 遍历加速结构时被调用(它以任意顺序发生,无论什么最适合数据布局)。然后,您(通常)只应该调用 ignoreIntersectionNV()
或 reportIntersectionNV()
之一,具体取决于它是否是 可能 命中。您还不应该将其计为有效命中。
在调用最近的命中着色器之前,您对顺序一无所知。途中遇到的可以记录any-hits,后面需要把范围外的丢弃,剩下的按要求排序。
您已经可以在 any-hit-shader 中做一些有意义的事情的唯一例外是针对无限(天空盒、无限距离光源)的可见性测试。在这种情况下,任何命中都可能被接受,您可以立即致电terminateRayNV()
。
通过 Nvidias Vulkan 扩展直接使用光线追踪不适合解决与顺序相关的问题。
为此,您必须以迭代方式发射光线(在 any-hit 中过滤,甚至 VK_GEOMETRY_OPAQUE_BIT、re-launch 在 closest-hit 中过滤)或构建一个良好的旧D-buffer 基于您从 any-hit 次调用中记录的潜在命中。
如果您需要有序的命中,并且您的几何形状不是太复杂,那么您可能宁愿看看 signed-distance-fields,如果适合您的应用程序。它们在遍历过程中提供稳定的顺序。
我的光线追踪着色器有一些问题,无法修复。我正在使用 vulkan 和 glsl。 到基元的距离没有排序。这意味着,光线似乎首先击中了一个比另一个更远的颤音。这是正常行为还是我做错了什么? 我用 matlab 验证了这个数据,这意味着,对于我图像中的每个像素,我 return 基元和距离进行进一步计算(最大 40)。但是在结果数据中,(你可以在下面看到)距离没有排序,这导致重新排序的计算时间很长。
在这里你可以看到任意命中着色器:
#version 460
#extension GL_NV_ray_tracing : require
#extension GL_EXT_nonuniform_qualifier : enable
layout(binding = 4, set = 0) buffer primitiveProperties
{
float ids[];
} primitives;
layout(binding = 6, set = 0) buffer distanceProperties
{
float values[];
} distances;
struct RayPayload {
uint outputId;
uint hitCounter;
};
layout(location = 0) rayPayloadInNV RayPayload rayPayload;
hitAttributeNV vec3 attribs;
void main()
{
uint outputIdCurrentTriangle = rayPayload.outputId + rayPayload.hitCounter++;
primitives.ids[outputIdCurrentTriangle] = gl_PrimitiveID + 1;
distances.values[outputIdCurrentTriangle] = gl_HitTNV;
ignoreIntersectionNV();
}
并且光线正常产生:
traceNV(topLevelAS, rayFlags, cullMask, 0, 0, 0, origin.xyz, tmin, direction.xyz, tmax, 0);
但结果看起来像: [像素的距离][1] [1]: https://i.stack.imgur.com/FCDhl.png
数据形式: 0.83021832 0.83021832 0.84927511 0.84927511 0.94443458 0.94443458 0.94811541 0.94811541 1.0063932 1.0063932 0.97728723 0.97728723 0.98426312 0.98426312
而且里面可能还有更多的错误。 所以我的问题又来了:发生这种情况正常吗?
感谢您的每一次帮助!
这是完全正常的预期行为。
你的 any-hit-shader 被设计为在 GPU 遍历加速结构时被调用(它以任意顺序发生,无论什么最适合数据布局)。然后,您(通常)只应该调用 ignoreIntersectionNV()
或 reportIntersectionNV()
之一,具体取决于它是否是 可能 命中。您还不应该将其计为有效命中。
在调用最近的命中着色器之前,您对顺序一无所知。途中遇到的可以记录any-hits,后面需要把范围外的丢弃,剩下的按要求排序。
您已经可以在 any-hit-shader 中做一些有意义的事情的唯一例外是针对无限(天空盒、无限距离光源)的可见性测试。在这种情况下,任何命中都可能被接受,您可以立即致电terminateRayNV()
。
通过 Nvidias Vulkan 扩展直接使用光线追踪不适合解决与顺序相关的问题。
为此,您必须以迭代方式发射光线(在 any-hit 中过滤,甚至 VK_GEOMETRY_OPAQUE_BIT、re-launch 在 closest-hit 中过滤)或构建一个良好的旧D-buffer 基于您从 any-hit 次调用中记录的潜在命中。
如果您需要有序的命中,并且您的几何形状不是太复杂,那么您可能宁愿看看 signed-distance-fields,如果适合您的应用程序。它们在遍历过程中提供稳定的顺序。