|
7 | 7 |
|
8 | 8 | #include "VulkanApp.h" |
9 | 9 |
|
| 10 | +const char* codeSlang = R"( |
| 11 | +struct Camera { |
| 12 | + float4x4 viewInverse; |
| 13 | + float4x4 projInverse; |
| 14 | +}; |
| 15 | +
|
| 16 | +struct PushConstants { |
| 17 | + Camera* cam; |
| 18 | + uint outTexture; |
| 19 | + uint tlas; |
| 20 | + float time; |
| 21 | +}; |
| 22 | +
|
| 23 | +[[vk::push_constant]] PushConstants pc; |
| 24 | +
|
| 25 | +[[vk::binding(2, 0)]] RWTexture2D<float4> kTextures2DInOut[]; |
| 26 | +// cannot handle unbounded arrays https://github.com/shader-slang/slang/issues/8902 |
| 27 | +[[vk::binding(4, 0)]] RaytracingAccelerationStructure kTLAS[]; |
| 28 | +
|
| 29 | +struct RayPayload { |
| 30 | + float3 color; |
| 31 | +}; |
| 32 | +
|
| 33 | +[shader("raygeneration")] |
| 34 | +void rayGenMain() { |
| 35 | + uint3 launchID = DispatchRaysIndex(); |
| 36 | + uint3 launchSize = DispatchRaysDimensions(); |
| 37 | +
|
| 38 | + float2 pixelCenter = float2(launchID.xy) + float2(0.5, 0.5); |
| 39 | + float2 d = 2.0 * (pixelCenter / float2(launchSize.xy)) - 1.0; |
| 40 | +
|
| 41 | + float4 origin = mul(float4(0, 0, 0, 1), pc.cam->viewInverse); |
| 42 | + float4 target = mul(float4(d, 1, 1), pc.cam->projInverse); |
| 43 | + float4 direction = mul(float4(normalize(target.xyz), 0), pc.cam->viewInverse); |
| 44 | +
|
| 45 | + RayDesc ray; |
| 46 | + ray.Origin = origin.xyz; |
| 47 | + ray.Direction = direction.xyz; |
| 48 | + ray.TMin = 0.1; |
| 49 | + ray.TMax = 500.0; |
| 50 | +
|
| 51 | + RayPayload payload = { float3(0.0, 0.0, 0.0) }; |
| 52 | +
|
| 53 | + TraceRay( |
| 54 | + kTLAS[NonUniformResourceIndex(pc.tlas)], |
| 55 | + RAY_FLAG_FORCE_OPAQUE, |
| 56 | + 0xff, |
| 57 | + 0, |
| 58 | + 0, |
| 59 | + 0, |
| 60 | + ray, |
| 61 | + payload |
| 62 | + ); |
| 63 | +
|
| 64 | + kTextures2DInOut[NonUniformResourceIndex(pc.outTexture)][launchID.xy] = float4(payload.color, 1.0); |
| 65 | +} |
| 66 | +
|
| 67 | +float2 rotate(float2 v, float angle) { |
| 68 | + float2x2 r = float2x2(cos(angle), -sin(angle), |
| 69 | + sin(angle), cos(angle)); |
| 70 | + return mul(v-0.5*DispatchRaysDimensions().xy, r); |
| 71 | +} |
| 72 | +
|
| 73 | +// helper function for GLSL-style mod() that works with negative numbers |
| 74 | +float mod(float x, float y) { |
| 75 | + return x - y * floor(x / y); |
| 76 | +} |
| 77 | +
|
| 78 | +[shader("miss")] |
| 79 | +void missMain(inout RayPayload payload) { |
| 80 | + float2 uv = rotate(DispatchRaysIndex().xy, 0.2 * pc.time); |
| 81 | + float2 pos = floor(uv / 64.0); |
| 82 | + payload.color = float3(mod(pos.x + mod(pos.y, 2.0), 2.0)); |
| 83 | +} |
| 84 | +
|
| 85 | +[shader("closesthit")] |
| 86 | +void closestHitMain(inout RayPayload payload, in BuiltInTriangleIntersectionAttributes attribs) { |
| 87 | + float3 baryCoords = float3( |
| 88 | + 1.0f - attribs.barycentrics.x - attribs.barycentrics.y, |
| 89 | + attribs.barycentrics.x, |
| 90 | + attribs.barycentrics.y |
| 91 | + ); |
| 92 | + payload.color = baryCoords; |
| 93 | +} |
| 94 | +)"; |
| 95 | + |
10 | 96 | const char* codeRayGen = R"( |
11 | 97 | #version 460 |
12 | 98 | #extension GL_EXT_ray_tracing : require |
@@ -240,9 +326,15 @@ VULKAN_APP_MAIN { |
240 | 326 | }, |
241 | 327 | "storageImage"); |
242 | 328 |
|
| 329 | +#if defined(LVK_DEMO_WITH_SLANG) |
| 330 | + res.raygen_ = ctx_->createShaderModule({codeSlang, lvk::Stage_RayGen, "Shader Module: main (raygen)"}); |
| 331 | + res.miss_ = ctx_->createShaderModule({codeSlang, lvk::Stage_Miss, "Shader Module: main (miss)"}); |
| 332 | + res.hit_ = ctx_->createShaderModule({codeSlang, lvk::Stage_ClosestHit, "Shader Module: main (closesthit)"}); |
| 333 | +#else |
243 | 334 | res.raygen_ = ctx_->createShaderModule({codeRayGen, lvk::Stage_RayGen, "Shader Module: main (raygen)"}); |
244 | 335 | res.miss_ = ctx_->createShaderModule({codeMiss, lvk::Stage_Miss, "Shader Module: main (miss)"}); |
245 | 336 | res.hit_ = ctx_->createShaderModule({codeClosestHit, lvk::Stage_ClosestHit, "Shader Module: main (closesthit)"}); |
| 337 | +#endif // defined(LVK_DEMO_WITH_SLANG) |
246 | 338 |
|
247 | 339 | res.pipeline = ctx_->createRayTracingPipeline(lvk::RayTracingPipelineDesc{ |
248 | 340 | .smRayGen = {lvk::ShaderModuleHandle(res.raygen_)}, |
|
0 commit comments