diff --git a/Editor/MaterialWindow.cpp b/Editor/MaterialWindow.cpp index ad87462b9..afca263f7 100644 --- a/Editor/MaterialWindow.cpp +++ b/Editor/MaterialWindow.cpp @@ -146,7 +146,7 @@ void MaterialWindow::Create(EditorComponent* editor) AddWidget(&blendModeComboBox); shadingRateComboBox.Create("Shading Rate: "); - shadingRateComboBox.SetTooltip("Select shading rate for this material. \nSelecting larger shading rate will decrease rendering quality of this material, \nbut increases performance.\nDX12 only and requires Tier1 hardware support for variable shading rate"); + shadingRateComboBox.SetTooltip("Select shading rate for this material. \nSelecting larger shading rate will decrease rendering quality of this material, \nbut increases performance.\nRequires hardware support for variable shading rate"); shadingRateComboBox.SetPos(XMFLOAT2(x, y += step)); shadingRateComboBox.SetSize(XMFLOAT2(wid, hei)); shadingRateComboBox.OnSelect([&](wiEventArgs args) { diff --git a/Editor/RendererWindow.cpp b/Editor/RendererWindow.cpp index 0915bc2a6..f85498b34 100644 --- a/Editor/RendererWindow.cpp +++ b/Editor/RendererWindow.cpp @@ -232,7 +232,7 @@ void RendererWindow::Create(EditorComponent* editor) shadowTypeComboBox.SetSize(XMFLOAT2(100, itemheight)); shadowTypeComboBox.SetPos(XMFLOAT2(x, y += step)); shadowTypeComboBox.AddItem("Shadowmaps"); - if (wiRenderer::GetDevice()->CheckCapability(wiGraphics::GRAPHICSDEVICE_CAPABILITY_RAYTRACING_INLINE)) + if (wiRenderer::GetDevice()->CheckCapability(wiGraphics::GRAPHICSDEVICE_CAPABILITY_RAYTRACING)) { shadowTypeComboBox.AddItem("Ray traced"); } @@ -380,7 +380,7 @@ void RendererWindow::Create(EditorComponent* editor) wiRenderer::SetRaytracedShadowsSampleCount((uint32_t)args.iValue); }); AddWidget(&raytracedShadowsSlider); - if (!wiRenderer::GetDevice()->CheckCapability(wiGraphics::GRAPHICSDEVICE_CAPABILITY_RAYTRACING_INLINE)) + if (!wiRenderer::GetDevice()->CheckCapability(wiGraphics::GRAPHICSDEVICE_CAPABILITY_RAYTRACING)) { raytracedShadowsSlider.SetEnabled(false); } diff --git a/WickedEngine/MainComponent.cpp b/WickedEngine/MainComponent.cpp index 7fe2dad06..75f1d62c6 100644 --- a/WickedEngine/MainComponent.cpp +++ b/WickedEngine/MainComponent.cpp @@ -104,11 +104,6 @@ void MainComponent::Initialize() #endif } - if (wiRenderer::GetDevice()->CheckCapability(GRAPHICSDEVICE_CAPABILITY_RAYTRACING_INLINE)) - { - wiRenderer::SetShaderPath(wiRenderer::GetShaderPath() + "inlinert/"); - } - } diff --git a/WickedEngine/RenderPath3D.cpp b/WickedEngine/RenderPath3D.cpp index ab94f482d..f632e45c4 100644 --- a/WickedEngine/RenderPath3D.cpp +++ b/WickedEngine/RenderPath3D.cpp @@ -140,6 +140,16 @@ void RenderPath3D::ResizeBuffers() device->CreateTexture(&desc, nullptr, &rtAO); device->SetName(&rtAO, "rtAO"); } + if(device->CheckCapability(GRAPHICSDEVICE_CAPABILITY_RAYTRACING)) + { + TextureDesc desc; + desc.BindFlags = BIND_SHADER_RESOURCE | BIND_UNORDERED_ACCESS; + desc.Format = FORMAT_R32G32B32A32_UINT; + desc.Width = internalResolution.x; + desc.Height = internalResolution.y; + device->CreateTexture(&desc, nullptr, &rtShadow); + device->SetName(&rtShadow, "rtShadow"); + } { TextureDesc desc; desc.BindFlags = BIND_RENDER_TARGET | BIND_SHADER_RESOURCE; @@ -849,6 +859,20 @@ void RenderPath3D::Render() const wiProfiler::EndRange(range); } + if (wiRenderer::GetRaytracedShadowsEnabled()) + { + wiRenderer::Postprocess_RTShadow( + *scene, + depthBuffer_Copy, + rtLinearDepth, + depthBuffer_Copy1, + entityTiles_Opaque, + rtShadow, + cmd + ); + device->BindResource(PS, &rtShadow, TEXSLOT_RENDERPATH_RTSHADOW, cmd); + } + device->RenderPassBegin(&renderpass_main, cmd); auto range = wiProfiler::BeginRangeGPU("Opaque Scene", cmd); diff --git a/WickedEngine/RenderPath3D.h b/WickedEngine/RenderPath3D.h index 201960076..ce052a368 100644 --- a/WickedEngine/RenderPath3D.h +++ b/WickedEngine/RenderPath3D.h @@ -75,6 +75,7 @@ public: wiGraphics::Texture rtBloom; // contains the bright parts of the image + mipchain wiGraphics::Texture rtBloom_tmp; // temporary for bloom downsampling wiGraphics::Texture rtAO; // full res AO + wiGraphics::Texture rtShadow; // raytraced shadows mask wiGraphics::Texture rtSun[2]; // 0: sun render target used for lightshafts (can be MSAA), 1: radial blurred lightshafts wiGraphics::Texture rtSun_resolved; // sun render target, but the resolved version if MSAA is enabled wiGraphics::Texture rtGUIBlurredBackground[3]; // downsampled, gaussian blurred scene for GUI diff --git a/WickedEngine/ResourceMapping.h b/WickedEngine/ResourceMapping.h index 40c846ea8..7e243101a 100644 --- a/WickedEngine/ResourceMapping.h +++ b/WickedEngine/ResourceMapping.h @@ -60,7 +60,8 @@ #define TEXSLOT_ONDEMAND21 43 #define TEXSLOT_ONDEMAND22 44 #define TEXSLOT_ONDEMAND23 45 -#define TEXSLOT_ONDEMAND_COUNT (TEXSLOT_ONDEMAND23 - TEXSLOT_ONDEMAND0 + 1) +#define TEXSLOT_ONDEMAND24 46 +#define TEXSLOT_ONDEMAND_COUNT (TEXSLOT_ONDEMAND24 - TEXSLOT_ONDEMAND0 + 1) // These are reserved for demand of any type of textures in specific shaders: #define TEXSLOT_UNIQUE0 46 @@ -84,20 +85,20 @@ #define TEXSLOT_RENDERER_OCCLUSIONMAP TEXSLOT_ONDEMAND5 #define TEXSLOT_RENDERER_TRANSMISSIONMAP TEXSLOT_ONDEMAND6 -#define TEXSLOT_RENDERER_BLEND1_BASECOLORMAP TEXSLOT_ONDEMAND12 -#define TEXSLOT_RENDERER_BLEND1_NORMALMAP TEXSLOT_ONDEMAND13 -#define TEXSLOT_RENDERER_BLEND1_SURFACEMAP TEXSLOT_ONDEMAND14 -#define TEXSLOT_RENDERER_BLEND1_EMISSIVEMAP TEXSLOT_ONDEMAND15 +#define TEXSLOT_RENDERER_BLEND1_BASECOLORMAP TEXSLOT_ONDEMAND13 +#define TEXSLOT_RENDERER_BLEND1_NORMALMAP TEXSLOT_ONDEMAND14 +#define TEXSLOT_RENDERER_BLEND1_SURFACEMAP TEXSLOT_ONDEMAND15 +#define TEXSLOT_RENDERER_BLEND1_EMISSIVEMAP TEXSLOT_ONDEMAND16 -#define TEXSLOT_RENDERER_BLEND2_BASECOLORMAP TEXSLOT_ONDEMAND16 -#define TEXSLOT_RENDERER_BLEND2_NORMALMAP TEXSLOT_ONDEMAND17 -#define TEXSLOT_RENDERER_BLEND2_SURFACEMAP TEXSLOT_ONDEMAND18 -#define TEXSLOT_RENDERER_BLEND2_EMISSIVEMAP TEXSLOT_ONDEMAND19 +#define TEXSLOT_RENDERER_BLEND2_BASECOLORMAP TEXSLOT_ONDEMAND17 +#define TEXSLOT_RENDERER_BLEND2_NORMALMAP TEXSLOT_ONDEMAND18 +#define TEXSLOT_RENDERER_BLEND2_SURFACEMAP TEXSLOT_ONDEMAND19 +#define TEXSLOT_RENDERER_BLEND2_EMISSIVEMAP TEXSLOT_ONDEMAND20 -#define TEXSLOT_RENDERER_BLEND3_BASECOLORMAP TEXSLOT_ONDEMAND20 -#define TEXSLOT_RENDERER_BLEND3_NORMALMAP TEXSLOT_ONDEMAND21 -#define TEXSLOT_RENDERER_BLEND3_SURFACEMAP TEXSLOT_ONDEMAND22 -#define TEXSLOT_RENDERER_BLEND3_EMISSIVEMAP TEXSLOT_ONDEMAND23 +#define TEXSLOT_RENDERER_BLEND3_BASECOLORMAP TEXSLOT_ONDEMAND21 +#define TEXSLOT_RENDERER_BLEND3_NORMALMAP TEXSLOT_ONDEMAND22 +#define TEXSLOT_RENDERER_BLEND3_SURFACEMAP TEXSLOT_ONDEMAND23 +#define TEXSLOT_RENDERER_BLEND3_EMISSIVEMAP TEXSLOT_ONDEMAND24 // RenderPath texture mappings: #define TEXSLOT_RENDERPATH_ENTITYTILES TEXSLOT_ONDEMAND7 @@ -106,6 +107,7 @@ #define TEXSLOT_RENDERPATH_WATERRIPPLES TEXSLOT_ONDEMAND10 #define TEXSLOT_RENDERPATH_AO TEXSLOT_ONDEMAND10 #define TEXSLOT_RENDERPATH_SSR TEXSLOT_ONDEMAND11 +#define TEXSLOT_RENDERPATH_RTSHADOW TEXSLOT_ONDEMAND12 // wiImage: #define TEXSLOT_IMAGE_BASE TEXSLOT_ONDEMAND0 diff --git a/WickedEngine/Shaders_SOURCE.vcxitems b/WickedEngine/Shaders_SOURCE.vcxitems index 41b4c5b7b..f8cbdc875 100644 --- a/WickedEngine/Shaders_SOURCE.vcxitems +++ b/WickedEngine/Shaders_SOURCE.vcxitems @@ -775,6 +775,11 @@ Compute Compute + + Compute + 4.0 + Document + Compute Compute diff --git a/WickedEngine/Shaders_SOURCE.vcxitems.filters b/WickedEngine/Shaders_SOURCE.vcxitems.filters index 4fbaa954e..b95884b51 100644 --- a/WickedEngine/Shaders_SOURCE.vcxitems.filters +++ b/WickedEngine/Shaders_SOURCE.vcxitems.filters @@ -929,5 +929,8 @@ GS + + LIB + \ No newline at end of file diff --git a/WickedEngine/brdf.hlsli b/WickedEngine/brdf.hlsli index 73a06d38d..53e6bcdbe 100644 --- a/WickedEngine/brdf.hlsli +++ b/WickedEngine/brdf.hlsli @@ -149,6 +149,10 @@ struct SurfaceToLight NdotL = dot(L, surface.N); +#ifdef BRDF_NDOTL_BIAS + NdotL += BRDF_NDOTL_BIAS; +#endif // BRDF_NDOTL_BIAS + NdotL_sss = (NdotL + surface.sss.rgb) * surface.sss_inv.rgb; NdotV = saturate(dot(surface.N, surface.V)); diff --git a/WickedEngine/compile_shaders_hlsl6.py b/WickedEngine/compile_shaders_hlsl6.py index 21f238d95..edebea788 100644 --- a/WickedEngine/compile_shaders_hlsl6.py +++ b/WickedEngine/compile_shaders_hlsl6.py @@ -36,6 +36,9 @@ for item in root.iter(): for shaderprofile in item.iter(namespace + "Filter"): profile = shaderprofile.text + #if name != "rtshadowLIB.hlsl": + # continue + cmd = "dxc " + name + " -T " if profile == "VS": @@ -70,19 +73,8 @@ for item in root.iter(): output_name = os.path.splitext(name)[0] + ".cso " - #inline raytracing disabled: - cmd1 = cmd - cmd1 += " -Fo " + "shaders/hlsl6/" + output_name - t = threading.Thread(target=compile, args=(cmd1,)) - threads.append(t) - t.start() - - - #inline raytracing enabled: - cmd2 = cmd - cmd2 += " -D RAYTRACING_INLINE " - cmd2 += " -Fo " + "shaders/hlsl6/inlinert/" + output_name - t = threading.Thread(target=compile, args=(cmd2,)) + cmd += " -Fo " + "shaders/hlsl6/" + output_name + t = threading.Thread(target=compile, args=(cmd,)) threads.append(t) t.start() diff --git a/WickedEngine/globals.hlsli b/WickedEngine/globals.hlsli index 348c74033..ce52d735a 100644 --- a/WickedEngine/globals.hlsli +++ b/WickedEngine/globals.hlsli @@ -7,9 +7,6 @@ TEXTURE2D(texture_depth, float, TEXSLOT_DEPTH); TEXTURE2D(texture_lineardepth, float, TEXSLOT_LINEARDEPTH); TEXTURE2D(texture_gbuffer0, float4, TEXSLOT_GBUFFER0); TEXTURE2D(texture_gbuffer1, float4, TEXSLOT_GBUFFER1); -#ifdef RAYTRACING_INLINE -RAYTRACINGACCELERATIONSTRUCTURE(scene_acceleration_structure, TEXSLOT_ACCELERATION_STRUCTURE); -#endif // RAYTRACING_INLINE TEXTURECUBE(texture_globalenvmap, float4, TEXSLOT_GLOBALENVMAP); TEXTURE2D(texture_globallightmap, float4, TEXSLOT_GLOBALLIGHTMAP); TEXTURECUBEARRAY(texture_envmaparray, float4, TEXSLOT_ENVMAPARRAY); @@ -669,4 +666,72 @@ float3 ClosestPointOnSegment(float3 a, float3 b, float3 c) return a + saturate(t) * ab; } +static const float4 halton64[] = { + float4(0.5000000000f, 0.3333333333f, 0.2000000000f, 0.1428571429f), + float4(0.2500000000f, 0.6666666667f, 0.4000000000f, 0.2857142857f), + float4(0.7500000000f, 0.1111111111f, 0.6000000000f, 0.4285714286f), + float4(0.1250000000f, 0.4444444444f, 0.8000000000f, 0.5714285714f), + float4(0.6250000000f, 0.7777777778f, 0.0400000000f, 0.7142857143f), + float4(0.3750000000f, 0.2222222222f, 0.2400000000f, 0.8571428571f), + float4(0.8750000000f, 0.5555555556f, 0.4400000000f, 0.0204081633f), + float4(0.0625000000f, 0.8888888889f, 0.6400000000f, 0.1632653061f), + float4(0.5625000000f, 0.0370370370f, 0.8400000000f, 0.3061224490f), + float4(0.3125000000f, 0.3703703704f, 0.0800000000f, 0.4489795918f), + float4(0.8125000000f, 0.7037037037f, 0.2800000000f, 0.5918367347f), + float4(0.1875000000f, 0.1481481481f, 0.4800000000f, 0.7346938776f), + float4(0.6875000000f, 0.4814814815f, 0.6800000000f, 0.8775510204f), + float4(0.4375000000f, 0.8148148148f, 0.8800000000f, 0.0408163265f), + float4(0.9375000000f, 0.2592592593f, 0.1200000000f, 0.1836734694f), + float4(0.0312500000f, 0.5925925926f, 0.3200000000f, 0.3265306122f), + float4(0.5312500000f, 0.9259259259f, 0.5200000000f, 0.4693877551f), + float4(0.2812500000f, 0.0740740741f, 0.7200000000f, 0.6122448980f), + float4(0.7812500000f, 0.4074074074f, 0.9200000000f, 0.7551020408f), + float4(0.1562500000f, 0.7407407407f, 0.1600000000f, 0.8979591837f), + float4(0.6562500000f, 0.1851851852f, 0.3600000000f, 0.0612244898f), + float4(0.4062500000f, 0.5185185185f, 0.5600000000f, 0.2040816327f), + float4(0.9062500000f, 0.8518518519f, 0.7600000000f, 0.3469387755f), + float4(0.0937500000f, 0.2962962963f, 0.9600000000f, 0.4897959184f), + float4(0.5937500000f, 0.6296296296f, 0.0080000000f, 0.6326530612f), + float4(0.3437500000f, 0.9629629630f, 0.2080000000f, 0.7755102041f), + float4(0.8437500000f, 0.0123456790f, 0.4080000000f, 0.9183673469f), + float4(0.2187500000f, 0.3456790123f, 0.6080000000f, 0.0816326531f), + float4(0.7187500000f, 0.6790123457f, 0.8080000000f, 0.2244897959f), + float4(0.4687500000f, 0.1234567901f, 0.0480000000f, 0.3673469388f), + float4(0.9687500000f, 0.4567901235f, 0.2480000000f, 0.5102040816f), + float4(0.0156250000f, 0.7901234568f, 0.4480000000f, 0.6530612245f), + float4(0.5156250000f, 0.2345679012f, 0.6480000000f, 0.7959183673f), + float4(0.2656250000f, 0.5679012346f, 0.8480000000f, 0.9387755102f), + float4(0.7656250000f, 0.9012345679f, 0.0880000000f, 0.1020408163f), + float4(0.1406250000f, 0.0493827160f, 0.2880000000f, 0.2448979592f), + float4(0.6406250000f, 0.3827160494f, 0.4880000000f, 0.3877551020f), + float4(0.3906250000f, 0.7160493827f, 0.6880000000f, 0.5306122449f), + float4(0.8906250000f, 0.1604938272f, 0.8880000000f, 0.6734693878f), + float4(0.0781250000f, 0.4938271605f, 0.1280000000f, 0.8163265306f), + float4(0.5781250000f, 0.8271604938f, 0.3280000000f, 0.9591836735f), + float4(0.3281250000f, 0.2716049383f, 0.5280000000f, 0.1224489796f), + float4(0.8281250000f, 0.6049382716f, 0.7280000000f, 0.2653061224f), + float4(0.2031250000f, 0.9382716049f, 0.9280000000f, 0.4081632653f), + float4(0.7031250000f, 0.0864197531f, 0.1680000000f, 0.5510204082f), + float4(0.4531250000f, 0.4197530864f, 0.3680000000f, 0.6938775510f), + float4(0.9531250000f, 0.7530864198f, 0.5680000000f, 0.8367346939f), + float4(0.0468750000f, 0.1975308642f, 0.7680000000f, 0.9795918367f), + float4(0.5468750000f, 0.5308641975f, 0.9680000000f, 0.0029154519f), + float4(0.2968750000f, 0.8641975309f, 0.0160000000f, 0.1457725948f), + float4(0.7968750000f, 0.3086419753f, 0.2160000000f, 0.2886297376f), + float4(0.1718750000f, 0.6419753086f, 0.4160000000f, 0.4314868805f), + float4(0.6718750000f, 0.9753086420f, 0.6160000000f, 0.5743440233f), + float4(0.4218750000f, 0.0246913580f, 0.8160000000f, 0.7172011662f), + float4(0.9218750000f, 0.3580246914f, 0.0560000000f, 0.8600583090f), + float4(0.1093750000f, 0.6913580247f, 0.2560000000f, 0.0233236152f), + float4(0.6093750000f, 0.1358024691f, 0.4560000000f, 0.1661807580f), + float4(0.3593750000f, 0.4691358025f, 0.6560000000f, 0.3090379009f), + float4(0.8593750000f, 0.8024691358f, 0.8560000000f, 0.4518950437f), + float4(0.2343750000f, 0.2469135802f, 0.0960000000f, 0.5947521866f), + float4(0.7343750000f, 0.5802469136f, 0.2960000000f, 0.7376093294f), + float4(0.4843750000f, 0.9135802469f, 0.4960000000f, 0.8804664723f), + float4(0.9843750000f, 0.0617283951f, 0.6960000000f, 0.0437317784f), + float4(0.0078125000f, 0.3950617284f, 0.8960000000f, 0.1865889213f), + float4(0.5078125000f, 0.7283950617f, 0.1360000000f, 0.3294460641f), +}; + #endif // WI_SHADER_GLOBALS_HF diff --git a/WickedEngine/lightingHF.hlsli b/WickedEngine/lightingHF.hlsli index 14a28c818..839b8944c 100644 --- a/WickedEngine/lightingHF.hlsli +++ b/WickedEngine/lightingHF.hlsli @@ -19,6 +19,8 @@ struct Lighting { LightingPart direct; LightingPart indirect; + uint4 shadow_mask; + uint shadow_index; inline void create( in float3 diffuse_direct, @@ -31,6 +33,8 @@ struct Lighting direct.specular = specular_direct; indirect.diffuse = diffuse_indirect; indirect.specular = specular_indirect; + shadow_mask = 0; + shadow_index = 0; } }; @@ -169,7 +173,7 @@ inline float shadowTrace(in Surface surface, in float3 L, in float dist) inline void DirectionalLight(in ShaderEntity light, in Surface surface, inout Lighting lighting) { - float3 L = light.GetDirection().xyz; + float3 L = light.GetDirection(); SurfaceToLight surfaceToLight; surfaceToLight.create(surface, L); @@ -185,7 +189,14 @@ inline void DirectionalLight(in ShaderEntity light, in Surface surface, inout Li [branch] if (g_xFrame_Options & OPTION_BIT_RAYTRACED_SHADOWS) { +#ifdef RAYTRACING_INLINE shadow *= shadowTrace(surface, normalize(L), FLT_MAX); +#else + uint mask_shift = (lighting.shadow_index % 4) * 8; + uint mask_bucket = lighting.shadow_index / 4; + uint mask = (lighting.shadow_mask[mask_bucket] >> mask_shift) & 0xFF; + shadow = mask / 255.0; +#endif // RAYTRACING_INLINE } else { @@ -246,6 +257,18 @@ inline void DirectionalLight(in ShaderEntity light, in Surface surface, inout Li max(0, lightColor * surfaceToLight.NdotL * BRDF_GetSpecular(surface, surfaceToLight)); } } + + [branch] + if (light.IsCastingShadow()) + { + // The shadow contribution for raytraced shadow is detected slightly differently + // in pixel shaders and raytracing step + // So if light is shadowed, we always increment shadow index, even if actual + // contribution might have been skipped. + // + // Read more about this in rtshadowLIB.hlsl file (**) + lighting.shadow_index++; + } } inline void PointLight(in ShaderEntity light, in Surface surface, inout Lighting lighting) { @@ -274,7 +297,14 @@ inline void PointLight(in ShaderEntity light, in Surface surface, inout Lighting [branch] if (g_xFrame_Options & OPTION_BIT_RAYTRACED_SHADOWS) { +#ifdef RAYTRACING_INLINE shadow *= shadowTrace(surface, L, dist); +#else + uint mask_shift = (lighting.shadow_index % 4) * 8; + uint mask_bucket = lighting.shadow_index / 4; + uint mask = (lighting.shadow_mask[mask_bucket] >> mask_shift) & 0xFF; + shadow = mask / 255.0; +#endif // RAYTRACING_INLINE } else { @@ -299,6 +329,18 @@ inline void PointLight(in ShaderEntity light, in Surface surface, inout Lighting } } } + + [branch] + if (light.IsCastingShadow()) + { + // The shadow contribution for raytraced shadow is detected slightly differently + // in pixel shaders and raytracing step + // So if light is shadowed, we always increment shadow index, even if actual + // contribution might have been skipped. + // + // Read more about this in rtshadowLIB.hlsl file (**) + lighting.shadow_index++; + } } inline void SpotLight(in ShaderEntity light, in Surface surface, inout Lighting lighting) { @@ -332,7 +374,14 @@ inline void SpotLight(in ShaderEntity light, in Surface surface, inout Lighting [branch] if (g_xFrame_Options & OPTION_BIT_RAYTRACED_SHADOWS) { +#ifdef RAYTRACING_INLINE shadow *= shadowTrace(surface, L, dist); +#else + uint mask_shift = (lighting.shadow_index % 4) * 8; + uint mask_bucket = lighting.shadow_index / 4; + uint mask = (lighting.shadow_mask[mask_bucket] >> mask_shift) & 0xFF; + shadow = mask / 255.0; +#endif // RAYTRACING_INLINE } else { @@ -366,6 +415,18 @@ inline void SpotLight(in ShaderEntity light, in Surface surface, inout Lighting } } } + + [branch] + if (light.IsCastingShadow()) + { + // The shadow contribution for raytraced shadow is detected slightly differently + // in pixel shaders and raytracing step + // So if light is shadowed, we always increment shadow index, even if actual + // contribution might have been skipped. + // + // Read more about this in rtshadowLIB.hlsl file (**) + lighting.shadow_index++; + } } diff --git a/WickedEngine/objectHF.hlsli b/WickedEngine/objectHF.hlsli index d1d52b2d7..af6d4c591 100644 --- a/WickedEngine/objectHF.hlsli +++ b/WickedEngine/objectHF.hlsli @@ -56,6 +56,7 @@ TEXTURE2D(texture_refraction, float4, TEXSLOT_RENDERPATH_REFRACTION); // rgba: TEXTURE2D(texture_waterriples, float4, TEXSLOT_RENDERPATH_WATERRIPPLES); // rgb: snorm8 water ripple normal map TEXTURE2D(texture_ao, float, TEXSLOT_RENDERPATH_AO); // r: ambient occlusion TEXTURE2D(texture_ssr, float4, TEXSLOT_RENDERPATH_SSR); // rgb: screen space ray-traced reflections, a: reflection blend based on ray hit or miss +TEXTURE2D(texture_rtshadow, uint4, TEXSLOT_RENDERPATH_RTSHADOW); // bitmask for max 16 shadows' visibility struct PixelInputType_Simple @@ -1089,6 +1090,11 @@ GBUFFEROutputType main(PIXELINPUT input) #endif + [branch] + if (g_xFrame_Options & OPTION_BIT_RAYTRACED_SHADOWS) + { + lighting.shadow_mask = texture_rtshadow[surface.pixel]; + } #ifdef FORWARD diff --git a/WickedEngine/rtaoLIB.hlsl b/WickedEngine/rtaoLIB.hlsl index 1f02f801d..8fbf7d9d6 100644 --- a/WickedEngine/rtaoLIB.hlsl +++ b/WickedEngine/rtaoLIB.hlsl @@ -2,9 +2,7 @@ #include "ShaderInterop_Postprocess.h" #include "raytracingHF.hlsli" -#ifndef RAYTRACING_INLINE RAYTRACINGACCELERATIONSTRUCTURE(scene_acceleration_structure, TEXSLOT_ACCELERATION_STRUCTURE); -#endif // RAYTRACING_INLINE TEXTURE2D(texture_normals, float3, TEXSLOT_ONDEMAND0); diff --git a/WickedEngine/rtreflectionLIB.hlsl b/WickedEngine/rtreflectionLIB.hlsl index d346d56be..e4e352ca6 100644 --- a/WickedEngine/rtreflectionLIB.hlsl +++ b/WickedEngine/rtreflectionLIB.hlsl @@ -1,15 +1,21 @@ #define DISABLE_SOFT_SHADOWMAP #define DISABLE_TRANSPARENT_SHADOWMAP + +#ifndef SPIRV +// Vulkan shader compiler has problem with this +// https://github.com/microsoft/DirectXShaderCompiler/issues/3119 +#define RAYTRACING_INLINE +#endif // SPIRV + #include "globals.hlsli" + +RAYTRACINGACCELERATIONSTRUCTURE(scene_acceleration_structure, TEXSLOT_ACCELERATION_STRUCTURE); + #include "ShaderInterop_Postprocess.h" #include "raytracingHF.hlsli" #include "stochasticSSRHF.hlsli" #include "lightingHF.hlsli" -#ifndef RAYTRACING_INLINE -RAYTRACINGACCELERATIONSTRUCTURE(scene_acceleration_structure, TEXSLOT_ACCELERATION_STRUCTURE); -#endif // RAYTRACING_INLINE - RWTEXTURE2D(output, float4, 0); ConstantBuffer subsets_material[] : register(b0, space1); @@ -185,6 +191,9 @@ void RTReflection_ClosestHit(inout RayPayload payload, in MyAttributes attr) Surface surface; surface.create(material, baseColor, surfaceMap); + surface.pixel = DispatchRaysIndex().xy; + surface.screenUV = surface.pixel / (float2)DispatchRaysDimensions().xy; + [branch] if (material.IsOcclusionEnabled_Secondary() && material.uvset_occlusionMap >= 0) { diff --git a/WickedEngine/rtshadowLIB.hlsl b/WickedEngine/rtshadowLIB.hlsl new file mode 100644 index 000000000..161ed2dea --- /dev/null +++ b/WickedEngine/rtshadowLIB.hlsl @@ -0,0 +1,283 @@ +#define BRDF_NDOTL_BIAS 0.1 +#include "globals.hlsli" +#include "ShaderInterop_Postprocess.h" +#include "raytracingHF.hlsli" + +RAYTRACINGACCELERATIONSTRUCTURE(scene_acceleration_structure, TEXSLOT_ACCELERATION_STRUCTURE); + +TEXTURE2D(texture_normals, float3, TEXSLOT_ONDEMAND0); +STRUCTUREDBUFFER(EntityTiles, uint, TEXSLOT_RENDERPATH_ENTITYTILES); + +static const uint MAX_RTSHADOWS = 16; +RWTEXTURE2D(output, uint4, 0); + +ConstantBuffer subsets_material[] : register(b0, space1); +Texture2D subsets_textures[] : register(t0, space2); +Buffer subsets_indexBuffer[] : register(t0, space3); +Buffer subsets_vertexBuffer_UVSETS[] : register(t0, space4); + +typedef BuiltInTriangleIntersectionAttributes MyAttributes; +struct RayPayload +{ + float color; +}; + +[shader("raygeneration")] +void RTAO_Raygen() +{ + const float2 uv = ((float2)DispatchRaysIndex() + 0.5f) / (float2)DispatchRaysDimensions(); + const float depth = texture_depth.SampleLevel(sampler_point_clamp, uv, 0); + if (depth == 0.0f) + return; + + const float3 P = reconstructPosition(uv, depth); + float3 N = normalize(texture_normals.SampleLevel(sampler_point_clamp, uv, 0) * 2 - 1); + + Surface surface; + surface.init(); + surface.pixel = DispatchRaysIndex().xy; + surface.P = P; + surface.N = N; + + const uint2 tileIndex = uint2(floor(surface.pixel / TILED_CULLING_BLOCKSIZE)); + const uint flatTileIndex = flatten2D(tileIndex, g_xFrame_EntityCullingTileCount.xy) * SHADER_ENTITY_TILE_BUCKET_COUNT; + + uint4 shadow_mask = 0; + uint shadow_index = 0; + + [branch] + if (g_xFrame_LightArrayCount > 0) + { + // Loop through light buckets in the tile: + const uint first_item = g_xFrame_LightArrayOffset; + const uint last_item = first_item + g_xFrame_LightArrayCount - 1; + const uint first_bucket = first_item / 32; + const uint last_bucket = min(last_item / 32, max(0, SHADER_ENTITY_TILE_BUCKET_COUNT - 1)); + [loop] + for (uint bucket = first_bucket; bucket <= last_bucket && shadow_index < MAX_RTSHADOWS; ++bucket) + { + uint bucket_bits = EntityTiles[flatTileIndex + bucket]; + + // Bucket scalarizer - Siggraph 2017 - Improved Culling [Michal Drobot]: + bucket_bits = WaveReadLaneFirst(WaveActiveBitOr(bucket_bits)); + + [loop] + while (bucket_bits != 0 && shadow_index < MAX_RTSHADOWS) + { + // Retrieve global entity index from local bucket, then remove bit from local bucket: + const uint bucket_bit_index = firstbitlow(bucket_bits); + const uint entity_index = bucket * 32 + bucket_bit_index; + bucket_bits ^= 1 << bucket_bit_index; + + // Check if it is a light and process: + [branch] + if (entity_index >= first_item && entity_index <= last_item) + { + ShaderEntity light = EntityArray[entity_index]; + + if (!light.IsCastingShadow()) + { + continue; + } + + if (light.GetFlags() & ENTITY_FLAG_LIGHT_STATIC) + { + continue; // static lights will be skipped (they are used in lightmap baking) + } + + RayDesc ray; + ray.TMin = 0.001; + ray.TMax = 0; + ray.Origin = surface.P + surface.N * 0.1; + + float3 L; + + switch (light.GetType()) + { + default: + case ENTITY_TYPE_DIRECTIONALLIGHT: + { + L = normalize(light.GetDirection()); + + SurfaceToLight surfaceToLight; + surfaceToLight.create(surface, L); + + [branch] + if (any(surfaceToLight.NdotL)) + { + [branch] + if (light.IsCastingShadow()) + { + ray.TMax = FLT_MAX; + } + } + } + break; + case ENTITY_TYPE_POINTLIGHT: + { + L = light.position - surface.P; + const float dist2 = dot(L, L); + const float range2 = light.GetRange() * light.GetRange(); + + [branch] + if (dist2 < range2) + { + const float3 Lunnormalized = L; + const float dist = sqrt(dist2); + L /= dist; + + SurfaceToLight surfaceToLight; + surfaceToLight.create(surface, L); + + [branch] + if (any(surfaceToLight.NdotL)) + { + ray.TMax = dist; + } + } + } + break; + case ENTITY_TYPE_SPOTLIGHT: + { + L = light.position - surface.P; + const float dist2 = dot(L, L); + const float range2 = light.GetRange() * light.GetRange(); + + [branch] + if (dist2 < range2) + { + const float dist = sqrt(dist2); + L /= dist; + + SurfaceToLight surfaceToLight; + surfaceToLight.create(surface, L); + + [branch] + if (any(surfaceToLight.NdotL_sss)) + { + const float SpotFactor = dot(L, light.GetDirection()); + const float spotCutOff = light.GetConeAngleCos(); + + [branch] + if (SpotFactor > spotCutOff) + { + ray.TMax = dist; + } + } + } + } + break; + } + + [branch] + if (ray.TMax > 0) + { + float seed = g_xFrame_FrameCount * 0.001; + + RayPayload payload; + payload.color = 0; + + for (uint i = 0; i < g_xFrame_RaytracedShadowsSampleCount; ++i) + { + float3 sampling_offset = float3(rand(seed, uv), rand(seed, uv), rand(seed, uv)) * 2 - 1; // todo: should be specific to light surface + ray.Direction = normalize(L + sampling_offset * 0.025); + + TraceRay( + scene_acceleration_structure, // AccelerationStructure + RAY_FLAG_SKIP_CLOSEST_HIT_SHADER, // RayFlags + ~0, // InstanceInclusionMask + 0, // RayContributionToHitGroupIndex + 0, // MultiplierForGeomtryContributionToShaderIndex + 0, // MissShaderIndex + ray, // Ray + payload // Payload + ); + } + payload.color /= g_xFrame_RaytracedShadowsSampleCount; + + uint mask = uint(saturate(payload.color) * 255); // 8 bits + uint mask_shift = (shadow_index % 4) * 8; + uint mask_bucket = shadow_index / 4; + shadow_mask[mask_bucket] |= mask << mask_shift; + } + + // (**) cannot detect exactly same contribution as is pixel shaders! + // So we always increment it for shadowed light, even if the + // shadow contribution is not traced + // + // This is because in the pixel shader, we will detect the shadow + // contribution more precisely due to more precise surface normals + shadow_index++; + + } + else if (entity_index > last_item) + { + // force exit: + bucket = SHADER_ENTITY_TILE_BUCKET_COUNT; + break; + } + + } + + } + } + + output[DispatchRaysIndex().xy] = shadow_mask; +} + +[shader("closesthit")] +void RTAO_ClosestHit(inout RayPayload payload, in MyAttributes attr) +{ + //payload.color = 0; +} + +[shader("anyhit")] +void RTAO_AnyHit(inout RayPayload payload, in MyAttributes attr) +{ + float u = attr.barycentrics.x; + float v = attr.barycentrics.y; + float w = 1 - u - v; + uint primitiveIndex = PrimitiveIndex(); + uint geometryOffset = InstanceID(); + uint geometryIndex = GeometryIndex(); // requires tier_1_1 GeometryIndex feature!! + uint descriptorIndex = geometryOffset + geometryIndex; + ShaderMaterial material = subsets_material[descriptorIndex]; + if (material.uvset_baseColorMap < 0) + { + AcceptHitAndEndSearch(); + } + uint i0 = subsets_indexBuffer[descriptorIndex][primitiveIndex * 3 + 0]; + uint i1 = subsets_indexBuffer[descriptorIndex][primitiveIndex * 3 + 1]; + uint i2 = subsets_indexBuffer[descriptorIndex][primitiveIndex * 3 + 2]; + float2 uv0, uv1, uv2; + if (material.uvset_baseColorMap == 0) + { + uv0 = subsets_vertexBuffer_UVSETS[descriptorIndex * VERTEXBUFFER_DESCRIPTOR_UV_COUNT + VERTEXBUFFER_DESCRIPTOR_UV_0][i0]; + uv1 = subsets_vertexBuffer_UVSETS[descriptorIndex * VERTEXBUFFER_DESCRIPTOR_UV_COUNT + VERTEXBUFFER_DESCRIPTOR_UV_0][i1]; + uv2 = subsets_vertexBuffer_UVSETS[descriptorIndex * VERTEXBUFFER_DESCRIPTOR_UV_COUNT + VERTEXBUFFER_DESCRIPTOR_UV_0][i2]; + } + else + { + uv0 = subsets_vertexBuffer_UVSETS[descriptorIndex * VERTEXBUFFER_DESCRIPTOR_UV_COUNT + VERTEXBUFFER_DESCRIPTOR_UV_1][i0]; + uv1 = subsets_vertexBuffer_UVSETS[descriptorIndex * VERTEXBUFFER_DESCRIPTOR_UV_COUNT + VERTEXBUFFER_DESCRIPTOR_UV_1][i1]; + uv2 = subsets_vertexBuffer_UVSETS[descriptorIndex * VERTEXBUFFER_DESCRIPTOR_UV_COUNT + VERTEXBUFFER_DESCRIPTOR_UV_1][i2]; + } + + float2 uv = uv0 * w + uv1 * u + uv2 * v; + float alpha = subsets_textures[descriptorIndex * MATERIAL_TEXTURE_SLOT_DESCRIPTOR_COUNT + MATERIAL_TEXTURE_SLOT_DESCRIPTOR_BASECOLOR].SampleLevel(sampler_point_wrap, uv, 2).a; + + if (alpha - material.alphaTest > 0) + { + AcceptHitAndEndSearch(); + } + else + { + IgnoreHit(); + } +} + +[shader("miss")] +void RTAO_Miss(inout RayPayload payload) +{ + payload.color += 1; +} diff --git a/WickedEngine/wiEmittedParticle.cpp b/WickedEngine/wiEmittedParticle.cpp index 9d7c513c2..f4d51f63a 100644 --- a/WickedEngine/wiEmittedParticle.cpp +++ b/WickedEngine/wiEmittedParticle.cpp @@ -46,6 +46,8 @@ static DepthStencilState depthStencilState; static PipelineState PSO[BLENDMODE_COUNT][wiEmittedParticle::PARTICLESHADERTYPE_COUNT]; static PipelineState PSO_wire; +static bool ALLOW_MESH_SHADER = false; + void wiEmittedParticle::SetMaxParticleCount(uint32_t value) { @@ -280,7 +282,7 @@ void wiEmittedParticle::UpdateGPU(const TransformComponent& transform, const Mat { cb.xEmitterOptions |= EMITTER_OPTION_BIT_FRAME_BLENDING_ENABLED; } - if (device->CheckCapability(GRAPHICSDEVICE_CAPABILITY_MESH_SHADER)) + if (ALLOW_MESH_SHADER && device->CheckCapability(GRAPHICSDEVICE_CAPABILITY_MESH_SHADER)) { cb.xEmitterOptions |= EMITTER_OPTION_BIT_MESH_SHADER_ENABLED; } @@ -547,7 +549,7 @@ void wiEmittedParticle::Draw(const CameraComponent& camera, const MaterialCompon device->BindConstantBuffer(PS, &constantBuffer, CB_GETBINDSLOT(EmittedParticleCB), cmd); device->BindConstantBuffer(PS, &material.constantBuffer, CB_GETBINDSLOT(MaterialCB), cmd); - if (device->CheckCapability(GRAPHICSDEVICE_CAPABILITY_MESH_SHADER)) + if (ALLOW_MESH_SHADER && device->CheckCapability(GRAPHICSDEVICE_CAPABILITY_MESH_SHADER)) { const GPUResource* res[] = { &counterBuffer, @@ -579,7 +581,7 @@ namespace wiEmittedParticle_Internal wiRenderer::LoadShader(VS, vertexShader, "emittedparticleVS.cso"); - if (wiRenderer::GetDevice()->CheckCapability(GRAPHICSDEVICE_CAPABILITY_MESH_SHADER)) + if (ALLOW_MESH_SHADER && wiRenderer::GetDevice()->CheckCapability(GRAPHICSDEVICE_CAPABILITY_MESH_SHADER)) { wiRenderer::LoadShader(MS, meshShader, "emittedparticleMS.cso"); } @@ -611,7 +613,7 @@ namespace wiEmittedParticle_Internal { PipelineStateDesc desc; desc.pt = TRIANGLESTRIP; - if (wiRenderer::GetDevice()->CheckCapability(GRAPHICSDEVICE_CAPABILITY_MESH_SHADER)) + if (ALLOW_MESH_SHADER && wiRenderer::GetDevice()->CheckCapability(GRAPHICSDEVICE_CAPABILITY_MESH_SHADER)) { desc.ms = &meshShader; } @@ -632,7 +634,7 @@ namespace wiEmittedParticle_Internal { PipelineStateDesc desc; - if (wiRenderer::GetDevice()->CheckCapability(GRAPHICSDEVICE_CAPABILITY_MESH_SHADER)) + if (ALLOW_MESH_SHADER && wiRenderer::GetDevice()->CheckCapability(GRAPHICSDEVICE_CAPABILITY_MESH_SHADER)) { desc.ms = &meshShader; } diff --git a/WickedEngine/wiEnums.h b/WickedEngine/wiEnums.h index 39c506775..7c4926986 100644 --- a/WickedEngine/wiEnums.h +++ b/WickedEngine/wiEnums.h @@ -347,6 +347,7 @@ enum SHADERTYPE // raytracing shaders RTTYPE_RTAO, RTTYPE_RTREFLECTION, + RTTYPE_RTSHADOW, diff --git a/WickedEngine/wiGraphicsDevice_Vulkan.cpp b/WickedEngine/wiGraphicsDevice_Vulkan.cpp index 069882e27..f1b66d519 100644 --- a/WickedEngine/wiGraphicsDevice_Vulkan.cpp +++ b/WickedEngine/wiGraphicsDevice_Vulkan.cpp @@ -2384,8 +2384,9 @@ using namespace Vulkan_Internal; } } - if (checkExtensionSupport(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME, available_deviceExtensions)) + if (!DEBUGDEVICE && checkExtensionSupport(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME, available_deviceExtensions)) { + // Note: VRS will crash vulkan validation layers: https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/2473 VARIABLE_RATE_SHADING_TILE_SIZE = std::min(fragment_shading_rate_properties.maxFragmentShadingRateAttachmentTexelSize.width, fragment_shading_rate_properties.maxFragmentShadingRateAttachmentTexelSize.height); enabled_deviceExtensions.push_back(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME); fragment_shading_rate_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR; @@ -2430,13 +2431,11 @@ using namespace Vulkan_Internal; { assert(acceleration_structure_features.accelerationStructure == VK_TRUE); assert(features_1_2.bufferDeviceAddress == VK_TRUE); - // Shader compiler has bug with vk inline raytracing now: - //capabilities |= GRAPHICSDEVICE_CAPABILITY_RAYTRACING_INLINE; + capabilities |= GRAPHICSDEVICE_CAPABILITY_RAYTRACING_INLINE; } if (mesh_shader_features.meshShader == VK_TRUE && mesh_shader_features.taskShader == VK_TRUE) { - // Enable mesh shader here (problematic with certain driver versions, disabled by default): - //capabilities |= GRAPHICSDEVICE_CAPABILITY_MESH_SHADER; + capabilities |= GRAPHICSDEVICE_CAPABILITY_MESH_SHADER; } assert(features_1_2.hostQueryReset == VK_TRUE); diff --git a/WickedEngine/wiRenderer.cpp b/WickedEngine/wiRenderer.cpp index fc74f874f..5e8403f9e 100644 --- a/WickedEngine/wiRenderer.cpp +++ b/WickedEngine/wiRenderer.cpp @@ -10302,6 +10302,206 @@ void Postprocess_SSR( wiProfiler::EndRange(range); device->EventEnd(cmd); } +void Postprocess_RTShadow( + const Scene& scene, + const Texture& depthbuffer, + const Texture& lineardepth, + const Texture& depth_history, + const wiGraphics::GPUBuffer& entityTiles_Opaque, + const Texture& output, + CommandList cmd +) +{ + if (!wiRenderer::device->CheckCapability(GRAPHICSDEVICE_CAPABILITY_RAYTRACING)) + return; + if (!wiRenderer::device->CheckCapability(GRAPHICSDEVICE_CAPABILITY_DESCRIPTOR_MANAGEMENT)) + return; + + if (scene.objects.GetCount() <= 0) + { + return; + } + + device->EventBegin("Postprocess_RTShadow", cmd); + auto prof_range = wiProfiler::BeginRangeGPU("RTShadow", cmd); + + static RaytracingPipelineState RTPSO; + static DescriptorTable descriptorTable; + static RootSignature rootSignature; + + auto load_shaders = [&scene](uint64_t userdata) { + + descriptorTable = DescriptorTable(); + descriptorTable.resources.push_back({ TEXTURE2D, TEXSLOT_DEPTH }); + descriptorTable.resources.push_back({ TEXTURE2D, TEXSLOT_ONDEMAND0 }); + descriptorTable.resources.push_back({ ACCELERATIONSTRUCTURE, TEXSLOT_ACCELERATION_STRUCTURE }); + descriptorTable.resources.push_back({ STRUCTUREDBUFFER, SBSLOT_ENTITYARRAY }); + descriptorTable.resources.push_back({ STRUCTUREDBUFFER, TEXSLOT_RENDERPATH_ENTITYTILES }); + descriptorTable.resources.push_back({ RWTEXTURE2D, 0 }); + descriptorTable.resources.push_back({ ROOT_CONSTANTBUFFER, CB_GETBINDSLOT(FrameCB) }); + descriptorTable.resources.push_back({ ROOT_CONSTANTBUFFER, CB_GETBINDSLOT(CameraCB) }); + descriptorTable.resources.push_back({ ROOT_CONSTANTBUFFER, CB_GETBINDSLOT(PostProcessCB) }); + descriptorTable.staticsamplers.push_back({ samplers[SSLOT_POINT_CLAMP], SSLOT_POINT_CLAMP }); + descriptorTable.staticsamplers.push_back({ samplers[SSLOT_LINEAR_CLAMP], SSLOT_LINEAR_CLAMP }); + descriptorTable.staticsamplers.push_back({ samplers[SSLOT_POINT_WRAP], SSLOT_POINT_WRAP }); + descriptorTable.staticsamplers.push_back({ samplers[SSLOT_LINEAR_WRAP], SSLOT_LINEAR_WRAP }); + device->CreateDescriptorTable(&descriptorTable); + + rootSignature = RootSignature(); + rootSignature.tables.push_back(descriptorTable); + rootSignature.tables.push_back(scene.descriptorTables[Scene::DESCRIPTORTABLE_SUBSETS_MATERIAL]); + rootSignature.tables.push_back(scene.descriptorTables[Scene::DESCRIPTORTABLE_SUBSETS_TEXTURES]); + rootSignature.tables.push_back(scene.descriptorTables[Scene::DESCRIPTORTABLE_SUBSETS_INDEXBUFFER]); + rootSignature.tables.push_back(scene.descriptorTables[Scene::DESCRIPTORTABLE_SUBSETS_VERTEXBUFFER_UVSETS]); + device->CreateRootSignature(&rootSignature); + + shaders[RTTYPE_RTSHADOW].rootSignature = &rootSignature; + bool success = LoadShader(SHADERSTAGE_COUNT, shaders[RTTYPE_RTSHADOW], "rtshadowLIB.cso"); + assert(success); + + RaytracingPipelineStateDesc rtdesc; + rtdesc.rootSignature = &rootSignature; + + rtdesc.shaderlibraries.emplace_back(); + rtdesc.shaderlibraries.back().shader = &shaders[RTTYPE_RTSHADOW]; + rtdesc.shaderlibraries.back().function_name = "RTAO_Raygen"; + rtdesc.shaderlibraries.back().type = ShaderLibrary::RAYGENERATION; + + rtdesc.shaderlibraries.emplace_back(); + rtdesc.shaderlibraries.back().shader = &shaders[RTTYPE_RTSHADOW]; + rtdesc.shaderlibraries.back().function_name = "RTAO_ClosestHit"; + rtdesc.shaderlibraries.back().type = ShaderLibrary::CLOSESTHIT; + + rtdesc.shaderlibraries.emplace_back(); + rtdesc.shaderlibraries.back().shader = &shaders[RTTYPE_RTSHADOW]; + rtdesc.shaderlibraries.back().function_name = "RTAO_AnyHit"; + rtdesc.shaderlibraries.back().type = ShaderLibrary::ANYHIT; + + rtdesc.shaderlibraries.emplace_back(); + rtdesc.shaderlibraries.back().shader = &shaders[RTTYPE_RTSHADOW]; + rtdesc.shaderlibraries.back().function_name = "RTAO_Miss"; + rtdesc.shaderlibraries.back().type = ShaderLibrary::MISS; + + rtdesc.hitgroups.emplace_back(); + rtdesc.hitgroups.back().type = ShaderHitGroup::GENERAL; + rtdesc.hitgroups.back().name = "RTAO_Raygen"; + rtdesc.hitgroups.back().general_shader = 0; + + rtdesc.hitgroups.emplace_back(); + rtdesc.hitgroups.back().type = ShaderHitGroup::GENERAL; + rtdesc.hitgroups.back().name = "RTAO_Miss"; + rtdesc.hitgroups.back().general_shader = 3; + + rtdesc.hitgroups.emplace_back(); + rtdesc.hitgroups.back().type = ShaderHitGroup::TRIANGLES; + rtdesc.hitgroups.back().name = "RTAO_Hitgroup"; + rtdesc.hitgroups.back().closesthit_shader = 1; + rtdesc.hitgroups.back().anyhit_shader = 2; + + rtdesc.max_trace_recursion_depth = 1; + rtdesc.max_payload_size_in_bytes = sizeof(float); + rtdesc.max_attribute_size_in_bytes = sizeof(XMFLOAT2); // bary + success = device->CreateRaytracingPipelineState(&rtdesc, &RTPSO); + assert(success); + + success = LoadShader(CS, shaders[CSTYPE_POSTPROCESS_RTAO_DENOISE_TEMPORAL], "rtao_denoise_temporalCS.cso"); + assert(success); + success = LoadShader(CS, shaders[CSTYPE_POSTPROCESS_RTAO_DENOISE_BLUR], "rtao_denoise_blurCS.cso"); + assert(success); + }; + + static wiEvent::Handle handle = wiEvent::Subscribe(SYSTEM_EVENT_RELOAD_SHADERS, load_shaders); + if (!RTPSO.IsValid()) + { + load_shaders(0); + } + + static TextureDesc saved_desc; + static Texture normals; + + const TextureDesc& lineardepth_desc = lineardepth.GetDesc(); + if (saved_desc.Width != lineardepth_desc.Width || saved_desc.Height != lineardepth_desc.Height) + { + saved_desc = lineardepth_desc; // <- this must already have SRV and UAV request flags set up! + saved_desc.MipLevels = 1; + + TextureDesc desc = saved_desc; + desc.Width = desc.Width; + desc.Height = desc.Height; + desc.Format = FORMAT_R11G11B10_FLOAT; + device->CreateTexture(&desc, nullptr, &normals); + device->SetName(&normals, "rtao_normals"); + } + + Postprocess_NormalsFromDepth(depthbuffer, normals, cmd); + + device->EventBegin("Raytrace", cmd); + + const TextureDesc& desc = output.GetDesc(); + + PostProcessCB cb; + cb.xPPResolution.x = desc.Width; + cb.xPPResolution.y = desc.Height; + cb.xPPResolution_rcp.x = 1.0f / cb.xPPResolution.x; + cb.xPPResolution_rcp.y = 1.0f / cb.xPPResolution.y; + GraphicsDevice::GPUAllocation cb_alloc = device->AllocateGPU(sizeof(cb), cmd); + memcpy(cb_alloc.data, &cb, sizeof(cb)); + + device->BindRaytracingPipelineState(&RTPSO, cmd); + device->WriteDescriptor(&descriptorTable, 0, 0, &depthbuffer); + device->WriteDescriptor(&descriptorTable, 1, 0, &normals); + device->WriteDescriptor(&descriptorTable, 2, 0, &scene.TLAS); + device->WriteDescriptor(&descriptorTable, 2, 0, &scene.TLAS); + device->WriteDescriptor(&descriptorTable, 3, 0, &resourceBuffers[RBTYPE_ENTITYARRAY]); + device->WriteDescriptor(&descriptorTable, 4, 0, &entityTiles_Opaque); + device->WriteDescriptor(&descriptorTable, 5, 0, &output); + for (size_t i = 0; i < rootSignature.tables.size(); ++i) + { + device->BindDescriptorTable(RAYTRACING, (uint32_t)i, &rootSignature.tables[i], cmd); + } + device->BindRootDescriptor(RAYTRACING, 0, &constantBuffers[CBTYPE_FRAME], 0, cmd); + device->BindRootDescriptor(RAYTRACING, 1, &constantBuffers[CBTYPE_CAMERA], 0, cmd); + device->BindRootDescriptor(RAYTRACING, 2, cb_alloc.buffer, cb_alloc.offset, cmd); + + size_t shaderIdentifierSize = device->GetShaderIdentifierSize(); + GraphicsDevice::GPUAllocation shadertable_raygen = device->AllocateGPU(shaderIdentifierSize, cmd); + GraphicsDevice::GPUAllocation shadertable_miss = device->AllocateGPU(shaderIdentifierSize, cmd); + GraphicsDevice::GPUAllocation shadertable_hitgroup = device->AllocateGPU(shaderIdentifierSize, cmd); + + device->WriteShaderIdentifier(&RTPSO, 0, shadertable_raygen.data); + device->WriteShaderIdentifier(&RTPSO, 1, shadertable_miss.data); + device->WriteShaderIdentifier(&RTPSO, 2, shadertable_hitgroup.data); + + DispatchRaysDesc dispatchraysdesc; + dispatchraysdesc.raygeneration.buffer = shadertable_raygen.buffer; + dispatchraysdesc.raygeneration.offset = shadertable_raygen.offset; + dispatchraysdesc.raygeneration.size = shaderIdentifierSize; + + dispatchraysdesc.miss.buffer = shadertable_miss.buffer; + dispatchraysdesc.miss.offset = shadertable_miss.offset; + dispatchraysdesc.miss.size = shaderIdentifierSize; + dispatchraysdesc.miss.stride = shaderIdentifierSize; + + dispatchraysdesc.hitgroup.buffer = shadertable_hitgroup.buffer; + dispatchraysdesc.hitgroup.offset = shadertable_hitgroup.offset; + dispatchraysdesc.hitgroup.size = shaderIdentifierSize; + dispatchraysdesc.hitgroup.stride = shaderIdentifierSize; + + dispatchraysdesc.Width = desc.Width; + dispatchraysdesc.Height = desc.Height; + + device->DispatchRays(&dispatchraysdesc, cmd); + + GPUBarrier barriers[] = { + GPUBarrier::Memory(), + }; + device->Barrier(barriers, arraysize(barriers), cmd); + + device->EventEnd(cmd); + + wiProfiler::EndRange(prof_range); + device->EventEnd(cmd); +} void Postprocess_LightShafts( const Texture& input, const Texture& output, diff --git a/WickedEngine/wiRenderer.h b/WickedEngine/wiRenderer.h index 9136aeb45..4769a7272 100644 --- a/WickedEngine/wiRenderer.h +++ b/WickedEngine/wiRenderer.h @@ -338,6 +338,15 @@ namespace wiRenderer const wiGraphics::Texture& output, wiGraphics::CommandList cmd ); + void Postprocess_RTShadow( + const wiScene::Scene& scene, + const wiGraphics::Texture& depthbuffer, + const wiGraphics::Texture& lineardepth, + const wiGraphics::Texture& depth_history, + const wiGraphics::GPUBuffer& entityTiles_Opaque, + const wiGraphics::Texture& output, + wiGraphics::CommandList cmd + ); void Postprocess_LightShafts( const wiGraphics::Texture& input, const wiGraphics::Texture& output, diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index b20231c5e..635fa392a 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -9,7 +9,7 @@ namespace wiVersion // minor features, major updates, breaking compatibility changes const int minor = 51; // minor bug fixes, alterations, refactors, updates - const int revision = 51; + const int revision = 52; const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);