繁体   English   中英

Vulkan Ray Tracing - 并非来自任何命中着色器的每个原始 Id

[英]Vulkan Ray Tracing - Not every primitive Id from any hit shader

编辑:我添加了我的项目的 .cpp 文件,它与 Sascha Willems 的 repo 中的示例类似。

我是 Vulkan 的新手,我尝试编写光线/三角形交叉点。 遗憾的是我没有找到一个例子。 也许你知道一个? 我需要这些交叉点来计算光线的衰减。 所以我做了一个这样的raygen着色器:

#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));
}

使用 any-hit 着色器,我只想像这样返回原始 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

我的问题是,即使对象是 noOpaque(通过将 Rayflag 设置为 cullNoOpaques 进行测试),我也只是找到所有表面三角形,离源最近。

有没有人有同样的问题或有一个例子,它也给出了任何回击的primitivesId?

我刚刚找到了一个适用于任何命中着色器的示例。 使用较少的 any-hit 着色器吗? 感谢您的帮助!

如果您想让任何命中着色器为场景中的所有三角形注册交点, ignoreIntersectionNV在任何命中着色器中调用ignoreIntersectionNV (请参阅GLSL_NV_ray_tracing 规范)。

有了这个,您的任何命中着色器将继续进行,而无需修改gl_RayTmaxNVgl_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,通过 hitcount 用颜色编码将其可视化将产生如下结果:

彩色交叉点

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM