Vulkan 光线追踪 - 并非来自任何命中着色器的每个原始 ID
Vulkan Ray Tracing - Not every primitive Id from any hit shader
编辑:我添加了我的项目的 .cpp 文件,它的退出类似于 Sascha Willems 的 repo 中的示例。
我是 Vulkan 的新手,我尝试写一个 Ray/Triangle 交集。可悲的是我没有找到一个例子。也许你知道一个?
我需要这些交点来计算光线的衰减。
所以我做了一个像这样的射线生成着色器:
#version 460
#extension GL_NV_ray_tracing : require
#define debug 0
layout(binding = 0, set = 0) uniform accelerationStructureNV topLevelAS;
layout(binding = 1, set = 0, rgba8) uniform image2D image;
layout(binding = 2, set = 0) uniform CameraProperties
{
mat4 viewInverse;
mat4 projInverse;
} cam;
layout(binding = 3, set = 0) buffer detectorProperties
{
double detectorValue[];
} detectors;
//layout(binding = 4, set = 0) buffer outputProperties
//{
// double outputValues[];
//} outputData;
layout(binding = 5, set = 0) buffer debugProperties
{
double debugValues[];
} debugData;
struct RayPayload {
uint outputId;
uint hitCounter;
};
layout(location = 0) rayPayloadNV RayPayload rayPayload;
void main()
{
rayPayload.outputId = gl_LaunchIDNV.x * 18+ gl_LaunchIDNV.y * gl_LaunchSizeNV.x * 18;
rayPayload.hitCounter = 0;
vec3 origin = vec3(cam.viewInverse[0].x, cam.viewInverse[1].y, cam.viewInverse[2].z);
uint rayId = uint(gl_LaunchIDNV.x + gl_LaunchSizeNV.x * gl_LaunchIDNV.y);
uint targetXId = rayId;
uint targetYId = rayId + gl_LaunchSizeNV.x * gl_LaunchSizeNV.y;
uint targetZId = rayId + gl_LaunchSizeNV.x * gl_LaunchSizeNV.y *2;
vec3 target = vec3(detectors.detectorValue[targetXId],detectors.detectorValue[targetYId], detectors.detectorValue[targetZId]) ;
vec3 direction = target.xyz-origin.xyz ;
#ifdef debug
uint debugId = rayPayload.outputId;
debugData.debugValues[debugId + 0 ] = gl_LaunchSizeNV.x;
debugData.debugValues[debugId + 1] = gl_LaunchSizeNV.y;
debugData.debugValues[debugId+ 2 ] = gl_LaunchIDNV.x;
debugData.debugValues[debugId+ 3 ] = gl_LaunchIDNV.y;
debugData.debugValues[debugId + 4] = targetXId;
debugData.debugValues[debugId + 5] = targetYId;
debugData.debugValues[debugId + 6] = targetZId;
debugData.debugValues[debugId + 7] = target.x;
debugData.debugValues[debugId + 8] = target.y;
debugData.debugValues[debugId + 9] = target.z;
debugData.debugValues[debugId + 10] = origin.x;
debugData.debugValues[debugId + 11] = origin.y;
debugData.debugValues[debugId + 12] = origin.z;
debugData.debugValues[debugId + 13] = direction.x;
debugData.debugValues[debugId + 14] = direction.y;
debugData.debugValues[debugId + 15] = direction.z;
debugData.debugValues[debugId + 16] = rayId;
debugData.debugValues[debugId + 17] = rayPayload.outputId;
#endif
uint rayFlags = gl_RayFlagsNoneNV;
uint cullMask = 0xff;
float tmin = 0.00001;
float tmax = 10000.0;
traceNV(topLevelAS, rayFlags, cullMask, 0, 0, 0, origin.xyz, tmin, direction.xyz, tmax, 0);
// uint outputId = gl_LaunchIDNV.x * 18+ gl_LaunchIDNV.y * gl_LaunchSizeNV.x *18;
// outputData.outputValues[outputId + hitCounter] = double(hitValue[hitCounter]);
imageStore(image, ivec2(gl_LaunchIDNV.xy), vec4(rayPayload.hitCounter,0,0, 0.0));
}
对于任意命中着色器,我只想像这样返回原始 Id:
#version 460
#extension GL_NV_ray_tracing : require
#extension GL_EXT_nonuniform_qualifier : enable
layout(binding = 4, set = 0) buffer outputProperties
{
float outputValues[];
} outputData;
struct RayPayload {
uint outputId;
uint hitCounter;
};
layout(location = 0) rayPayloadInNV RayPayload rayPayload;
hitAttributeNV vec3 attribs;
void main()
{
// uint outputIdCurrentTriangle = rayPayload.outputId + rayPayload.hitCounter;
uint outputIdCurrentTriangle = rayPayload.outputId + rayPayload.hitCounter++;
outputData.outputValues[outputIdCurrentTriangle] = gl_PrimitiveID;
// rayPayload.hitCounter ++;
}
您可以在此处查看 .cpp 文件:
https://drive.google.com/file/d/1iTX3ATaP3pT7d4CEowo4IVnQxTOerxaD/view?usp=sharing
我的问题是,即使对象是不透明的(通过将 Rayflag 设置为 cullNoOpaques 进行测试),我也只是找到了所有表面三角形,最接近源。
有没有人有同样的问题,或者有一个例子也给出了任何回击的 primitivesId?
我刚找到一个任意命中着色器的示例。 any-hit 着色器这么少用吗?
感谢您的帮助!
如果您想让任意命中着色器为场景中的所有三角形注册交点,您应该在任意命中着色器中调用 ignoreIntersectionNV
(参见 GLSL_NV_ray_tracing specs)。
这样,您的任意命中着色器将在不修改 gl_RayTmaxNV
和 gl_HitKindNV
的情况下继续运行,触发所有光线相交。
使用像这样的简单任意命中着色器:
#version 460
#extension GL_NV_ray_tracing : require
#extension GL_GOOGLE_include_directive : enable
#include "raypayload.glsl"
layout(binding = 1, set = 0, rgba8) uniform image2D image;
layout(location = 0) rayPayloadInNV RayPayload rayPayload;
void main()
{
rayPayload.hitcount++;
ignoreIntersectionNV();
}
每个交叉点 hitCount
将增加 1,通过点击计数用颜色编码将其可视化将产生如下内容:
编辑:我添加了我的项目的 .cpp 文件,它的退出类似于 Sascha Willems 的 repo 中的示例。
我是 Vulkan 的新手,我尝试写一个 Ray/Triangle 交集。可悲的是我没有找到一个例子。也许你知道一个? 我需要这些交点来计算光线的衰减。 所以我做了一个像这样的射线生成着色器:
#version 460
#extension GL_NV_ray_tracing : require
#define debug 0
layout(binding = 0, set = 0) uniform accelerationStructureNV topLevelAS;
layout(binding = 1, set = 0, rgba8) uniform image2D image;
layout(binding = 2, set = 0) uniform CameraProperties
{
mat4 viewInverse;
mat4 projInverse;
} cam;
layout(binding = 3, set = 0) buffer detectorProperties
{
double detectorValue[];
} detectors;
//layout(binding = 4, set = 0) buffer outputProperties
//{
// double outputValues[];
//} outputData;
layout(binding = 5, set = 0) buffer debugProperties
{
double debugValues[];
} debugData;
struct RayPayload {
uint outputId;
uint hitCounter;
};
layout(location = 0) rayPayloadNV RayPayload rayPayload;
void main()
{
rayPayload.outputId = gl_LaunchIDNV.x * 18+ gl_LaunchIDNV.y * gl_LaunchSizeNV.x * 18;
rayPayload.hitCounter = 0;
vec3 origin = vec3(cam.viewInverse[0].x, cam.viewInverse[1].y, cam.viewInverse[2].z);
uint rayId = uint(gl_LaunchIDNV.x + gl_LaunchSizeNV.x * gl_LaunchIDNV.y);
uint targetXId = rayId;
uint targetYId = rayId + gl_LaunchSizeNV.x * gl_LaunchSizeNV.y;
uint targetZId = rayId + gl_LaunchSizeNV.x * gl_LaunchSizeNV.y *2;
vec3 target = vec3(detectors.detectorValue[targetXId],detectors.detectorValue[targetYId], detectors.detectorValue[targetZId]) ;
vec3 direction = target.xyz-origin.xyz ;
#ifdef debug
uint debugId = rayPayload.outputId;
debugData.debugValues[debugId + 0 ] = gl_LaunchSizeNV.x;
debugData.debugValues[debugId + 1] = gl_LaunchSizeNV.y;
debugData.debugValues[debugId+ 2 ] = gl_LaunchIDNV.x;
debugData.debugValues[debugId+ 3 ] = gl_LaunchIDNV.y;
debugData.debugValues[debugId + 4] = targetXId;
debugData.debugValues[debugId + 5] = targetYId;
debugData.debugValues[debugId + 6] = targetZId;
debugData.debugValues[debugId + 7] = target.x;
debugData.debugValues[debugId + 8] = target.y;
debugData.debugValues[debugId + 9] = target.z;
debugData.debugValues[debugId + 10] = origin.x;
debugData.debugValues[debugId + 11] = origin.y;
debugData.debugValues[debugId + 12] = origin.z;
debugData.debugValues[debugId + 13] = direction.x;
debugData.debugValues[debugId + 14] = direction.y;
debugData.debugValues[debugId + 15] = direction.z;
debugData.debugValues[debugId + 16] = rayId;
debugData.debugValues[debugId + 17] = rayPayload.outputId;
#endif
uint rayFlags = gl_RayFlagsNoneNV;
uint cullMask = 0xff;
float tmin = 0.00001;
float tmax = 10000.0;
traceNV(topLevelAS, rayFlags, cullMask, 0, 0, 0, origin.xyz, tmin, direction.xyz, tmax, 0);
// uint outputId = gl_LaunchIDNV.x * 18+ gl_LaunchIDNV.y * gl_LaunchSizeNV.x *18;
// outputData.outputValues[outputId + hitCounter] = double(hitValue[hitCounter]);
imageStore(image, ivec2(gl_LaunchIDNV.xy), vec4(rayPayload.hitCounter,0,0, 0.0));
}
对于任意命中着色器,我只想像这样返回原始 Id:
#version 460
#extension GL_NV_ray_tracing : require
#extension GL_EXT_nonuniform_qualifier : enable
layout(binding = 4, set = 0) buffer outputProperties
{
float outputValues[];
} outputData;
struct RayPayload {
uint outputId;
uint hitCounter;
};
layout(location = 0) rayPayloadInNV RayPayload rayPayload;
hitAttributeNV vec3 attribs;
void main()
{
// uint outputIdCurrentTriangle = rayPayload.outputId + rayPayload.hitCounter;
uint outputIdCurrentTriangle = rayPayload.outputId + rayPayload.hitCounter++;
outputData.outputValues[outputIdCurrentTriangle] = gl_PrimitiveID;
// rayPayload.hitCounter ++;
}
您可以在此处查看 .cpp 文件: https://drive.google.com/file/d/1iTX3ATaP3pT7d4CEowo4IVnQxTOerxaD/view?usp=sharing
我的问题是,即使对象是不透明的(通过将 Rayflag 设置为 cullNoOpaques 进行测试),我也只是找到了所有表面三角形,最接近源。
有没有人有同样的问题,或者有一个例子也给出了任何回击的 primitivesId?
我刚找到一个任意命中着色器的示例。 any-hit 着色器这么少用吗? 感谢您的帮助!
如果您想让任意命中着色器为场景中的所有三角形注册交点,您应该在任意命中着色器中调用 ignoreIntersectionNV
(参见 GLSL_NV_ray_tracing specs)。
这样,您的任意命中着色器将在不修改 gl_RayTmaxNV
和 gl_HitKindNV
的情况下继续运行,触发所有光线相交。
使用像这样的简单任意命中着色器:
#version 460
#extension GL_NV_ray_tracing : require
#extension GL_GOOGLE_include_directive : enable
#include "raypayload.glsl"
layout(binding = 1, set = 0, rgba8) uniform image2D image;
layout(location = 0) rayPayloadInNV RayPayload rayPayload;
void main()
{
rayPayload.hitcount++;
ignoreIntersectionNV();
}
每个交叉点 hitCount
将增加 1,通过点击计数用颜色编码将其可视化将产生如下内容: