#version 460
#extension GL_EXT_ray_tracing : require
struct Payload {
vec3 hit_value;
};
layout(binding = 0, set = 0) uniform accelerationStructureEXT tlas;
layout(binding = 1, set = 0, rgba32f) uniform image2D rt_out;
layout(push_constant) uniform PushConstants {
mat4 view;
mat4 projection;
} pc;
layout(location = 0) rayPayloadEXT Payload payload;
void main() {
// Compute normalized pixel coordinates between 0 and 1
const vec2 pixel_center = vec2(gl_LaunchIDEXT.xy);
const vec2 in_uv = pixel_center / vec2(gl_LaunchSizeEXT.xy);
vec2 normalized_uv = in_uv * 2.0 - 1.0;
// Apply inverse of view and projection to find camera direction
// This gives us the origin and direction of the ray
vec4 origin = inverse(pc.view) * vec4(0, 0, 0, 1);
vec4 target = inverse(pc.projection) * vec4(normalized_uv.x, normalized_uv.y, 1, 1);
vec4 direction = inverse(pc.view) * vec4(normalize(target.xyz), 0);
uint ray_flags = gl_RayFlagsNoneEXT;
// Set min and max distance for intersections along the ray. Useful for optimisation (cfr near/far planes).
const float min_dist = 0.001;
const float max_dist = 10000.0;
payload.hit_value = vec3(0.0);
// Do the actual ray tracing
traceRayEXT(
tlas, // Top-level acceleration structure
ray_flags, // Ray flags
0xFF, // Cull mask
0, // sbtRecordOffset
0, // sbtRecordStride
0, // Index of the miss shader to use
origin.xyz, // Ray origin
min_dist, // Minimum ray range
direction.xyz, // Ray direction
max_dist, // Maximum ray range
0 // Location of the ray payload
);
imageStore(rt_out, ivec2(gl_LaunchIDEXT.xy), vec4(payload.hit_value, 1.0));
}