Files
rogue/assets/shaders/raytrace/compute.slang
2026-04-23 19:33:39 -03:00

56 lines
1.5 KiB
Plaintext

#include "intersection.slang"
#include "sky.slang"
#include "../camera.slang"
[[vk::binding(0, 0)]] ConstantBuffer<rt::camera_data> camera;
[[vk::binding(1, 0)]] ConstantBuffer<rt::raytrace_config> config;
[[vk::binding(2, 0)]] ConstantBuffer<rt::sky_config> sky_config;
[[vk::binding(0, 1)]] RWTexture2D<float4> output;
struct pixel_data {
uint2 coord;
float2 uv;
float3 r_o;
float3 r_d;
};
Optional<pixel_data> current_pixel_data(
in const uint2 thread_id) {
if (any(thread_id >= camera.resolution.xy)) {
return none;
}
float2 uv = (float2(thread_id) + 0.5f) / float2(camera.resolution.xy);
uv = uv * 2.0 - 1.0;
uv.y = -uv.y;
let ndc = float4(uv.x, uv.y, 1.0, 1.0);
float4 view = mul(camera.inverse_projection, ndc);
view /= view.w;
let view_dir = normalize(view.xyz);
let r_d = normalize(mul((float3x3)camera.inverse_view, view_dir));
let r_o = float3(camera.inverse_view[0][3],
camera.inverse_view[1][3],
camera.inverse_view[2][3]);
return pixel_data(thread_id, uv, r_o, r_d);
}
[shader("compute")]
[numthreads(16, 16, 1)]
void main(uint3 d_threadid : SV_DispatchThreadID) {
if (let data = current_pixel_data(d_threadid.xy)) {
float3 color_out = float3(1.0f);
if (let isect = rt::intersect_sphere(data.r_o, data.r_d, float3(0.0f), 1.0)) {
let reflected = reflect(data.r_d, isect.n);
color_out = rt::evaluate_sky(-reflected, sky_config);
color_out = isect.n * 0.5f + 0.5f;
} else {
color_out = rt::evaluate_sky(-data.r_d, sky_config);
}
output[data.coord] = float4(color_out, 1.0f);
}
}