From 5db9781d529467c4474bbc957ab5f1ee06126cf4 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Sat, 6 Mar 2021 16:21:09 +0100 Subject: [PATCH] Added HLSL shaders for ray tracing callable sample Minor cleanup --- README.md | 2 +- .../glsl/raytracingcallable/callable3.rcall | 2 - .../glsl/raytracingcallable/shadow.rmiss | 9 -- .../glsl/raytracingcallable/shadow.rmiss.spv | Bin 320 -> 0 bytes .../hlsl/raytracingcallable/callable1.rcall | 14 +++ .../hlsl/raytracingcallable/callable2.rcall | 12 +++ .../hlsl/raytracingcallable/callable3.rcall | 14 +++ .../hlsl/raytracingcallable/closesthit.rchit | 26 +++++ .../raytracingcallable/closesthit.rchit.spv | Bin 0 -> 624 bytes .../hlsl/raytracingcallable/miss.rmiss | 12 +++ .../hlsl/raytracingcallable/miss.rmiss.spv | Bin 0 -> 380 bytes .../hlsl/raytracingcallable/raygen.rgen | 39 +++++++ .../hlsl/raytracingcallable/raygen.rgen.spv | Bin 0 -> 2356 bytes .../raytracingcallable/raytracingcallable.cpp | 101 +++++++++--------- 14 files changed, 168 insertions(+), 63 deletions(-) delete mode 100644 data/shaders/glsl/raytracingcallable/shadow.rmiss delete mode 100644 data/shaders/glsl/raytracingcallable/shadow.rmiss.spv create mode 100644 data/shaders/hlsl/raytracingcallable/callable1.rcall create mode 100644 data/shaders/hlsl/raytracingcallable/callable2.rcall create mode 100644 data/shaders/hlsl/raytracingcallable/callable3.rcall create mode 100644 data/shaders/hlsl/raytracingcallable/closesthit.rchit create mode 100644 data/shaders/hlsl/raytracingcallable/closesthit.rchit.spv create mode 100644 data/shaders/hlsl/raytracingcallable/miss.rmiss create mode 100644 data/shaders/hlsl/raytracingcallable/miss.rmiss.spv create mode 100644 data/shaders/hlsl/raytracingcallable/raygen.rgen create mode 100644 data/shaders/hlsl/raytracingcallable/raygen.rgen.spv diff --git a/README.md b/README.md index 9b106a24..61451a1f 100644 --- a/README.md +++ b/README.md @@ -308,7 +308,7 @@ Renders a complex scene with reflective surfaces using the new ray tracing exten #### [Callable ray tracing shaders](examples/raytracingcallable) -Callable shaders can be dynamically invoked from within other ray tracing shaders to execute different shaders based on your own conditions. The example ray traces multiple geometries, with each calling a different callable shader from the closest hit shader. +Callable shaders can be dynamically invoked from within other ray tracing shaders to execute different shaders based on dynamic conditions. The example ray traces multiple geometries, with each calling a different callable shader from the closest hit shader. #### [Ray query](examples/rayquery) diff --git a/data/shaders/glsl/raytracingcallable/callable3.rcall b/data/shaders/glsl/raytracingcallable/callable3.rcall index 6c52133b..1cc3a701 100644 --- a/data/shaders/glsl/raytracingcallable/callable3.rcall +++ b/data/shaders/glsl/raytracingcallable/callable3.rcall @@ -8,6 +8,4 @@ void main() // Generate a line pattern vec2 pos = vec2(gl_LaunchIDEXT / 8); outColor = vec3(mod(pos.y, 2.0)); - -// outColor = vec3(0.0, 0.0, 1.0); } \ No newline at end of file diff --git a/data/shaders/glsl/raytracingcallable/shadow.rmiss b/data/shaders/glsl/raytracingcallable/shadow.rmiss deleted file mode 100644 index 36d9b7ba..00000000 --- a/data/shaders/glsl/raytracingcallable/shadow.rmiss +++ /dev/null @@ -1,9 +0,0 @@ -#version 460 -#extension GL_EXT_ray_tracing : require - -layout(location = 2) rayPayloadInEXT bool shadowed; - -void main() -{ - shadowed = false; -} \ No newline at end of file diff --git a/data/shaders/glsl/raytracingcallable/shadow.rmiss.spv b/data/shaders/glsl/raytracingcallable/shadow.rmiss.spv deleted file mode 100644 index 65b01ba9610f1ccd0371be438bf842bb68f9e3d6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 320 zcmY*VO$z~06ut9hd=!bb$j)N2KuXzZlvxPL?)5Ul0yQ%wE5FXpZ}2;8lyim!Z#r|| zJ@=e@-+PwXbj3C#FInKT%3{j3EXXr5pDxv8JX4Xrs3g+s{c$S=@CKxQFb}*q3B69Y zO=nT8v;k`+Xl_*z8~cOaA6du(7Csa44v`IwAE?o4@z-7)RDOL97<%KK4o~Mzh^_cg zkgEagSHYjLkxuwPVfJ@=QdGz)U-G-vyKh*%j;QauRXK2HS9K>W>=RtS>={lUAb94e^h7W`QptPFnYmPP6A#oq9-QudVBQ&%h=@MBHG@#6hhU1k$k z6z8sXa{U}RUb(0zWl>i6v7a=Xt@W~VUE76Xw2c_hBSz zRNIs#UU95$BbTVwmi-h5H;&YS#{U}pAF7d~cUv|P*wxpyJFB!=r{_*iYz)1`T zd*LC51MTnxs<5jo97_Qlw6zL3m?qvg?(9N^X#W=mbb`;{ZZWQ4C2)7;%(~2$!Z4YXP{gqnEk7n z^wK3OH9W#+hvZ+1(1Og-ce};fO>jil31;(TJ93NfseB=)@@_I6+|8`g3plS4pD1a~ z*Sgga`grKI-{|JhV)W7m_o;p)nktHRvbuiEq(ag_q>Xb*g8w^w*Wq8^txK c#TE$7ZZcV%{)Lu&f6OV8+mP~!{fB4~XI image : register(u1); + +struct CameraProperties +{ + float4x4 viewInverse; + float4x4 projInverse; +}; +cbuffer cam : register(b2) { CameraProperties cam; }; + +struct Payload +{ +[[vk::location(0)]] float3 hitValue; +}; + +[shader("raygeneration")] +void main() +{ + uint3 LaunchID = DispatchRaysIndex(); + uint3 LaunchSize = DispatchRaysDimensions(); + + const float2 pixelCenter = float2(LaunchID.xy) + float2(0.5, 0.5); + const float2 inUV = pixelCenter/float2(LaunchSize.xy); + float2 d = inUV * 2.0 - 1.0; + float4 target = mul(cam.projInverse, float4(d.x, d.y, 1, 1)); + + RayDesc rayDesc; + rayDesc.Origin = mul(cam.viewInverse, float4(0,0,0,1)).xyz; + rayDesc.Direction = mul(cam.viewInverse, float4(normalize(target.xyz), 0)).xyz; + rayDesc.TMin = 0.001; + rayDesc.TMax = 10000.0; + + Payload payload; + TraceRay(rs, RAY_FLAG_FORCE_OPAQUE, 0xff, 0, 0, 0, rayDesc, payload); + + image[int2(LaunchID.xy)] = float4(payload.hitValue, 0.0); +} diff --git a/data/shaders/hlsl/raytracingcallable/raygen.rgen.spv b/data/shaders/hlsl/raytracingcallable/raygen.rgen.spv new file mode 100644 index 0000000000000000000000000000000000000000..611d1de15f639dd9562c2da18ea20d55961c052e GIT binary patch literal 2356 zcmZ9MTW?fV6vsDhrwEopxr11ypomaLMQ(!7B9|5@bf8$CNOLkh!7*)TayrE{ApygS zPsXprlYRyhzlSeIf4|ec%du;+X0P>Mm%Y~7d!PQkliNdWTL@t|JmX&)34P)9NC-Q_ zV3=#pFFcrjvQT8}3%w$1wO3w*55bL?nwgtvto9Zg7cPEj+;Hf3DQ&y)dbdB2DTL*$ zy&|r40ItD<@OJnExSyZc8=Pw(JCL(hD__cstk>?W%=L=3R&TAyAI)ReJA`6Y-$7~& zp|{@68|N1r?d9x6j$UII_j#|^s3!WgvSmaf2TDv?s75tI$hWd(c5N1&ZeH}-IlJgP zSlX0dw)3Cvt-Q>O)qE3o7Tu!rW5TV`em3$Bgk8wZY<;PdEtWCr(hu$4e73Y^$z{#X zq8t6}p*p)MbZ2HCzcW{L=coQh)Qum7CGF1XM5(>k$11urs@m1HmuE}7Jyh-L+O2CE ztMighZY=-9tZffGO`hau{uJjP#!YU)w#Mm~;_OvQ`%TfInDrb)9%ik>XNgeW4MP)$ z(5*#G-*IYJ=Zcp;`lXn?$k1fc_m%3Ki4?=AgP44Pya!n8uyq=vesGI^2wh4!4{xZ! zx{e@QmpzViqUuLseG-v;d6#n+4!@p=66qH#-nU) z+Rw3ij@qxGkFmO!q;9YFC8=A#ZzK6zuW!|wwX1utlWvW^RqNbFW@~T2m&js`=8>%V zZ?rF1uan3A{m_~_>0cq6dzOFuIuGk3OYYev*8Bc7to`SB|1U($caY*QBAZi|s_~c5 zwf_?1FC&{n{MU$GK^FHNy^Yv6$l|mcZc@GTz6v`t--hqSew_a`SleT)p7FP^@lwLB zBa2yEGrpM{$ogta@AEfucn2q7?dDGVPa>!Nts(7y6Iok|{SMjpC_c-nc~-YzaappC zJ~-KLBfF<8CHoM)8-FKauKK3F?nWESCN>o@b0oj%h`DF#{~ogO`fK;wk$Sj~ti9U9 z19Wj&N;Nh)2j9*N?47*9{q(M?JEI+}4`JWK^O2!aK8{?6{njLQMt-Z@$8VH5j5qhA zsN0Y8n2i|AW{=H?SFy(ttIpy{#HzEH12bNK?atyAd;6}R!oC4@-^=$Av$mbc^RREb QMQzI3%_sfCl&--40jqM6SO5S3 literal 0 HcmV?d00001 diff --git a/examples/raytracingcallable/raytracingcallable.cpp b/examples/raytracingcallable/raytracingcallable.cpp index a949c0f6..b2e56af5 100644 --- a/examples/raytracingcallable/raytracingcallable.cpp +++ b/examples/raytracingcallable/raytracingcallable.cpp @@ -1,9 +1,11 @@ /* * Vulkan Example - Hardware accelerated ray tracing callable shaders example * -* Renders a complex scene using multiple hit and miss shaders for implementing shadows +* Dynamically calls different shaders based on the geoemtry id in the closest hit shader * -* Copyright (C) by Sascha Willems - www.saschawillems.de +* Relevant code parts are marked with [POI] +* +* Copyright (C) 2021 by Sascha Willems - www.saschawillems.de * * This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) */ @@ -56,20 +58,22 @@ public: ~VulkanExample() { - vkDestroyPipeline(device, pipeline, nullptr); - vkDestroyPipelineLayout(device, pipelineLayout, nullptr); - vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr); - deleteStorageImage(); - deleteAccelerationStructure(bottomLevelAS); - deleteAccelerationStructure(topLevelAS); - shaderBindingTables.raygen.destroy(); - shaderBindingTables.miss.destroy(); - shaderBindingTables.hit.destroy(); - shaderBindingTables.callable.destroy(); - vertexBuffer.destroy(); - indexBuffer.destroy(); - transformBuffer.destroy(); - ubo.destroy(); + if (device) { + vkDestroyPipeline(device, pipeline, nullptr); + vkDestroyPipelineLayout(device, pipelineLayout, nullptr); + vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr); + deleteStorageImage(); + deleteAccelerationStructure(bottomLevelAS); + deleteAccelerationStructure(topLevelAS); + shaderBindingTables.raygen.destroy(); + shaderBindingTables.miss.destroy(); + shaderBindingTables.hit.destroy(); + shaderBindingTables.callable.destroy(); + vertexBuffer.destroy(); + indexBuffer.destroy(); + transformBuffer.destroy(); + ubo.destroy(); + } } /* @@ -183,6 +187,7 @@ public: accelerationBuildGeometryInfo.pGeometries = accelerationStructureGeometries.data(); accelerationBuildGeometryInfo.scratchData.deviceAddress = scratchBuffer.deviceAddress; + // [POI] The bottom level acceleration structure for this sample contains three separate triangle geometries, so we can use gl_GeometryIndexEXT in the closest hit shader to select different callable shaders std::vector accelerationStructureBuildRangeInfos{}; for (uint32_t i = 0; i < objectCount; i++) { VkAccelerationStructureBuildRangeInfoKHR accelerationStructureBuildRangeInfo{}; @@ -350,7 +355,7 @@ public: createShaderBindingTable(shaderBindingTables.raygen, 1); createShaderBindingTable(shaderBindingTables.miss, 1); createShaderBindingTable(shaderBindingTables.hit, 1); - // The callable shader binding table contains one shader handle per ray traced object + // [POI] The callable shader binding table contains one shader handle per ray traced object createShaderBindingTable(shaderBindingTables.callable, objectCount); // Copy handles @@ -437,50 +442,44 @@ public: Setup ray tracing shader groups */ std::vector shaderStages; + VkRayTracingShaderGroupCreateInfoKHR shaderGroup; // Ray generation shader group - { - shaderStages.push_back(loadShader(getShadersPath() + "raytracingcallable/raygen.rgen.spv", VK_SHADER_STAGE_RAYGEN_BIT_KHR)); - VkRayTracingShaderGroupCreateInfoKHR shaderGroup = vks::initializers::rayTracingShaderGroupCreateInfoKHR(); - shaderGroup.type = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR; - shaderGroup.generalShader = static_cast(shaderStages.size()) - 1; - shaderGroup.closestHitShader = VK_SHADER_UNUSED_KHR; - shaderGroup.anyHitShader = VK_SHADER_UNUSED_KHR; - shaderGroup.intersectionShader = VK_SHADER_UNUSED_KHR; - shaderGroups.push_back(shaderGroup); - } + shaderStages.push_back(loadShader(getShadersPath() + "raytracingcallable/raygen.rgen.spv", VK_SHADER_STAGE_RAYGEN_BIT_KHR)); + shaderGroup = vks::initializers::rayTracingShaderGroupCreateInfoKHR(); + shaderGroup.type = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR; + shaderGroup.generalShader = static_cast(shaderStages.size()) - 1; + shaderGroup.closestHitShader = VK_SHADER_UNUSED_KHR; + shaderGroup.anyHitShader = VK_SHADER_UNUSED_KHR; + shaderGroup.intersectionShader = VK_SHADER_UNUSED_KHR; + shaderGroups.push_back(shaderGroup); // Miss shader group - { - shaderStages.push_back(loadShader(getShadersPath() + "raytracingcallable/miss.rmiss.spv", VK_SHADER_STAGE_MISS_BIT_KHR)); - VkRayTracingShaderGroupCreateInfoKHR shaderGroup = vks::initializers::rayTracingShaderGroupCreateInfoKHR(); - shaderGroup.type = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR; - shaderGroup.generalShader = static_cast(shaderStages.size()) - 1; - shaderGroup.closestHitShader = VK_SHADER_UNUSED_KHR; - shaderGroup.anyHitShader = VK_SHADER_UNUSED_KHR; - shaderGroup.intersectionShader = VK_SHADER_UNUSED_KHR; - shaderGroups.push_back(shaderGroup); - } + shaderStages.push_back(loadShader(getShadersPath() + "raytracingcallable/miss.rmiss.spv", VK_SHADER_STAGE_MISS_BIT_KHR)); + shaderGroup = vks::initializers::rayTracingShaderGroupCreateInfoKHR(); + shaderGroup.type = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR; + shaderGroup.generalShader = static_cast(shaderStages.size()) - 1; + shaderGroup.closestHitShader = VK_SHADER_UNUSED_KHR; + shaderGroup.anyHitShader = VK_SHADER_UNUSED_KHR; + shaderGroup.intersectionShader = VK_SHADER_UNUSED_KHR; + shaderGroups.push_back(shaderGroup); // Closest hit shader group - { - shaderStages.push_back(loadShader(getShadersPath() + "raytracingcallable/closesthit.rchit.spv", VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR)); - VkRayTracingShaderGroupCreateInfoKHR shaderGroup = vks::initializers::rayTracingShaderGroupCreateInfoKHR(); - shaderGroup.type = VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_KHR; - shaderGroup.generalShader = VK_SHADER_UNUSED_KHR; - shaderGroup.closestHitShader = static_cast(shaderStages.size()) - 1; - shaderGroup.anyHitShader = VK_SHADER_UNUSED_KHR; - shaderGroup.intersectionShader = VK_SHADER_UNUSED_KHR; - shaderGroups.push_back(shaderGroup); - } + shaderStages.push_back(loadShader(getShadersPath() + "raytracingcallable/closesthit.rchit.spv", VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR)); + shaderGroup = vks::initializers::rayTracingShaderGroupCreateInfoKHR(); + shaderGroup.type = VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_KHR; + shaderGroup.generalShader = VK_SHADER_UNUSED_KHR; + shaderGroup.closestHitShader = static_cast(shaderStages.size()) - 1; + shaderGroup.anyHitShader = VK_SHADER_UNUSED_KHR; + shaderGroup.intersectionShader = VK_SHADER_UNUSED_KHR; + shaderGroups.push_back(shaderGroup); - // Callable shader group - // This sample's hit shader will call different callable shaders depending on the geometry index, so as we render three different geometries, we'll also use three callable shaders + // [POI] Callable shader group + // This sample's hit shader will call different callable shaders depending on the geometry index using executeCallableEXT, so as we render three geometries, we'll also use three callable shaders for (uint32_t i = 0; i < objectCount; i++) { shaderStages.push_back(loadShader(getShadersPath() + "raytracingcallable/callable" + std::to_string(i+1) + ".rcall.spv", VK_SHADER_STAGE_CALLABLE_BIT_KHR)); - VkRayTracingShaderGroupCreateInfoKHR shaderGroup{}; - shaderGroup.sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR; + shaderGroup = vks::initializers::rayTracingShaderGroupCreateInfoKHR(); shaderGroup.type = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR; shaderGroup.generalShader = static_cast(shaderStages.size()) - 1; shaderGroup.closestHitShader = VK_SHADER_UNUSED_KHR;