#version 460
#extension GL_EXT_ray_tracing : enable
#extension GL_EXT_shader_image_load_formatted : enable
#extension GL_EXT_shader_explicit_arithmetic_types_int16 : enable
#extension GL_EXT_descriptor_heap : enable
#extension GL_EXT_nonuniform_qualifier : enable

layout(constant_id = 0) const uint16_t bufferStart = 0us;
layout(descriptor_heap) uniform accelerationStructureEXT topLevelAS[];
layout(descriptor_heap) uniform writeonly image2D image[];

layout(location = 0) rayPayloadEXT vec3 hitValue;

void main() {
    // Pixel coordinates
    uvec2 pixel = gl_LaunchIDEXT.xy;
    uvec2 resolution = gl_LaunchSizeEXT.xy;

    // Normalized coordinates in range [-1, 1]
    vec2 uv = (vec2(pixel) + 0.5) / vec2(resolution);
    vec2 ndc = uv * 2.0 - 1.0;

    // Camera parameters
    vec3 origin = vec3(0.0, 0.0, -300.0);

    float aspect = float(resolution.x) / float(resolution.y);
    float fov = radians(60.0);
    float tanHalfFov = tan(fov * 0.5);

    // Simple pinhole camera facing +Z
    vec3 direction = normalize(vec3(
        ndc.x * aspect * tanHalfFov,
        -ndc.y * tanHalfFov,
        1.0
    ));

    traceRayEXT(
        topLevelAS[bufferStart],
        gl_RayFlagsNoneEXT,
        0xff,
        0, 0, 0,
        origin,
        0.001,
        direction,
        10000.0,
        0
    );

    imageStore(image[0], ivec2(pixel), vec4(hitValue, 1));
}
