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);