Ray traced diffuse (#561)
* Ray traced diffuse * tweaks * tweaks * tweaks * updates * ddgi update speed, ssr roughness cutoff, rt reflections ray length, rt diffuse ray length,
This commit is contained in:
@@ -1069,6 +1069,7 @@ It inherits functions from RenderPath2D, so it can render a 2D overlay.
|
||||
- AO_MSAO : int -- enable multi scale screen space ambient occlusion (use in SetAO() function)
|
||||
- SetAOPower(float value) -- applies AO power value if any AO is enabled
|
||||
- SetSSREnabled(bool value)
|
||||
- SetRaytracedDiffuseEnabled(bool value)
|
||||
- SetRaytracedReflectionsEnabled(bool value)
|
||||
- SetShadowsEnabled(bool value)
|
||||
- SetReflectionsEnabled(bool value)
|
||||
|
||||
@@ -14,7 +14,7 @@ void GraphicsWindow::Create(EditorComponent* _editor)
|
||||
wi::renderer::SetToDrawGridHelper(true);
|
||||
wi::renderer::SetToDrawDebugCameras(true);
|
||||
|
||||
SetSize(XMFLOAT2(580, 1760));
|
||||
SetSize(XMFLOAT2(580, 1850));
|
||||
|
||||
float step = 21;
|
||||
float itemheight = 18;
|
||||
@@ -199,6 +199,16 @@ void GraphicsWindow::Create(EditorComponent* _editor)
|
||||
});
|
||||
AddWidget(&ddgiRayCountSlider);
|
||||
|
||||
ddgiBlendSpeedSlider.Create(0, 0.1f, 0.02f, 1000, "DDGI Blend Speed: ");
|
||||
ddgiBlendSpeedSlider.SetTooltip("Adjust the contribution of newly traced rays. Higher values will make the DDGI update faster, but can result in increased flickering.");
|
||||
ddgiBlendSpeedSlider.SetSize(XMFLOAT2(wid, itemheight));
|
||||
ddgiBlendSpeedSlider.SetPos(XMFLOAT2(x, y += step));
|
||||
ddgiBlendSpeedSlider.SetValue(wi::renderer::GetDDGIBlendSpeed());
|
||||
ddgiBlendSpeedSlider.OnSlide([&](wi::gui::EventArgs args) {
|
||||
wi::renderer::SetDDGIBlendSpeed(args.fValue);
|
||||
});
|
||||
AddWidget(&ddgiBlendSpeedSlider);
|
||||
|
||||
ddgiSmoothBackfaceSlider.Create(0, 1, 0, 1000, "DDGI Smoothen: ");
|
||||
ddgiSmoothBackfaceSlider.SetTooltip("Adjust the amount of smooth backface test.");
|
||||
ddgiSmoothBackfaceSlider.SetSize(XMFLOAT2(wid, itemheight));
|
||||
@@ -758,7 +768,7 @@ void GraphicsWindow::Create(EditorComponent* _editor)
|
||||
lightShaftsStrengthStrengthSlider.SetTooltip("Set light shaft strength.");
|
||||
lightShaftsStrengthStrengthSlider.SetSize(XMFLOAT2(mod_wid, hei));
|
||||
lightShaftsStrengthStrengthSlider.SetPos(XMFLOAT2(x + 100, y));
|
||||
if (editor->main->config.GetSection("graphics").GetBool("lightshafts_strength"))
|
||||
if (editor->main->config.GetSection("graphics").Has("lightshafts_strength"))
|
||||
{
|
||||
editor->renderPath->setLightShaftsStrength(editor->main->config.GetSection("graphics").GetFloat("lightshafts_strength"));
|
||||
}
|
||||
@@ -800,7 +810,7 @@ void GraphicsWindow::Create(EditorComponent* _editor)
|
||||
aoPowerSlider.SetTooltip("Set SSAO Power. Higher values produce darker, more pronounced effect");
|
||||
aoPowerSlider.SetSize(XMFLOAT2(mod_wid, hei));
|
||||
aoPowerSlider.SetPos(XMFLOAT2(x + 100, y += step));
|
||||
if (editor->main->config.GetSection("graphics").GetBool("ambient_occlusion_power"))
|
||||
if (editor->main->config.GetSection("graphics").Has("ambient_occlusion_power"))
|
||||
{
|
||||
editor->renderPath->setAOPower(editor->main->config.GetSection("graphics").GetFloat("ambient_occlusion_power"));
|
||||
}
|
||||
@@ -815,7 +825,7 @@ void GraphicsWindow::Create(EditorComponent* _editor)
|
||||
aoRangeSlider.SetTooltip("Set AO ray length. Only for SSAO and RTAO");
|
||||
aoRangeSlider.SetSize(XMFLOAT2(mod_wid, hei));
|
||||
aoRangeSlider.SetPos(XMFLOAT2(x + 100, y += step));
|
||||
if (editor->main->config.GetSection("graphics").GetBool("ambient_occlusion_range"))
|
||||
if (editor->main->config.GetSection("graphics").Has("ambient_occlusion_range"))
|
||||
{
|
||||
editor->renderPath->setAORange(editor->main->config.GetSection("graphics").GetFloat("ambient_occlusion_range"));
|
||||
}
|
||||
@@ -836,7 +846,7 @@ void GraphicsWindow::Create(EditorComponent* _editor)
|
||||
AddWidget(&aoSampleCountSlider);
|
||||
|
||||
ssrCheckBox.Create("SSR: ");
|
||||
ssrCheckBox.SetTooltip("Enable Screen Space Reflections.");
|
||||
ssrCheckBox.SetTooltip("Enable Screen Space Reflections. This can not reflect anything that is outside of the screen.");
|
||||
ssrCheckBox.SetScriptTip("RenderPath3D::SetSSREnabled(bool value)");
|
||||
ssrCheckBox.SetSize(XMFLOAT2(hei, hei));
|
||||
ssrCheckBox.SetPos(XMFLOAT2(x, y += step));
|
||||
@@ -848,6 +858,21 @@ void GraphicsWindow::Create(EditorComponent* _editor)
|
||||
});
|
||||
AddWidget(&ssrCheckBox);
|
||||
|
||||
reflectionsRoughnessCutoffSlider.Create(0, 1, 0.6f, 1000, "Cutoff: ");
|
||||
reflectionsRoughnessCutoffSlider.SetTooltip("Set maximum roughness which can be used to apply screen space or raytraced reflections.");
|
||||
reflectionsRoughnessCutoffSlider.SetSize(XMFLOAT2(mod_wid, hei));
|
||||
reflectionsRoughnessCutoffSlider.SetPos(XMFLOAT2(x + 100, y += step));
|
||||
if (editor->main->config.GetSection("graphics").Has("reflection_roughness_cutoff"))
|
||||
{
|
||||
editor->renderPath->setReflectionRoughnessCutoff(editor->main->config.GetSection("graphics").GetFloat("reflection_roughness_cutoff"));
|
||||
}
|
||||
reflectionsRoughnessCutoffSlider.OnSlide([=](wi::gui::EventArgs args) {
|
||||
editor->renderPath->setReflectionRoughnessCutoff(args.fValue);
|
||||
editor->main->config.GetSection("graphics").Set("reflection_roughness_cutoff", args.fValue);
|
||||
editor->main->config.Commit();
|
||||
});
|
||||
AddWidget(&reflectionsRoughnessCutoffSlider);
|
||||
|
||||
raytracedReflectionsCheckBox.Create("RT Reflections: ");
|
||||
raytracedReflectionsCheckBox.SetTooltip("Enable Ray Traced Reflections. Only if GPU supports raytracing.");
|
||||
raytracedReflectionsCheckBox.SetScriptTip("RenderPath3D::SetRaytracedReflectionsEnabled(bool value)");
|
||||
@@ -862,6 +887,52 @@ void GraphicsWindow::Create(EditorComponent* _editor)
|
||||
AddWidget(&raytracedReflectionsCheckBox);
|
||||
raytracedReflectionsCheckBox.SetEnabled(wi::graphics::GetDevice()->CheckCapability(GraphicsDeviceCapability::RAYTRACING));
|
||||
|
||||
raytracedReflectionsRangeSlider.Create(1.0f, 10000.0f, 1, 1000, "Range: ");
|
||||
raytracedReflectionsRangeSlider.SetTooltip("Set Reflection ray length for Ray traced reflections.");
|
||||
raytracedReflectionsRangeSlider.SetSize(XMFLOAT2(mod_wid, hei));
|
||||
raytracedReflectionsRangeSlider.SetPos(XMFLOAT2(x + 100, y += step));
|
||||
if (editor->main->config.GetSection("graphics").Has("rtreflection_range"))
|
||||
{
|
||||
editor->renderPath->setRaytracedReflectionsRange(editor->main->config.GetSection("graphics").GetFloat("rtreflection_range"));
|
||||
}
|
||||
raytracedReflectionsRangeSlider.OnSlide([=](wi::gui::EventArgs args) {
|
||||
editor->renderPath->setRaytracedReflectionsRange(args.fValue);
|
||||
editor->main->config.GetSection("graphics").Set("rtreflection_range", args.fValue);
|
||||
editor->main->config.Commit();
|
||||
});
|
||||
AddWidget(&raytracedReflectionsRangeSlider);
|
||||
raytracedReflectionsRangeSlider.SetEnabled(wi::graphics::GetDevice()->CheckCapability(GraphicsDeviceCapability::RAYTRACING));
|
||||
|
||||
raytracedDiffuseCheckBox.Create("RT Diffuse: ");
|
||||
raytracedDiffuseCheckBox.SetTooltip("Enable Ray Traced Diffuse. Only if GPU supports raytracing.\nThis effect computes single bounce diffuse with ray tracing per pixel.\nIf DDGI is enabled, it will make it multi bounce.");
|
||||
raytracedDiffuseCheckBox.SetScriptTip("RenderPath3D::SetRaytracedDiffuseEnabled(bool value)");
|
||||
raytracedDiffuseCheckBox.SetSize(XMFLOAT2(hei, hei));
|
||||
raytracedDiffuseCheckBox.SetPos(XMFLOAT2(x + 140, y));
|
||||
editor->renderPath->setRaytracedDiffuseEnabled(editor->main->config.GetSection("graphics").GetBool("raytraced_diffuse"));
|
||||
raytracedDiffuseCheckBox.OnClick([=](wi::gui::EventArgs args) {
|
||||
editor->renderPath->setRaytracedDiffuseEnabled(args.bValue);
|
||||
editor->main->config.GetSection("graphics").Set("raytraced_diffuse", args.bValue);
|
||||
editor->main->config.Commit();
|
||||
});
|
||||
AddWidget(&raytracedDiffuseCheckBox);
|
||||
raytracedDiffuseCheckBox.SetEnabled(wi::graphics::GetDevice()->CheckCapability(GraphicsDeviceCapability::RAYTRACING));
|
||||
|
||||
raytracedDiffuseRangeSlider.Create(1.0f, 100.0f, 1, 1000, "Range: ");
|
||||
raytracedDiffuseRangeSlider.SetTooltip("Set Reflection ray length for Ray traced diffuse.");
|
||||
raytracedDiffuseRangeSlider.SetSize(XMFLOAT2(mod_wid, hei));
|
||||
raytracedDiffuseRangeSlider.SetPos(XMFLOAT2(x + 100, y += step));
|
||||
if (editor->main->config.GetSection("graphics").Has("rtdiffuse_range"))
|
||||
{
|
||||
editor->renderPath->setRaytracedDiffuseRange(editor->main->config.GetSection("graphics").GetFloat("rtdiffuse_range"));
|
||||
}
|
||||
raytracedDiffuseRangeSlider.OnSlide([=](wi::gui::EventArgs args) {
|
||||
editor->renderPath->setRaytracedDiffuseRange(args.fValue);
|
||||
editor->main->config.GetSection("graphics").Set("rtdiffuse_range", args.fValue);
|
||||
editor->main->config.Commit();
|
||||
});
|
||||
AddWidget(&raytracedDiffuseRangeSlider);
|
||||
raytracedDiffuseRangeSlider.SetEnabled(wi::graphics::GetDevice()->CheckCapability(GraphicsDeviceCapability::RAYTRACING));
|
||||
|
||||
screenSpaceShadowsCheckBox.Create("Screen Shadows: ");
|
||||
screenSpaceShadowsCheckBox.SetTooltip("Enable screen space contact shadows. This can add small shadows details to shadow maps in screen space.");
|
||||
screenSpaceShadowsCheckBox.SetSize(XMFLOAT2(hei, hei));
|
||||
@@ -1477,7 +1548,11 @@ void GraphicsWindow::Update()
|
||||
aoRangeSlider.SetValue((float)editor->renderPath->getAORange());
|
||||
aoSampleCountSlider.SetValue((float)editor->renderPath->getAOSampleCount());
|
||||
ssrCheckBox.SetCheck(editor->renderPath->getSSREnabled());
|
||||
reflectionsRoughnessCutoffSlider.SetValue(editor->renderPath->getReflectionRoughnessCutoff());
|
||||
raytracedReflectionsCheckBox.SetCheck(editor->renderPath->getRaytracedReflectionEnabled());
|
||||
raytracedReflectionsRangeSlider.SetValue(editor->renderPath->getRaytracedReflectionsRange());
|
||||
raytracedDiffuseCheckBox.SetCheck(editor->renderPath->getRaytracedDiffuseEnabled());
|
||||
raytracedDiffuseRangeSlider.SetValue(editor->renderPath->getRaytracedDiffuseRange());
|
||||
screenSpaceShadowsCheckBox.SetCheck(wi::renderer::GetScreenSpaceShadowsEnabled());
|
||||
screenSpaceShadowsRangeSlider.SetValue((float)editor->renderPath->getScreenSpaceShadowRange());
|
||||
screenSpaceShadowsStepCountSlider.SetValue((float)editor->renderPath->getScreenSpaceShadowSampleCount());
|
||||
@@ -1652,6 +1727,7 @@ void GraphicsWindow::ResizeLayout()
|
||||
ddgiY.SetVisible(false);
|
||||
ddgiX.SetVisible(false);
|
||||
ddgiRayCountSlider.SetVisible(false);
|
||||
ddgiBlendSpeedSlider.SetVisible(false);
|
||||
ddgiSmoothBackfaceSlider.SetVisible(false);
|
||||
voxelRadianceDebugCheckBox.SetVisible(false);
|
||||
voxelRadianceCheckBox.SetVisible(false);
|
||||
@@ -1677,6 +1753,7 @@ void GraphicsWindow::ResizeLayout()
|
||||
ddgiY.SetVisible(true);
|
||||
ddgiX.SetVisible(true);
|
||||
ddgiRayCountSlider.SetVisible(true);
|
||||
ddgiBlendSpeedSlider.SetVisible(true);
|
||||
ddgiSmoothBackfaceSlider.SetVisible(true);
|
||||
ddgiSmoothBackfaceSlider.SetValue(editor->GetCurrentScene().ddgi.smooth_backface);
|
||||
voxelRadianceDebugCheckBox.SetVisible(true);
|
||||
@@ -1703,6 +1780,7 @@ void GraphicsWindow::ResizeLayout()
|
||||
ddgiY.SetPos(XMFLOAT2(ddgiZ.GetPos().x - ddgiY.GetSize().x - padding, ddgiZ.GetPos().y));
|
||||
ddgiX.SetPos(XMFLOAT2(ddgiY.GetPos().x - ddgiX.GetSize().x - padding, ddgiY.GetPos().y));
|
||||
add(ddgiRayCountSlider);
|
||||
add(ddgiBlendSpeedSlider);
|
||||
add(ddgiSmoothBackfaceSlider);
|
||||
|
||||
y += jump;
|
||||
@@ -1728,8 +1806,12 @@ void GraphicsWindow::ResizeLayout()
|
||||
add(aoPowerSlider);
|
||||
add(aoRangeSlider);
|
||||
add(aoSampleCountSlider);
|
||||
add_right(ssrCheckBox);
|
||||
add_right(raytracedReflectionsCheckBox);
|
||||
add_right(reflectionsRoughnessCutoffSlider);
|
||||
ssrCheckBox.SetPos(XMFLOAT2(reflectionsRoughnessCutoffSlider.GetPos().x - ssrCheckBox.GetSize().x - 80, reflectionsRoughnessCutoffSlider.GetPos().y));
|
||||
add_right(raytracedReflectionsRangeSlider);
|
||||
raytracedReflectionsCheckBox.SetPos(XMFLOAT2(raytracedReflectionsRangeSlider.GetPos().x - raytracedReflectionsCheckBox.GetSize().x - 80, raytracedReflectionsRangeSlider.GetPos().y));
|
||||
add_right(raytracedDiffuseRangeSlider);
|
||||
raytracedDiffuseCheckBox.SetPos(XMFLOAT2(raytracedDiffuseRangeSlider.GetPos().x - raytracedDiffuseCheckBox.GetSize().x - 80, raytracedDiffuseRangeSlider.GetPos().y));
|
||||
add_right(screenSpaceShadowsStepCountSlider);
|
||||
screenSpaceShadowsCheckBox.SetPos(XMFLOAT2(screenSpaceShadowsStepCountSlider.GetPos().x - screenSpaceShadowsCheckBox.GetSize().x - 80, screenSpaceShadowsStepCountSlider.GetPos().y));
|
||||
add_right(screenSpaceShadowsRangeSlider);
|
||||
|
||||
@@ -27,6 +27,7 @@ public:
|
||||
wi::gui::TextInputField ddgiY;
|
||||
wi::gui::TextInputField ddgiZ;
|
||||
wi::gui::Slider ddgiRayCountSlider;
|
||||
wi::gui::Slider ddgiBlendSpeedSlider;
|
||||
wi::gui::Slider ddgiSmoothBackfaceSlider;
|
||||
wi::gui::CheckBox voxelRadianceCheckBox;
|
||||
wi::gui::CheckBox voxelRadianceDebugCheckBox;
|
||||
@@ -61,6 +62,10 @@ public:
|
||||
wi::gui::Slider aoSampleCountSlider;
|
||||
wi::gui::CheckBox ssrCheckBox;
|
||||
wi::gui::CheckBox raytracedReflectionsCheckBox;
|
||||
wi::gui::Slider reflectionsRoughnessCutoffSlider;
|
||||
wi::gui::Slider raytracedReflectionsRangeSlider;
|
||||
wi::gui::CheckBox raytracedDiffuseCheckBox;
|
||||
wi::gui::Slider raytracedDiffuseRangeSlider;
|
||||
wi::gui::CheckBox screenSpaceShadowsCheckBox;
|
||||
wi::gui::Slider screenSpaceShadowsStepCountSlider;
|
||||
wi::gui::Slider screenSpaceShadowsRangeSlider;
|
||||
|
||||
@@ -51,6 +51,10 @@ wi::vector<ShaderEntry> shaders = {
|
||||
{"fsr_upscalingCS", wi::graphics::ShaderStage::CS},
|
||||
{"fsr_sharpenCS", wi::graphics::ShaderStage::CS},
|
||||
{"ssaoCS", wi::graphics::ShaderStage::CS},
|
||||
{"rtdiffuseCS", wi::graphics::ShaderStage::CS, wi::graphics::ShaderModel::SM_6_5},
|
||||
{"rtdiffuse_spatialCS", wi::graphics::ShaderStage::CS},
|
||||
{"rtdiffuse_temporalCS", wi::graphics::ShaderStage::CS},
|
||||
{"rtdiffuse_bilateralCS", wi::graphics::ShaderStage::CS},
|
||||
{"rtreflectionCS", wi::graphics::ShaderStage::CS, wi::graphics::ShaderModel::SM_6_5},
|
||||
{"ssr_tileMaxRoughness_horizontalCS", wi::graphics::ShaderStage::CS},
|
||||
{"ssr_tileMaxRoughness_verticalCS", wi::graphics::ShaderStage::CS},
|
||||
|
||||
@@ -17,6 +17,7 @@ struct DDGIPushConstants
|
||||
uint instanceInclusionMask;
|
||||
uint frameIndex;
|
||||
uint rayCount;
|
||||
float blendSpeed;
|
||||
};
|
||||
|
||||
struct DDGIRayData
|
||||
|
||||
@@ -41,6 +41,7 @@ struct Bloom
|
||||
#define lineardepth_inputresolution_rcp postprocess.params0.zw
|
||||
|
||||
static const uint SSR_TILESIZE = 32;
|
||||
#define ssr_roughness_cutoff postprocess.params0.z
|
||||
#define ssr_frame postprocess.params0.w
|
||||
|
||||
#define ssao_range postprocess.params0.x
|
||||
@@ -50,7 +51,11 @@ static const uint SSR_TILESIZE = 32;
|
||||
#define rtao_range ssao_range
|
||||
#define rtao_power ssao_power
|
||||
|
||||
#define rtdiffuse_range ssao_range
|
||||
#define rtdiffuse_frame ssr_frame
|
||||
|
||||
#define rtreflection_range ssao_range
|
||||
#define rtreflection_roughness_cutoff ssr_roughness_cutoff
|
||||
#define rtreflection_frame ssr_frame
|
||||
|
||||
static const uint POSTPROCESS_HBAO_THREADCOUNT = 320;
|
||||
|
||||
@@ -787,7 +787,7 @@ struct CameraCB
|
||||
|
||||
uint2 visibility_tilecount;
|
||||
uint visibility_tilecount_flat;
|
||||
uint padding;
|
||||
int texture_rtdiffuse_index;
|
||||
|
||||
int texture_primitiveID_index;
|
||||
int texture_depth_index;
|
||||
|
||||
@@ -946,6 +946,22 @@
|
||||
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Compute</ShaderType>
|
||||
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">4.0</ShaderModel>
|
||||
</FxCompile>
|
||||
<FxCompile Include="$(MSBuildThisFileDirectory)rtdiffuseCS.hlsl">
|
||||
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Compute</ShaderType>
|
||||
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">4.0</ShaderModel>
|
||||
</FxCompile>
|
||||
<FxCompile Include="$(MSBuildThisFileDirectory)rtdiffuse_bilateralCS.hlsl">
|
||||
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Compute</ShaderType>
|
||||
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">4.0</ShaderModel>
|
||||
</FxCompile>
|
||||
<FxCompile Include="$(MSBuildThisFileDirectory)rtdiffuse_spatialCS.hlsl">
|
||||
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Compute</ShaderType>
|
||||
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">4.0</ShaderModel>
|
||||
</FxCompile>
|
||||
<FxCompile Include="$(MSBuildThisFileDirectory)rtdiffuse_temporalCS.hlsl">
|
||||
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Compute</ShaderType>
|
||||
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">4.0</ShaderModel>
|
||||
</FxCompile>
|
||||
<FxCompile Include="$(MSBuildThisFileDirectory)rtreflectionCS.hlsl">
|
||||
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Compute</ShaderType>
|
||||
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">4.0</ShaderModel>
|
||||
|
||||
@@ -1064,6 +1064,18 @@
|
||||
<FxCompile Include="$(MSBuildThisFileDirectory)volumetricCloud_renderCS_capture_MSAA.hlsl">
|
||||
<Filter>CS</Filter>
|
||||
</FxCompile>
|
||||
<FxCompile Include="$(MSBuildThisFileDirectory)rtdiffuseCS.hlsl">
|
||||
<Filter>CS</Filter>
|
||||
</FxCompile>
|
||||
<FxCompile Include="$(MSBuildThisFileDirectory)rtdiffuse_spatialCS.hlsl">
|
||||
<Filter>CS</Filter>
|
||||
</FxCompile>
|
||||
<FxCompile Include="$(MSBuildThisFileDirectory)rtdiffuse_temporalCS.hlsl">
|
||||
<Filter>CS</Filter>
|
||||
</FxCompile>
|
||||
<FxCompile Include="$(MSBuildThisFileDirectory)rtdiffuse_bilateralCS.hlsl">
|
||||
<Filter>CS</Filter>
|
||||
</FxCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)ShaderInterop.h">
|
||||
|
||||
@@ -133,7 +133,7 @@ void main(uint3 GTid : SV_GroupThreadID, uint3 Gid : SV_GroupID, uint groupIndex
|
||||
|
||||
if (push.frameIndex > 0)
|
||||
{
|
||||
result = lerp(prev_result, result, 0.02);
|
||||
result = lerp(prev_result, result, push.blendSpeed);
|
||||
}
|
||||
|
||||
output[pixel_current] = result;
|
||||
|
||||
@@ -859,6 +859,13 @@ inline void TiledLighting(inout Surface surface, inout Lighting lighting, uint f
|
||||
}
|
||||
|
||||
#ifndef TRANSPARENT
|
||||
[branch]
|
||||
if ((surface.flags & SURFACE_FLAG_GI_APPLIED) == 0 && GetCamera().texture_rtdiffuse_index >= 0)
|
||||
{
|
||||
lighting.indirect.diffuse = bindless_textures[GetCamera().texture_rtdiffuse_index][surface.pixel].rgb * GetFrame().gi_boost;
|
||||
surface.flags |= SURFACE_FLAG_GI_APPLIED;
|
||||
}
|
||||
|
||||
[branch]
|
||||
if ((surface.flags & SURFACE_FLAG_GI_APPLIED) == 0 && GetFrame().options & OPTION_BIT_SURFELGI_ENABLED && GetCamera().texture_surfelgi_index >= 0 && surfel_cellvalid(surfel_cell(surface.P)))
|
||||
{
|
||||
|
||||
@@ -0,0 +1,216 @@
|
||||
#define RTAPI
|
||||
#define DISABLE_SOFT_SHADOWMAP
|
||||
#define DISABLE_TRANSPARENT_SHADOWMAP
|
||||
#define SURFACE_LOAD_MIPCONE
|
||||
|
||||
#include "globals.hlsli"
|
||||
#include "ShaderInterop_Postprocess.h"
|
||||
#include "raytracingHF.hlsli"
|
||||
#include "stochasticSSRHF.hlsli"
|
||||
#include "lightingHF.hlsli"
|
||||
#include "ShaderInterop_SurfelGI.h"
|
||||
#include "ShaderInterop_DDGI.h"
|
||||
|
||||
PUSHCONSTANT(postprocess, PostProcess);
|
||||
|
||||
RWTexture2D<float4> output_rayIndirectDiffuse : register(u0);
|
||||
|
||||
struct RayPayload
|
||||
{
|
||||
float3 data;
|
||||
};
|
||||
|
||||
[numthreads(8, 4, 1)]
|
||||
void main(uint2 DTid : SV_DispatchThreadID)
|
||||
{
|
||||
const float2 uv = ((float2)DTid.xy + 0.5) * postprocess.resolution_rcp;
|
||||
|
||||
const uint downsampleFactor = 2;
|
||||
|
||||
// This is necessary for accurate upscaling. This is so we don't reuse the same half-res pixels
|
||||
uint2 screenJitter = floor(blue_noise(uint2(0, 0)).xy * downsampleFactor);
|
||||
uint2 jitterPixel = screenJitter + DTid.xy * downsampleFactor;
|
||||
float2 jitterUV = (screenJitter + DTid.xy + 0.5f) * postprocess.resolution_rcp;
|
||||
|
||||
const float depth = texture_depth.SampleLevel(sampler_linear_clamp, jitterUV, 0);
|
||||
if (depth == 0)
|
||||
return;
|
||||
|
||||
const float lineardepth = texture_lineardepth.SampleLevel(sampler_linear_clamp, jitterUV, 0);
|
||||
const float roughness = 1;
|
||||
|
||||
const float3 N = decode_oct(texture_normal[jitterPixel]);
|
||||
const float3 P = reconstruct_position(jitterUV, depth);
|
||||
const float3 V = normalize(GetCamera().position - P);
|
||||
|
||||
RayPayload payload;
|
||||
payload.data = 0;
|
||||
|
||||
//const float2 bluenoise = blue_noise(DTid.xy).xy;
|
||||
//const float3 R = normalize(mul(hemispherepoint_cos(bluenoise.x, bluenoise.y), get_tangentspace(N)));
|
||||
|
||||
const uint samplecount = 1;
|
||||
for (uint i = 0; i < samplecount; ++i)
|
||||
{
|
||||
const float2 bluenoise = blue_noise(DTid.xy, (float)i / (float)samplecount).xy;
|
||||
const float3 R = normalize(mul(hemispherepoint_cos(bluenoise.x, bluenoise.y), get_tangentspace(N)));
|
||||
|
||||
RayDesc ray;
|
||||
ray.TMin = 0.01;
|
||||
ray.TMax = rtdiffuse_range;
|
||||
ray.Origin = P;
|
||||
ray.Direction = normalize(R);
|
||||
|
||||
const float minraycone = 0.05;
|
||||
RayCone raycone = RayCone::from_spread_angle(pixel_cone_spread_angle_from_image_height(postprocess.resolution.y));
|
||||
raycone = raycone.propagate(sqr(max(minraycone, roughness)), lineardepth * GetCamera().z_far);
|
||||
|
||||
float4 additive_dist = float4(0, 0, 0, FLT_MAX);
|
||||
|
||||
RayQuery<
|
||||
RAY_FLAG_SKIP_PROCEDURAL_PRIMITIVES
|
||||
> q;
|
||||
q.TraceRayInline(
|
||||
scene_acceleration_structure, // RaytracingAccelerationStructure AccelerationStructure
|
||||
0, // uint RayFlags
|
||||
asuint(postprocess.params1.x), // uint InstanceInclusionMask
|
||||
ray // RayDesc Ray
|
||||
);
|
||||
while (q.Proceed())
|
||||
{
|
||||
PrimitiveID prim;
|
||||
prim.primitiveIndex = q.CandidatePrimitiveIndex();
|
||||
prim.instanceIndex = q.CandidateInstanceID();
|
||||
prim.subsetIndex = q.CandidateGeometryIndex();
|
||||
|
||||
Surface surface;
|
||||
surface.init();
|
||||
surface.V = -ray.Direction;
|
||||
surface.raycone = raycone;
|
||||
surface.hit_depth = q.CandidateTriangleRayT();
|
||||
if (!surface.load(prim, q.CandidateTriangleBarycentrics()))
|
||||
break;
|
||||
|
||||
float alphatest = clamp(blue_noise(DTid.xy, q.CandidateTriangleRayT()).r, 0, 0.99);
|
||||
|
||||
if (surface.material.options & SHADERMATERIAL_OPTION_BIT_ADDITIVE)
|
||||
{
|
||||
additive_dist.xyz += surface.emissiveColor;
|
||||
additive_dist.w = min(additive_dist.w, q.CandidateTriangleRayT());
|
||||
}
|
||||
else if (surface.opacity - alphatest >= 0)
|
||||
{
|
||||
q.CommitNonOpaqueTriangleHit();
|
||||
}
|
||||
}
|
||||
|
||||
if (additive_dist.w <= q.CommittedRayT())
|
||||
{
|
||||
payload.data.xyz += max(0, additive_dist.xyz);
|
||||
}
|
||||
|
||||
if (q.CommittedStatus() != COMMITTED_TRIANGLE_HIT)
|
||||
{
|
||||
// miss:
|
||||
[branch]
|
||||
if (GetScene().ddgi.color_texture >= 0)
|
||||
{
|
||||
payload.data += ddgi_sample_irradiance(P, N);
|
||||
}
|
||||
else if (GetFrame().options & OPTION_BIT_SURFELGI_ENABLED && GetCamera().texture_surfelgi_index >= 0 && surfel_cellvalid(surfel_cell(P)))
|
||||
{
|
||||
payload.data += bindless_textures[GetCamera().texture_surfelgi_index][DTid.xy * 2].rgb * GetFrame().gi_boost;
|
||||
}
|
||||
else
|
||||
{
|
||||
payload.data.xyz += GetAmbient(q.WorldRayDirection());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// closest hit:
|
||||
PrimitiveID prim;
|
||||
prim.primitiveIndex = q.CommittedPrimitiveIndex();
|
||||
prim.instanceIndex = q.CommittedInstanceID();
|
||||
prim.subsetIndex = q.CommittedGeometryIndex();
|
||||
|
||||
Surface surface;
|
||||
surface.init();
|
||||
if (!q.CommittedTriangleFrontFace())
|
||||
{
|
||||
surface.flags |= SURFACE_FLAG_BACKFACE;
|
||||
}
|
||||
surface.V = -ray.Direction;
|
||||
surface.raycone = raycone;
|
||||
surface.hit_depth = q.CommittedRayT();
|
||||
if (!surface.load(prim, q.CommittedTriangleBarycentrics()))
|
||||
return;
|
||||
|
||||
surface.pixel = DTid.xy;
|
||||
surface.screenUV = surface.pixel * postprocess.resolution_rcp.xy;
|
||||
|
||||
if (surface.material.IsUnlit())
|
||||
{
|
||||
payload.data.xyz = surface.albedo + surface.emissiveColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Light sampling:
|
||||
surface.P = q.WorldRayOrigin() + q.WorldRayDirection() * q.CommittedRayT();
|
||||
surface.V = -q.WorldRayDirection();
|
||||
surface.update();
|
||||
|
||||
Lighting lighting;
|
||||
lighting.create(0, 0, 0, 0);
|
||||
|
||||
[loop]
|
||||
for (uint iterator = 0; iterator < GetFrame().lightarray_count; iterator++)
|
||||
{
|
||||
ShaderEntity light = load_entity(GetFrame().lightarray_offset + iterator);
|
||||
if ((light.layerMask & surface.material.layerMask) == 0)
|
||||
continue;
|
||||
|
||||
if (light.GetFlags() & ENTITY_FLAG_LIGHT_STATIC)
|
||||
{
|
||||
continue; // static lights will be skipped (they are used in lightmap baking)
|
||||
}
|
||||
|
||||
switch (light.GetType())
|
||||
{
|
||||
case ENTITY_TYPE_DIRECTIONALLIGHT:
|
||||
{
|
||||
light_directional(light, surface, lighting);
|
||||
}
|
||||
break;
|
||||
case ENTITY_TYPE_POINTLIGHT:
|
||||
{
|
||||
light_point(light, surface, lighting);
|
||||
}
|
||||
break;
|
||||
case ENTITY_TYPE_SPOTLIGHT:
|
||||
{
|
||||
light_spot(light, surface, lighting);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
lighting.indirect.specular += surface.emissiveColor;
|
||||
|
||||
[branch]
|
||||
if (GetScene().ddgi.color_texture >= 0)
|
||||
{
|
||||
lighting.indirect.diffuse = ddgi_sample_irradiance(surface.P, surface.N);
|
||||
}
|
||||
|
||||
float4 color = 0;
|
||||
ApplyLighting(surface, lighting, color);
|
||||
payload.data.xyz += color.rgb;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
payload.data /= (float)samplecount;
|
||||
|
||||
output_rayIndirectDiffuse[DTid.xy] = float4(payload.data.xyz, 1);
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
#include "globals.hlsli"
|
||||
#include "stochasticSSRHF.hlsli"
|
||||
#include "ShaderInterop_Postprocess.h"
|
||||
|
||||
PUSHCONSTANT(postprocess, PostProcess);
|
||||
|
||||
Texture2D<float4> texture_temporal : register(t0);
|
||||
Texture2D<float> texture_resolve_variance : register(t1);
|
||||
|
||||
RWTexture2D<float4> output : register(u0);
|
||||
|
||||
static const float depthThreshold = 10000.0;
|
||||
static const float normalThreshold = 1.0;
|
||||
static const float varianceEstimateThreshold = 0.015; // Larger variance values use stronger blur
|
||||
static const float varianceExitThreshold = 0.0025; // Variance needs to be higher than this value to accept blur
|
||||
static const uint2 bilateralMinMaxRadius = uint2(4, 8); // Chosen by variance
|
||||
|
||||
#define BILATERAL_SIGMA 0.9
|
||||
|
||||
[numthreads(POSTPROCESS_BLOCKSIZE, POSTPROCESS_BLOCKSIZE, 1)]
|
||||
void main(uint3 DTid : SV_DispatchThreadID)
|
||||
{
|
||||
const float depth = texture_depth[DTid.xy];
|
||||
|
||||
float2 direction = postprocess.params0.xy;
|
||||
|
||||
const float linearDepth = texture_lineardepth[DTid.xy];
|
||||
const float3 N = decode_oct(texture_normal[DTid.xy]);
|
||||
|
||||
const float2 uv = (DTid.xy + 0.5) * postprocess.resolution_rcp;
|
||||
float4 outputColor = texture_temporal.SampleLevel(sampler_linear_clamp, uv, 0);
|
||||
|
||||
//output[DTid.xy] = outputColor;
|
||||
//return;
|
||||
|
||||
float variance = texture_resolve_variance.SampleLevel(sampler_linear_clamp, uv, 0);
|
||||
bool strongBlur = variance > varianceEstimateThreshold;
|
||||
|
||||
float radius = strongBlur ? bilateralMinMaxRadius.y : bilateralMinMaxRadius.x;
|
||||
|
||||
float sigma = radius * BILATERAL_SIGMA;
|
||||
int effectiveRadius = min(sigma * 2.0, radius);
|
||||
|
||||
//if (variance > varianceExitThreshold && effectiveRadius > 0)
|
||||
{
|
||||
float2 uv = (DTid.xy + 0.5f) * postprocess.resolution_rcp;
|
||||
float3 P = reconstruct_position(uv, depth);
|
||||
|
||||
float4 result = 0;
|
||||
float weightSum = 0.0f;
|
||||
|
||||
for (int r = -effectiveRadius; r <= effectiveRadius; r++)
|
||||
{
|
||||
const int2 sampleCoord = DTid.xy + (direction * r); // Left to right diameter directionally
|
||||
|
||||
if (all(sampleCoord >= int2(0, 0) && sampleCoord < (int2) postprocess.resolution))
|
||||
{
|
||||
const float sampleDepth = texture_depth[sampleCoord];
|
||||
|
||||
float2 sampleUV = (sampleCoord + 0.5) * postprocess.resolution_rcp;
|
||||
const float4 sampleColor = texture_temporal.SampleLevel(sampler_linear_clamp, sampleUV, 0);
|
||||
|
||||
const float3 sampleN = decode_oct(texture_normal[sampleCoord]);
|
||||
|
||||
float3 sampleP = reconstruct_position(sampleUV, sampleDepth);
|
||||
|
||||
{
|
||||
float3 dq = P - sampleP;
|
||||
float planeError = max(abs(dot(dq, sampleN)), abs(dot(dq, N)));
|
||||
float relativeDepthDifference = planeError / (linearDepth * GetCamera().z_far);
|
||||
float bilateralDepthWeight = exp(-sqr(relativeDepthDifference) * depthThreshold);
|
||||
|
||||
float normalError = pow(saturate(dot(sampleN, N)), 4.0);
|
||||
float bilateralNormalWeight = saturate(1.0 - (1.0 - normalError) * normalThreshold);
|
||||
|
||||
float bilateralWeight = bilateralDepthWeight * bilateralNormalWeight;
|
||||
|
||||
float gaussian = exp(-sqr(r / sigma));
|
||||
float weight = (r == 0) ? 1.0 : gaussian * bilateralWeight; // Skip center gaussian peak
|
||||
|
||||
result += sampleColor * weight;
|
||||
weightSum += weight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result /= weightSum;
|
||||
outputColor = result;
|
||||
}
|
||||
|
||||
output[DTid.xy] = outputColor;
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
#include "globals.hlsli"
|
||||
#include "brdf.hlsli"
|
||||
#include "stochasticSSRHF.hlsli"
|
||||
#include "ShaderInterop_Postprocess.h"
|
||||
|
||||
Texture2D<float4> texture_rayIndirectDiffuse : register(t0);
|
||||
|
||||
RWTexture2D<float4> texture_resolve : register(u0);
|
||||
RWTexture2D<float> texture_resolve_variance : register(u1);
|
||||
|
||||
static const float resolveSpatialSize = 8.0;
|
||||
static const uint resolveSpatialReconstructionCount = 4.0f;
|
||||
|
||||
// Weighted incremental variance
|
||||
// https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance
|
||||
void GetWeightedVariance(float4 sampleColor, float weight, float weightSum, inout float mean, inout float S)
|
||||
{
|
||||
float luminance = Luminance(sampleColor.rgb);
|
||||
float oldMean = mean;
|
||||
mean += weight / weightSum * (luminance - oldMean);
|
||||
S += weight * (luminance - oldMean) * (luminance - mean);
|
||||
}
|
||||
|
||||
// modified from 'globals.hlsli' with random shift
|
||||
// idx : iteration index
|
||||
// num : number of iterations in total
|
||||
// random : 16 bit random sequence
|
||||
inline float2 hammersley2d_random(uint idx, uint num, uint2 random)
|
||||
{
|
||||
uint bits = idx;
|
||||
bits = (bits << 16u) | (bits >> 16u);
|
||||
bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
|
||||
bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
|
||||
bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
|
||||
bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
|
||||
const float radicalInverse_VdC = float(bits ^ random.y) * 2.3283064365386963e-10; // / 0x100000000
|
||||
|
||||
// ... & 0xffff) / (1 << 16): limit to 65536 then range 0 - 1
|
||||
return float2(frac(float(idx) / float(num) + float(random.x & 0xffff) / (1 << 16)), radicalInverse_VdC); // frac since we only want range [0; 1[
|
||||
}
|
||||
|
||||
uint baseHash(uint3 p)
|
||||
{
|
||||
p = 1103515245u * ((p.xyz >> 1u) ^ (p.yzx));
|
||||
uint h32 = 1103515245u * ((p.x ^ p.z) ^ (p.y >> 3u));
|
||||
return h32 ^ (h32 >> 16);
|
||||
}
|
||||
|
||||
// Great quality hash with 3D input
|
||||
// based on: https://www.shadertoy.com/view/Xt3cDn
|
||||
uint3 hash33(uint3 x)
|
||||
{
|
||||
uint n = baseHash(x);
|
||||
return uint3(n, n * 16807u, n * 48271u); //see: http://random.mat.sbg.ac.at/results/karl/server/node4.html
|
||||
}
|
||||
|
||||
[numthreads(POSTPROCESS_BLOCKSIZE, POSTPROCESS_BLOCKSIZE, 1)]
|
||||
void main(uint3 DTid : SV_DispatchThreadID)
|
||||
{
|
||||
const uint2 tracingCoord = DTid.xy;
|
||||
|
||||
const float depth = texture_depth[DTid.xy * 2];
|
||||
|
||||
const float farplane = GetCamera().z_far;
|
||||
const float lineardepth = texture_lineardepth[DTid.xy * 2] * farplane;
|
||||
|
||||
// Everthing in world space:
|
||||
const float3 N = decode_oct(texture_normal[DTid.xy * 2]);
|
||||
|
||||
float4 result = 0.0f;
|
||||
float weightSum = 0.0f;
|
||||
|
||||
float mean = 0.0f;
|
||||
float S = 0.0f;
|
||||
|
||||
float closestRayLength = 0.0f;
|
||||
|
||||
const uint sampleCount = resolveSpatialReconstructionCount;
|
||||
const uint2 random = hash33(uint3(DTid.xy, GetFrame().frame_count)).xy;
|
||||
|
||||
for (int i = 0; i < sampleCount; i++)
|
||||
{
|
||||
float2 offset = (hammersley2d_random(i, sampleCount, random) - 0.5) * resolveSpatialSize;
|
||||
|
||||
int2 neighborTracingCoord = tracingCoord + offset;
|
||||
int2 neighborCoord = DTid.xy * 2 + offset;
|
||||
|
||||
float neighbor_lineardepth = texture_lineardepth[neighborCoord] * farplane;
|
||||
if (neighbor_lineardepth < farplane)
|
||||
{
|
||||
float weight = 1;
|
||||
weight *= 1 - saturate(abs(lineardepth - neighbor_lineardepth));
|
||||
|
||||
float4 sampleColor = texture_rayIndirectDiffuse[neighborTracingCoord];
|
||||
sampleColor.rgb *= rcp(1 + Luminance(sampleColor.rgb));
|
||||
|
||||
result += sampleColor * weight;
|
||||
weightSum += weight;
|
||||
|
||||
GetWeightedVariance(sampleColor, weight, weightSum, mean, S);
|
||||
}
|
||||
}
|
||||
|
||||
result /= weightSum;
|
||||
result.rgb *= rcp(1 - Luminance(result.rgb));
|
||||
|
||||
// Population variance
|
||||
float resolveVariance = S / weightSum;
|
||||
|
||||
texture_resolve[DTid.xy] = max(result, 0.00001f);
|
||||
texture_resolve_variance[DTid.xy] = resolveVariance;
|
||||
}
|
||||
@@ -0,0 +1,226 @@
|
||||
#include "globals.hlsli"
|
||||
#include "stochasticSSRHF.hlsli"
|
||||
#include "ShaderInterop_Postprocess.h"
|
||||
|
||||
PUSHCONSTANT(postprocess, PostProcess);
|
||||
|
||||
Texture2D<float4> texture_color_current : register(t0);
|
||||
Texture2D<float4> texture_color_history : register(t1);
|
||||
Texture2D<float> texture_variance_current : register(t2);
|
||||
Texture2D<float> texture_variance_history : register(t3);
|
||||
|
||||
RWTexture2D<float4> output_color : register(u0);
|
||||
RWTexture2D<float> output_variance : register(u1);
|
||||
|
||||
static const float temporalResponse = 0.98;
|
||||
static const float temporalScale = 0.9;
|
||||
static const float disocclusionDepthWeight = 1.0f;
|
||||
static const float disocclusionThreshold = 0.89f;
|
||||
static const float varianceTemporalResponse = 0.6f;
|
||||
|
||||
float2 CalculateReprojectionBuffer(float2 uv, float depth)
|
||||
{
|
||||
float x = uv.x * 2 - 1;
|
||||
float y = (1 - uv.y) * 2 - 1;
|
||||
float2 screenPosition = float2(x, y);
|
||||
|
||||
float4 thisClip = float4(screenPosition, depth, 1);
|
||||
|
||||
float4 prevClip = mul(GetCamera().inverse_view_projection, thisClip);
|
||||
prevClip = mul(GetCamera().previous_view_projection, prevClip);
|
||||
|
||||
float2 prevScreen = prevClip.xy / prevClip.w;
|
||||
|
||||
float2 screenVelocity = screenPosition - prevScreen;
|
||||
float2 prevScreenPosition = screenPosition - screenVelocity;
|
||||
|
||||
return prevScreenPosition * float2(0.5, -0.5) + 0.5;
|
||||
}
|
||||
|
||||
float GetDisocclusion(float depth, float depthHistory)
|
||||
{
|
||||
float lineardepthCurrent = compute_lineardepth(depth);
|
||||
float lineardepthHistory = compute_lineardepth(depthHistory);
|
||||
|
||||
float disocclusion = 1.0
|
||||
//* exp(-abs(1.0 - max(0.0, dot(normal, normalHistory))) * disocclusionNormalWeight) // Potential normal check if necessary
|
||||
* exp(-abs(lineardepthHistory - lineardepthCurrent) / lineardepthCurrent * disocclusionDepthWeight);
|
||||
|
||||
return disocclusion;
|
||||
}
|
||||
|
||||
float4 SamplePreviousColor(float2 prevUV, float2 size, float depth, out float disocclusion, out float2 prevUVSample)
|
||||
{
|
||||
prevUVSample = prevUV;
|
||||
|
||||
float4 previousColor = texture_color_history.SampleLevel(sampler_linear_clamp, prevUVSample, 0);
|
||||
float previousDepth = texture_depth_history.SampleLevel(sampler_point_clamp, prevUVSample, 0);
|
||||
|
||||
disocclusion = GetDisocclusion(depth, previousDepth);
|
||||
if (disocclusion > disocclusionThreshold) // Good enough
|
||||
{
|
||||
return previousColor;
|
||||
}
|
||||
|
||||
// Try to find the closest sample in the vicinity if we are not convinced of a disocclusion
|
||||
if (disocclusion < disocclusionThreshold)
|
||||
{
|
||||
float2 closestUV = prevUVSample;
|
||||
float2 dudv = rcp(size);
|
||||
|
||||
const int searchRadius = 1;
|
||||
for (int y = -searchRadius; y <= searchRadius; y++)
|
||||
{
|
||||
for (int x = -searchRadius; x <= searchRadius; x++)
|
||||
{
|
||||
int2 offset = int2(x, y);
|
||||
float2 sampleUV = prevUVSample + offset * dudv;
|
||||
|
||||
float samplePreviousDepth = texture_depth_history.SampleLevel(sampler_point_clamp, sampleUV, 0);
|
||||
|
||||
float weight = GetDisocclusion(depth, samplePreviousDepth);
|
||||
if (weight > disocclusion)
|
||||
{
|
||||
disocclusion = weight;
|
||||
closestUV = sampleUV;
|
||||
prevUVSample = closestUV;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
previousColor = texture_color_history.SampleLevel(sampler_linear_clamp, prevUVSample, 0);
|
||||
}
|
||||
|
||||
// Bilinear interpolation on fallback - near edges
|
||||
if (disocclusion < disocclusionThreshold)
|
||||
{
|
||||
float2 weight = frac(prevUVSample * size + 0.5);
|
||||
|
||||
// Bilinear weights
|
||||
float weights[4] =
|
||||
{
|
||||
(1 - weight.x) * (1 - weight.y),
|
||||
weight.x * (1 - weight.y),
|
||||
(1 - weight.x) * weight.y,
|
||||
weight.x * weight.y
|
||||
};
|
||||
|
||||
float4 previousColorResult = 0;
|
||||
float previousDepthResult = 0;
|
||||
float weightSum = 0;
|
||||
|
||||
uint2 prevCoord = uint2(size * prevUVSample - 0.5);
|
||||
uint2 offsets[4] = { uint2(0, 0), uint2(1, 0), uint2(0, 1), uint2(1, 1) };
|
||||
|
||||
for (uint i = 0; i < 4; i++)
|
||||
{
|
||||
uint2 sampleCoord = prevCoord + offsets[i];
|
||||
|
||||
previousColorResult += weights[i] * texture_color_history[sampleCoord];
|
||||
previousDepthResult += weights[i] * texture_depth_history[sampleCoord];
|
||||
|
||||
weightSum += weights[i];
|
||||
}
|
||||
|
||||
previousColorResult /= max(weightSum, 0.00001);
|
||||
previousDepthResult /= max(weightSum, 0.00001);
|
||||
|
||||
previousColor = previousColorResult;
|
||||
disocclusion = GetDisocclusion(depth, previousDepthResult);
|
||||
}
|
||||
|
||||
disocclusion = disocclusion < disocclusionThreshold ? 0.0 : disocclusion;
|
||||
return previousColor;
|
||||
}
|
||||
|
||||
[numthreads(POSTPROCESS_BLOCKSIZE, POSTPROCESS_BLOCKSIZE, 1)]
|
||||
void main(uint3 Gid : SV_GroupID, uint3 GTid : SV_GroupThreadID, uint3 DTid : SV_DispatchThreadID)
|
||||
{
|
||||
if ((uint) rtdiffuse_frame == 0)
|
||||
{
|
||||
float4 color = texture_color_current[DTid.xy];
|
||||
output_color[DTid.xy] = color;
|
||||
return;
|
||||
}
|
||||
|
||||
const float depth = texture_depth[DTid.xy * 2];
|
||||
|
||||
// Welford's online algorithm:
|
||||
// https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance
|
||||
|
||||
float4 m1 = 0.0;
|
||||
float4 m2 = 0.0;
|
||||
for (int x = -1; x <= 1; x++)
|
||||
{
|
||||
for (int y = -1; y <= 1; y++)
|
||||
{
|
||||
int2 offset = int2(x, y);
|
||||
int2 coord = DTid.xy + offset;
|
||||
|
||||
float4 sampleColor = texture_color_current[coord];
|
||||
|
||||
m1 += sampleColor;
|
||||
m2 += sampleColor * sampleColor;
|
||||
}
|
||||
}
|
||||
|
||||
float4 mean = m1 / 9.0;
|
||||
float4 variance = (m2 / 9.0) - (mean * mean);
|
||||
float4 stddev = sqrt(max(variance, 0.0f));
|
||||
|
||||
float2 velocity = texture_velocity[DTid.xy * 2];
|
||||
|
||||
float2 uv = (DTid.xy + 0.5f) * postprocess.resolution_rcp;
|
||||
|
||||
float2 prevUVVelocity = uv + velocity;
|
||||
float2 prevUVReflectionHit = CalculateReprojectionBuffer(uv, depth);
|
||||
|
||||
float4 previousColorVelocity = texture_color_history.SampleLevel(sampler_linear_clamp, prevUVVelocity, 0);
|
||||
float4 previousColorReflectionHit = texture_color_history.SampleLevel(sampler_linear_clamp, prevUVReflectionHit, 0);
|
||||
|
||||
float previousDistanceVelocity = abs(Luminance(previousColorVelocity.rgb) - Luminance(mean.rgb));
|
||||
float previousDistanceReflectionHit = abs(Luminance(previousColorReflectionHit.rgb) - Luminance(mean.rgb));
|
||||
|
||||
float2 prevUV = previousDistanceVelocity < previousDistanceReflectionHit ? prevUVVelocity : prevUVReflectionHit;
|
||||
|
||||
float disocclusion = 0.0;
|
||||
float2 prevUVSample = 0.0;
|
||||
float4 previousColor = SamplePreviousColor(prevUV, postprocess.resolution, depth, disocclusion, prevUVSample);
|
||||
|
||||
float4 currentColor = texture_color_current[DTid.xy];
|
||||
float4 resultColor = currentColor;
|
||||
|
||||
// Disocclusion fallback: color
|
||||
if (disocclusion > disocclusionThreshold && is_saturated(prevUVSample))
|
||||
{
|
||||
// Color box clamp
|
||||
float4 colorMin = mean - temporalScale * stddev;
|
||||
float4 colorMax = mean + temporalScale * stddev;
|
||||
previousColor = clamp(previousColor, colorMin, colorMax);
|
||||
|
||||
resultColor = lerp(currentColor, previousColor, temporalResponse);
|
||||
}
|
||||
#if 0 // Debug
|
||||
else
|
||||
{
|
||||
resultColor = float4(1, 0, 0, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
float currentVariance = texture_variance_current[DTid.xy];
|
||||
float varianceResponse = varianceTemporalResponse;
|
||||
|
||||
// Disocclusion fallback: variance
|
||||
if (disocclusion < disocclusionThreshold || !is_saturated(prevUVSample))
|
||||
{
|
||||
// Apply white for variance on occlusion. This helps to hide artifacts from temporal
|
||||
varianceResponse = 0.0f;
|
||||
currentVariance = 1.0f;
|
||||
}
|
||||
|
||||
float previousVariance = texture_variance_history.SampleLevel(sampler_linear_clamp, prevUVSample, 0);
|
||||
float resultVariance = lerp(currentVariance, previousVariance, varianceResponse);
|
||||
|
||||
output_color[DTid.xy] = max(0, resultColor);
|
||||
output_variance[DTid.xy] = max(0, resultVariance);
|
||||
}
|
||||
@@ -37,7 +37,7 @@ void main(uint2 DTid : SV_DispatchThreadID)
|
||||
const float lineardepth = texture_lineardepth.SampleLevel(sampler_linear_clamp, jitterUV, 0);
|
||||
const float roughness = texture_roughness[jitterPixel];
|
||||
|
||||
if (!NeedReflection(roughness, depth))
|
||||
if (!NeedReflection(roughness, depth, rtreflection_roughness_cutoff))
|
||||
{
|
||||
output_rayIndirectSpecular[DTid.xy] = 0;
|
||||
output_rayDirectionPDF[DTid.xy] = 0;
|
||||
|
||||
@@ -43,7 +43,7 @@ void RTReflection_Raygen()
|
||||
const float depth = texture_depth.SampleLevel(sampler_linear_clamp, jitterUV, 0);
|
||||
const float roughness = texture_roughness[jitterPixel];
|
||||
|
||||
if (!NeedReflection(roughness, depth))
|
||||
if (!NeedReflection(roughness, depth, rtreflection_roughness_cutoff))
|
||||
{
|
||||
output_rayIndirectSpecular[DTid.xy] = 0;
|
||||
output_rayDirectionPDF[DTid.xy] = 0;
|
||||
|
||||
@@ -28,7 +28,7 @@ void main(uint3 DTid : SV_DispatchThreadID)
|
||||
const float depth = texture_depth[DTid.xy];
|
||||
const float roughness = texture_roughness[DTid.xy];
|
||||
|
||||
if (!NeedReflection(roughness, depth))
|
||||
if (!NeedReflection(roughness, depth, ssr_roughness_cutoff))
|
||||
{
|
||||
output[DTid.xy] = texture_temporal[DTid.xy];
|
||||
return;
|
||||
@@ -75,7 +75,7 @@ void main(uint3 DTid : SV_DispatchThreadID)
|
||||
float3 sampleP = reconstruct_position(sampleUV, sampleDepth);
|
||||
|
||||
// Don't let invalid roughness samples interfere
|
||||
if (NeedReflection(sampleRoughness, sampleDepth))
|
||||
if (NeedReflection(sampleRoughness, sampleDepth, ssr_roughness_cutoff))
|
||||
{
|
||||
float3 dq = P - sampleP;
|
||||
float planeError = max(abs(dot(dq, sampleN)), abs(dot(dq, N)));
|
||||
|
||||
@@ -250,7 +250,7 @@ void main(uint3 Gid : SV_GroupID, uint3 GTid : SV_GroupThreadID)
|
||||
float depth = texture_depth_hierarchy[screenJitter + pixel].r;
|
||||
float roughness = texture_roughness[jitterPixel];
|
||||
|
||||
if (!NeedReflection(roughness, depth))
|
||||
if (!NeedReflection(roughness, depth, ssr_roughness_cutoff))
|
||||
{
|
||||
output_rayIndirectSpecular[pixel] = 0.0;
|
||||
output_rayDirectionPDF[pixel] = 0.0;
|
||||
|
||||
@@ -92,7 +92,7 @@ void main(uint3 DTid : SV_DispatchThreadID)
|
||||
const float depth = texture_depth[DTid.xy];
|
||||
const float roughness = texture_roughness[DTid.xy];
|
||||
|
||||
if (!NeedReflection(roughness, depth))
|
||||
if (!NeedReflection(roughness, depth, ssr_roughness_cutoff))
|
||||
{
|
||||
texture_resolve[DTid.xy] = texture_rayIndirectSpecular[tracingCoord];
|
||||
texture_resolve_variance[DTid.xy] = 0.0;
|
||||
|
||||
@@ -146,7 +146,7 @@ void main(uint3 Gid : SV_GroupID, uint3 GTid : SV_GroupThreadID, uint3 DTid : SV
|
||||
const float depth = texture_depth[DTid.xy];
|
||||
const float roughness = texture_roughness[DTid.xy];
|
||||
|
||||
if (!NeedReflection(roughness, depth))
|
||||
if (!NeedReflection(roughness, depth, ssr_roughness_cutoff))
|
||||
{
|
||||
output_color[DTid.xy] = texture_color_current[DTid.xy];
|
||||
output_variance[DTid.xy] = 0.0;
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
#include "stochasticSSRHF.hlsli"
|
||||
#include "ShaderInterop_Postprocess.h"
|
||||
|
||||
PUSHCONSTANT(postprocess, PostProcess);
|
||||
|
||||
Texture2D<float2> tile_minmax_roughness_horizontal : register(t0);
|
||||
|
||||
RWByteAddressBuffer tile_tracing_statistics : register(u0);
|
||||
@@ -43,7 +45,7 @@ void main(uint3 DTid : SV_DispatchThreadID)
|
||||
tile_tracing_statistics.InterlockedAdd(TILE_STATISTICS_OFFSET_EXPENSIVE, 1, prevCount);
|
||||
tiles_tracing_expensive[prevCount] = tile;
|
||||
}
|
||||
else if (maxRoughness > SSRRoughnessCheap && minRoughness < ReflectionMaxRoughness)
|
||||
else if (maxRoughness > SSRRoughnessCheap && minRoughness < ssr_roughness_cutoff)
|
||||
{
|
||||
tile_tracing_statistics.InterlockedAdd(TILE_STATISTICS_OFFSET_CHEAP, 1, prevCount);
|
||||
tiles_tracing_cheap[prevCount] = tile;
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#define GGX_IMPORTANCE_SAMPLE_BIAS 0.1
|
||||
|
||||
// Shared Reflection settings:
|
||||
static const float ReflectionMaxRoughness = 0.6f;
|
||||
|
||||
uint2 GetReflectionIndirectDispatchCoord(uint3 Gid, uint3 GTid, StructuredBuffer<uint> tiles, uint downsample)
|
||||
{
|
||||
@@ -23,9 +22,9 @@ uint2 GetReflectionIndirectDispatchCoord(uint3 Gid, uint3 GTid, StructuredBuffer
|
||||
return subtile_upperleft + unflatten2D(GTid.x, POSTPROCESS_BLOCKSIZE);
|
||||
}
|
||||
|
||||
bool NeedReflection(float roughness, float depth)
|
||||
bool NeedReflection(float roughness, float depth, float roughness_cutoff)
|
||||
{
|
||||
return (roughness < ReflectionMaxRoughness) && (depth > 0.0);
|
||||
return (roughness < roughness_cutoff) && (depth > 0.0);
|
||||
}
|
||||
|
||||
// Brian Karis, Epic Games "Real Shading in Unreal Engine 4"
|
||||
|
||||
@@ -282,6 +282,10 @@ namespace wi::enums
|
||||
CSTYPE_POSTPROCESS_MSAO_BLURUPSAMPLE_PREMIN,
|
||||
CSTYPE_POSTPROCESS_MSAO_BLURUPSAMPLE_PREMIN_BLENDOUT,
|
||||
CSTYPE_POSTPROCESS_RTREFLECTION,
|
||||
CSTYPE_POSTPROCESS_RTDIFFUSE,
|
||||
CSTYPE_POSTPROCESS_RTDIFFUSE_SPATIAL,
|
||||
CSTYPE_POSTPROCESS_RTDIFFUSE_TEMPORAL,
|
||||
CSTYPE_POSTPROCESS_RTDIFFUSE_BILATERAL,
|
||||
CSTYPE_POSTPROCESS_SSR_TILEMAXROUGHNESS_HORIZONTAL,
|
||||
CSTYPE_POSTPROCESS_SSR_TILEMAXROUGHNESS_VERTICAL,
|
||||
CSTYPE_POSTPROCESS_SSR_KICKJOBS,
|
||||
|
||||
@@ -492,6 +492,7 @@ void RenderPath3D::ResizeBuffers()
|
||||
setAO(ao);
|
||||
setSSREnabled(ssrEnabled);
|
||||
setRaytracedReflectionsEnabled(raytracedReflectionsEnabled);
|
||||
setRaytracedDiffuseEnabled(raytracedDiffuseEnabled);
|
||||
setFSREnabled(fsrEnabled);
|
||||
|
||||
RenderPath2D::ResizeBuffers();
|
||||
@@ -521,7 +522,9 @@ void RenderPath3D::Update(float dt)
|
||||
wi::renderer::GetDDGIEnabled() ||
|
||||
(hw_raytrace && wi::renderer::GetRaytracedShadowsEnabled()) ||
|
||||
(hw_raytrace && getAO() == AO_RTAO) ||
|
||||
(hw_raytrace && getRaytracedReflectionEnabled()))
|
||||
(hw_raytrace && getRaytracedReflectionEnabled()) ||
|
||||
(hw_raytrace && getRaytracedDiffuseEnabled())
|
||||
)
|
||||
{
|
||||
scene->SetAccelerationStructureUpdateRequested(true);
|
||||
}
|
||||
@@ -588,6 +591,10 @@ void RenderPath3D::Update(float dt)
|
||||
{
|
||||
rtSSR = {};
|
||||
}
|
||||
if (!getRaytracedDiffuseEnabled())
|
||||
{
|
||||
rtRaytracedDiffuse = {};
|
||||
}
|
||||
if (getAO() == AO_DISABLED)
|
||||
{
|
||||
rtAO = {};
|
||||
@@ -599,6 +606,7 @@ void RenderPath3D::Update(float dt)
|
||||
wi::renderer::GetTemporalAAEnabled() ||
|
||||
getSSREnabled() ||
|
||||
getRaytracedReflectionEnabled() ||
|
||||
getRaytracedDiffuseEnabled() ||
|
||||
wi::renderer::GetRaytracedShadowsEnabled() ||
|
||||
getAO() == AO::AO_RTAO ||
|
||||
wi::renderer::GetVariableRateShadingClassification()
|
||||
@@ -700,6 +708,7 @@ void RenderPath3D::Update(float dt)
|
||||
camera->texture_ao_index = device->GetDescriptorIndex(&rtAO, SubresourceType::SRV);
|
||||
camera->texture_ssr_index = device->GetDescriptorIndex(&rtSSR, SubresourceType::SRV);
|
||||
camera->texture_rtshadow_index = device->GetDescriptorIndex(&rtShadow, SubresourceType::SRV);
|
||||
camera->texture_rtdiffuse_index = device->GetDescriptorIndex(&rtRaytracedDiffuse, SubresourceType::SRV);
|
||||
camera->texture_surfelgi_index = device->GetDescriptorIndex(&surfelGIResources.result, SubresourceType::SRV);
|
||||
|
||||
camera_reflection.canvas.init(*this);
|
||||
@@ -874,6 +883,7 @@ void RenderPath3D::Render() const
|
||||
else if(
|
||||
getSSREnabled() ||
|
||||
getRaytracedReflectionEnabled() ||
|
||||
getRaytracedDiffuseEnabled() ||
|
||||
wi::renderer::GetScreenSpaceShadowsEnabled() ||
|
||||
wi::renderer::GetRaytracedShadowsEnabled()
|
||||
)
|
||||
@@ -1104,9 +1114,22 @@ void RenderPath3D::Render() const
|
||||
*scene,
|
||||
rtSSR,
|
||||
cmd,
|
||||
getRaytracedReflectionsRange(),
|
||||
getReflectionRoughnessCutoff(),
|
||||
instanceInclusionMask_RTReflection
|
||||
);
|
||||
}
|
||||
if (getRaytracedDiffuseEnabled())
|
||||
{
|
||||
wi::renderer::Postprocess_RTDiffuse(
|
||||
rtdiffuseResources,
|
||||
*scene,
|
||||
rtRaytracedDiffuse,
|
||||
cmd,
|
||||
getRaytracedDiffuseRange(),
|
||||
instanceInclusionMask_RTDiffuse
|
||||
);
|
||||
}
|
||||
|
||||
// Depth buffers were created on COMPUTE queue, so make them available for pixel shaders here:
|
||||
{
|
||||
@@ -1327,7 +1350,8 @@ void RenderPath3D::RenderSSR(CommandList cmd) const
|
||||
ssrResources,
|
||||
rtSceneCopy,
|
||||
rtSSR,
|
||||
cmd
|
||||
cmd,
|
||||
getReflectionRoughnessCutoff()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1794,6 +1818,32 @@ void RenderPath3D::setRaytracedReflectionsEnabled(bool value)
|
||||
}
|
||||
}
|
||||
|
||||
void RenderPath3D::setRaytracedDiffuseEnabled(bool value)
|
||||
{
|
||||
raytracedDiffuseEnabled = value;
|
||||
|
||||
if (value)
|
||||
{
|
||||
GraphicsDevice* device = wi::graphics::GetDevice();
|
||||
XMUINT2 internalResolution = GetInternalResolution();
|
||||
|
||||
TextureDesc desc;
|
||||
desc.bind_flags = BindFlag::SHADER_RESOURCE | BindFlag::UNORDERED_ACCESS;
|
||||
desc.format = Format::R16G16B16A16_FLOAT;
|
||||
desc.width = internalResolution.x;
|
||||
desc.height = internalResolution.y;
|
||||
device->CreateTexture(&desc, nullptr, &rtRaytracedDiffuse);
|
||||
device->SetName(&rtRaytracedDiffuse, "rtRaytracedDiffuse");
|
||||
|
||||
wi::renderer::CreateRTDiffuseResources(rtdiffuseResources, internalResolution);
|
||||
}
|
||||
else
|
||||
{
|
||||
rtRaytracedDiffuse = {};
|
||||
rtdiffuseResources = {};
|
||||
}
|
||||
}
|
||||
|
||||
void RenderPath3D::setFSREnabled(bool value)
|
||||
{
|
||||
fsrEnabled = value;
|
||||
|
||||
@@ -40,11 +40,15 @@ namespace wi
|
||||
float eyeadaptionRate = 1;
|
||||
float fsrSharpness = 1.0f;
|
||||
float lightShaftsStrength = 0.2f;
|
||||
float raytracedDiffuseRange = 10;
|
||||
float raytracedReflectionsRange = 10000.0f;
|
||||
float reflectionRoughnessCutoff = 0.6f;
|
||||
|
||||
AO ao = AO_DISABLED;
|
||||
bool fxaaEnabled = false;
|
||||
bool ssrEnabled = false;
|
||||
bool raytracedReflectionsEnabled = false;
|
||||
bool raytracedDiffuseEnabled = false;
|
||||
bool reflectionsEnabled = true;
|
||||
bool shadowsEnabled = true;
|
||||
bool bloomEnabled = true;
|
||||
@@ -72,6 +76,7 @@ namespace wi
|
||||
wi::graphics::Texture rtPrimitiveID_render; // can be MSAA
|
||||
wi::graphics::Texture rtVelocity; // optional R16G16_FLOAT
|
||||
wi::graphics::Texture rtReflection; // contains the scene rendered for planar reflections
|
||||
wi::graphics::Texture rtRaytracedDiffuse; // raytraced diffuse screen space texture
|
||||
wi::graphics::Texture rtSSR; // standard screen-space reflection results
|
||||
wi::graphics::Texture rtSceneCopy; // contains the rendered scene that can be fed into transparent pass for distortion effect
|
||||
wi::graphics::Texture rtSceneCopy_tmp; // temporary for gaussian mipchain
|
||||
@@ -117,6 +122,7 @@ namespace wi
|
||||
wi::renderer::SSAOResources ssaoResources;
|
||||
wi::renderer::MSAOResources msaoResources;
|
||||
wi::renderer::RTAOResources rtaoResources;
|
||||
wi::renderer::RTDiffuseResources rtdiffuseResources;
|
||||
wi::renderer::RTReflectionResources rtreflectionResources;
|
||||
wi::renderer::SSRResources ssrResources;
|
||||
wi::renderer::RTShadowResources rtshadowResources;
|
||||
@@ -161,6 +167,7 @@ namespace wi
|
||||
|
||||
uint8_t instanceInclusionMask_RTAO = 0xFF;
|
||||
uint8_t instanceInclusionMask_RTShadow = 0xFF;
|
||||
uint8_t instanceInclusionMask_RTDiffuse = 0xFF;
|
||||
uint8_t instanceInclusionMask_RTReflection = 0xFF;
|
||||
uint8_t instanceInclusionMask_SurfelGI = 0xFF;
|
||||
uint8_t instanceInclusionMask_Lightmap = 0xFF;
|
||||
@@ -189,10 +196,14 @@ namespace wi
|
||||
constexpr float getEyeAdaptionRate() const { return eyeadaptionRate; }
|
||||
constexpr float getFSRSharpness() const { return fsrSharpness; }
|
||||
constexpr float getLightShaftsStrength() const { return lightShaftsStrength; }
|
||||
constexpr float getRaytracedDiffuseRange() const { return raytracedDiffuseRange; }
|
||||
constexpr float getRaytracedReflectionsRange() const { return raytracedReflectionsRange; }
|
||||
constexpr float getReflectionRoughnessCutoff() const { return reflectionRoughnessCutoff; }
|
||||
|
||||
constexpr bool getAOEnabled() const { return ao != AO_DISABLED; }
|
||||
constexpr AO getAO() const { return ao; }
|
||||
constexpr bool getSSREnabled() const { return ssrEnabled; }
|
||||
constexpr bool getRaytracedDiffuseEnabled() const { return raytracedDiffuseEnabled; }
|
||||
constexpr bool getRaytracedReflectionEnabled() const { return raytracedReflectionsEnabled; }
|
||||
constexpr bool getShadowsEnabled() const { return shadowsEnabled; }
|
||||
constexpr bool getReflectionsEnabled() const { return reflectionsEnabled; }
|
||||
@@ -233,10 +244,14 @@ namespace wi
|
||||
constexpr void setEyeAdaptionRate(float value) { eyeadaptionRate = value; }
|
||||
constexpr void setFSRSharpness(float value) { fsrSharpness = value; }
|
||||
constexpr void setLightShaftsStrength(float value) { lightShaftsStrength = value; }
|
||||
constexpr void setRaytracedDiffuseRange(float value) { raytracedDiffuseRange = value; }
|
||||
constexpr void setRaytracedReflectionsRange(float value) { raytracedReflectionsRange = value; }
|
||||
constexpr void setReflectionRoughnessCutoff(float value) { reflectionRoughnessCutoff = value; }
|
||||
|
||||
void setAO(AO value);
|
||||
void setSSREnabled(bool value);
|
||||
void setRaytracedReflectionsEnabled(bool value);
|
||||
void setRaytracedDiffuseEnabled(bool value);
|
||||
constexpr void setShadowsEnabled(bool value) { shadowsEnabled = value; }
|
||||
constexpr void setReflectionsEnabled(bool value) { reflectionsEnabled = value; }
|
||||
constexpr void setFXAAEnabled(bool value) { fxaaEnabled = value; }
|
||||
|
||||
@@ -28,6 +28,7 @@ namespace wi::lua
|
||||
lunamethod(RenderPath3D_BindLua, SetAO),
|
||||
lunamethod(RenderPath3D_BindLua, SetAOPower),
|
||||
lunamethod(RenderPath3D_BindLua, SetSSREnabled),
|
||||
lunamethod(RenderPath3D_BindLua, SetRaytracedDiffuseEnabled),
|
||||
lunamethod(RenderPath3D_BindLua, SetRaytracedReflectionsEnabled),
|
||||
lunamethod(RenderPath3D_BindLua, SetShadowsEnabled),
|
||||
lunamethod(RenderPath3D_BindLua, SetReflectionsEnabled),
|
||||
@@ -102,6 +103,19 @@ namespace wi::lua
|
||||
wi::lua::SError(L, "SetSSREnabled(bool value) not enough arguments!");
|
||||
return 0;
|
||||
}
|
||||
int RenderPath3D_BindLua::SetRaytracedDiffuseEnabled(lua_State* L)
|
||||
{
|
||||
if (component == nullptr)
|
||||
{
|
||||
wi::lua::SError(L, "SetRaytracedDiffuseEnabled(bool value) component is null!");
|
||||
return 0;
|
||||
}
|
||||
if (wi::lua::SGetArgCount(L) > 0)
|
||||
((RenderPath3D*)component)->setRaytracedDiffuseEnabled(wi::lua::SGetBool(L, 1));
|
||||
else
|
||||
wi::lua::SError(L, "SetRaytracedDiffuseEnabled(bool value) not enough arguments!");
|
||||
return 0;
|
||||
}
|
||||
int RenderPath3D_BindLua::SetRaytracedReflectionsEnabled(lua_State* L)
|
||||
{
|
||||
if (component == nullptr)
|
||||
|
||||
@@ -32,6 +32,7 @@ namespace wi::lua
|
||||
int SetAO(lua_State* L);
|
||||
int SetAOPower(lua_State* L);
|
||||
int SetSSREnabled(lua_State* L);
|
||||
int SetRaytracedDiffuseEnabled(lua_State* L);
|
||||
int SetRaytracedReflectionsEnabled(lua_State* L);
|
||||
int SetShadowsEnabled(lua_State* L);
|
||||
int SetReflectionsEnabled(lua_State* L);
|
||||
|
||||
+319
-6
@@ -99,6 +99,7 @@ SURFEL_DEBUG SURFELGI_DEBUG = SURFEL_DEBUG_NONE;
|
||||
bool DDGI_ENABLED = false;
|
||||
bool DDGI_DEBUG_ENABLED = false;
|
||||
uint32_t DDGI_RAYCOUNT = 128u;
|
||||
float DDGI_BLEND_SPEED = 0.02f;
|
||||
float GI_BOOST = 1.0f;
|
||||
std::atomic<size_t> SHADER_ERRORS{ 0 };
|
||||
std::atomic<size_t> SHADER_MISSING{ 0 };
|
||||
@@ -1037,6 +1038,11 @@ void LoadShaders()
|
||||
|
||||
if (device->CheckCapability(GraphicsDeviceCapability::RAYTRACING))
|
||||
{
|
||||
wi::jobsystem::Execute(ctx, [](wi::jobsystem::JobArgs args) { LoadShader(ShaderStage::CS, shaders[CSTYPE_POSTPROCESS_RTDIFFUSE], "rtdiffuseCS.cso", ShaderModel::SM_6_5); });
|
||||
wi::jobsystem::Execute(ctx, [](wi::jobsystem::JobArgs args) { LoadShader(ShaderStage::CS, shaders[CSTYPE_POSTPROCESS_RTDIFFUSE_SPATIAL], "rtdiffuse_spatialCS.cso"); });
|
||||
wi::jobsystem::Execute(ctx, [](wi::jobsystem::JobArgs args) { LoadShader(ShaderStage::CS, shaders[CSTYPE_POSTPROCESS_RTDIFFUSE_TEMPORAL], "rtdiffuse_temporalCS.cso"); });
|
||||
wi::jobsystem::Execute(ctx, [](wi::jobsystem::JobArgs args) { LoadShader(ShaderStage::CS, shaders[CSTYPE_POSTPROCESS_RTDIFFUSE_BILATERAL], "rtdiffuse_bilateralCS.cso"); });
|
||||
|
||||
wi::jobsystem::Execute(ctx, [](wi::jobsystem::JobArgs args) { LoadShader(ShaderStage::CS, shaders[CSTYPE_POSTPROCESS_RTREFLECTION], "rtreflectionCS.cso", ShaderModel::SM_6_5); });
|
||||
|
||||
wi::jobsystem::Execute(ctx, [](wi::jobsystem::JobArgs args) { LoadShader(ShaderStage::CS, shaders[CSTYPE_POSTPROCESS_RTSHADOW], "rtshadowCS.cso", ShaderModel::SM_6_5); });
|
||||
@@ -7970,6 +7976,7 @@ void BindCameraCB(
|
||||
cb.texture_ao_index = camera.texture_ao_index;
|
||||
cb.texture_ssr_index = camera.texture_ssr_index;
|
||||
cb.texture_rtshadow_index = camera.texture_rtshadow_index;
|
||||
cb.texture_rtdiffuse_index = camera.texture_rtdiffuse_index;
|
||||
cb.texture_surfelgi_index = camera.texture_surfelgi_index;
|
||||
cb.texture_depth_index_prev = camera_previous.texture_depth_index;
|
||||
|
||||
@@ -8903,6 +8910,7 @@ void DDGI(
|
||||
push.instanceInclusionMask = instanceInclusionMask;
|
||||
push.frameIndex = scene.ddgi.frame_index;
|
||||
push.rayCount = std::min(GetDDGIRayCount(), DDGI_MAX_RAYCOUNT);
|
||||
push.blendSpeed = GetDDGIBlendSpeed();
|
||||
|
||||
// Raytracing:
|
||||
{
|
||||
@@ -10225,6 +10233,294 @@ void Postprocess_RTAO(
|
||||
wi::profiler::EndRange(prof_range);
|
||||
device->EventEnd(cmd);
|
||||
}
|
||||
void CreateRTDiffuseResources(RTDiffuseResources& res, XMUINT2 resolution)
|
||||
{
|
||||
res.frame = 0;
|
||||
|
||||
TextureDesc desc;
|
||||
desc.type = TextureDesc::Type::TEXTURE_2D;
|
||||
desc.width = resolution.x / 2;
|
||||
desc.height = resolution.y / 2;
|
||||
desc.bind_flags = BindFlag::SHADER_RESOURCE | BindFlag::UNORDERED_ACCESS;
|
||||
desc.layout = ResourceState::SHADER_RESOURCE_COMPUTE;
|
||||
|
||||
desc.format = Format::R11G11B10_FLOAT;
|
||||
device->CreateTexture(&desc, nullptr, &res.texture_rayIndirectDiffuse);
|
||||
|
||||
desc.format = Format::R11G11B10_FLOAT;
|
||||
device->CreateTexture(&desc, nullptr, &res.texture_spatial);
|
||||
device->CreateTexture(&desc, nullptr, &res.texture_temporal[0]);
|
||||
device->CreateTexture(&desc, nullptr, &res.texture_temporal[1]);
|
||||
desc.format = Format::R16_FLOAT;
|
||||
device->CreateTexture(&desc, nullptr, &res.texture_spatial_variance);
|
||||
device->CreateTexture(&desc, nullptr, &res.texture_temporal_variance[0]);
|
||||
device->CreateTexture(&desc, nullptr, &res.texture_temporal_variance[1]);
|
||||
|
||||
desc.format = Format::R11G11B10_FLOAT;
|
||||
desc.width = resolution.x;
|
||||
desc.height = resolution.y;
|
||||
device->CreateTexture(&desc, nullptr, &res.texture_bilateral_temp);
|
||||
}
|
||||
void Postprocess_RTDiffuse(
|
||||
const RTDiffuseResources& res,
|
||||
const Scene& scene,
|
||||
const Texture& output,
|
||||
CommandList cmd,
|
||||
float range,
|
||||
uint8_t instanceInclusionMask
|
||||
)
|
||||
{
|
||||
if (!device->CheckCapability(GraphicsDeviceCapability::RAYTRACING))
|
||||
return;
|
||||
|
||||
if (!scene.TLAS.IsValid() && !scene.BVH.IsValid())
|
||||
return;
|
||||
|
||||
device->EventBegin("Postprocess_RTDiffuse", cmd);
|
||||
auto profilerRange = wi::profiler::BeginRangeGPU("RTDiffuse", cmd);
|
||||
|
||||
BindCommonResources(cmd);
|
||||
|
||||
const TextureDesc& desc = output.desc;
|
||||
|
||||
// Render half-res:
|
||||
PostProcess postprocess;
|
||||
postprocess.resolution.x = desc.width / 2;
|
||||
postprocess.resolution.y = desc.height / 2;
|
||||
postprocess.resolution_rcp.x = 1.0f / postprocess.resolution.x;
|
||||
postprocess.resolution_rcp.y = 1.0f / postprocess.resolution.y;
|
||||
rtdiffuse_range = range;
|
||||
rtdiffuse_frame = (float)res.frame;
|
||||
std::memcpy(&postprocess.params1.x, &instanceInclusionMask, sizeof(instanceInclusionMask));
|
||||
|
||||
{
|
||||
device->EventBegin("RTDiffuse Raytrace pass", cmd);
|
||||
|
||||
device->BindComputeShader(&shaders[CSTYPE_POSTPROCESS_RTDIFFUSE], cmd);
|
||||
|
||||
device->PushConstants(&postprocess, sizeof(postprocess), cmd);
|
||||
|
||||
const GPUResource* uavs[] = {
|
||||
&res.texture_rayIndirectDiffuse,
|
||||
};
|
||||
device->BindUAVs(uavs, 0, arraysize(uavs), cmd);
|
||||
|
||||
{
|
||||
GPUBarrier barriers[] = {
|
||||
GPUBarrier::Image(&res.texture_rayIndirectDiffuse, res.texture_rayIndirectDiffuse.desc.layout, ResourceState::UNORDERED_ACCESS),
|
||||
};
|
||||
device->Barrier(barriers, arraysize(barriers), cmd);
|
||||
}
|
||||
|
||||
device->Dispatch(
|
||||
(res.texture_rayIndirectDiffuse.GetDesc().width + 7) / 8,
|
||||
(res.texture_rayIndirectDiffuse.GetDesc().height + 3) / 4,
|
||||
1,
|
||||
cmd
|
||||
);
|
||||
|
||||
{
|
||||
GPUBarrier barriers[] = {
|
||||
GPUBarrier::Memory(),
|
||||
GPUBarrier::Image(&res.texture_rayIndirectDiffuse, ResourceState::UNORDERED_ACCESS, res.texture_rayIndirectDiffuse.desc.layout),
|
||||
};
|
||||
device->Barrier(barriers, arraysize(barriers), cmd);
|
||||
}
|
||||
|
||||
device->EventEnd(cmd);
|
||||
}
|
||||
|
||||
// Spatial pass:
|
||||
{
|
||||
device->EventBegin("RTDiffuse - spatial filter", cmd);
|
||||
device->BindComputeShader(&shaders[CSTYPE_POSTPROCESS_RTDIFFUSE_SPATIAL], cmd);
|
||||
|
||||
const GPUResource* resarray[] = {
|
||||
&res.texture_rayIndirectDiffuse,
|
||||
};
|
||||
device->BindResources(resarray, 0, arraysize(resarray), cmd);
|
||||
|
||||
const GPUResource* uavs[] = {
|
||||
&res.texture_spatial,
|
||||
&res.texture_spatial_variance,
|
||||
};
|
||||
device->BindUAVs(uavs, 0, arraysize(uavs), cmd);
|
||||
|
||||
{
|
||||
GPUBarrier barriers[] = {
|
||||
GPUBarrier::Image(&res.texture_spatial, res.texture_spatial.desc.layout, ResourceState::UNORDERED_ACCESS),
|
||||
GPUBarrier::Image(&res.texture_spatial_variance, res.texture_spatial_variance.desc.layout, ResourceState::UNORDERED_ACCESS),
|
||||
};
|
||||
device->Barrier(barriers, arraysize(barriers), cmd);
|
||||
}
|
||||
|
||||
device->Dispatch(
|
||||
(res.texture_spatial.GetDesc().width + POSTPROCESS_BLOCKSIZE - 1) / POSTPROCESS_BLOCKSIZE,
|
||||
(res.texture_spatial.GetDesc().height + POSTPROCESS_BLOCKSIZE - 1) / POSTPROCESS_BLOCKSIZE,
|
||||
1,
|
||||
cmd
|
||||
);
|
||||
|
||||
{
|
||||
GPUBarrier barriers[] = {
|
||||
GPUBarrier::Image(&res.texture_spatial, ResourceState::UNORDERED_ACCESS, res.texture_spatial.desc.layout),
|
||||
GPUBarrier::Image(&res.texture_spatial_variance, ResourceState::UNORDERED_ACCESS, res.texture_spatial_variance.desc.layout),
|
||||
};
|
||||
device->Barrier(barriers, arraysize(barriers), cmd);
|
||||
}
|
||||
|
||||
device->EventEnd(cmd);
|
||||
}
|
||||
|
||||
int temporal_output = res.frame % 2;
|
||||
int temporal_history = 1 - temporal_output;
|
||||
|
||||
// Temporal pass:
|
||||
{
|
||||
device->EventBegin("RTDiffuse temporal filter", cmd);
|
||||
device->BindComputeShader(&shaders[CSTYPE_POSTPROCESS_RTDIFFUSE_TEMPORAL], cmd);
|
||||
|
||||
device->PushConstants(&postprocess, sizeof(postprocess), cmd);
|
||||
|
||||
const GPUResource* resarray[] = {
|
||||
&res.texture_spatial,
|
||||
&res.texture_temporal[temporal_history],
|
||||
&res.texture_spatial_variance,
|
||||
&res.texture_temporal_variance[temporal_history],
|
||||
};
|
||||
device->BindResources(resarray, 0, arraysize(resarray), cmd);
|
||||
|
||||
const GPUResource* uavs[] = {
|
||||
&res.texture_temporal[temporal_output],
|
||||
&res.texture_temporal_variance[temporal_output],
|
||||
};
|
||||
device->BindUAVs(uavs, 0, arraysize(uavs), cmd);
|
||||
|
||||
{
|
||||
GPUBarrier barriers[] = {
|
||||
GPUBarrier::Image(&res.texture_temporal[temporal_output], res.texture_temporal[temporal_output].desc.layout, ResourceState::UNORDERED_ACCESS),
|
||||
GPUBarrier::Image(&res.texture_temporal_variance[temporal_output], res.texture_temporal_variance[temporal_output].desc.layout, ResourceState::UNORDERED_ACCESS),
|
||||
};
|
||||
device->Barrier(barriers, arraysize(barriers), cmd);
|
||||
}
|
||||
|
||||
device->Dispatch(
|
||||
(res.texture_temporal[temporal_output].GetDesc().width + POSTPROCESS_BLOCKSIZE - 1) / POSTPROCESS_BLOCKSIZE,
|
||||
(res.texture_temporal[temporal_output].GetDesc().height + POSTPROCESS_BLOCKSIZE - 1) / POSTPROCESS_BLOCKSIZE,
|
||||
1,
|
||||
cmd
|
||||
);
|
||||
|
||||
{
|
||||
GPUBarrier barriers[] = {
|
||||
GPUBarrier::Memory(),
|
||||
GPUBarrier::Image(&res.texture_temporal[temporal_output], ResourceState::UNORDERED_ACCESS, res.texture_temporal[temporal_output].desc.layout),
|
||||
GPUBarrier::Image(&res.texture_temporal_variance[temporal_output], ResourceState::UNORDERED_ACCESS, res.texture_temporal_variance[temporal_output].desc.layout),
|
||||
};
|
||||
device->Barrier(barriers, arraysize(barriers), cmd);
|
||||
}
|
||||
|
||||
device->EventEnd(cmd);
|
||||
}
|
||||
|
||||
// Full res:
|
||||
postprocess.resolution.x = desc.width;
|
||||
postprocess.resolution.y = desc.height;
|
||||
postprocess.resolution_rcp.x = 1.0f / postprocess.resolution.x;
|
||||
postprocess.resolution_rcp.y = 1.0f / postprocess.resolution.y;
|
||||
|
||||
// Bilateral blur pass:
|
||||
{
|
||||
device->EventBegin("RTDiffuse - bilateral filter", cmd);
|
||||
device->BindComputeShader(&shaders[CSTYPE_POSTPROCESS_RTDIFFUSE_BILATERAL], cmd);
|
||||
|
||||
// Horizontal:
|
||||
{
|
||||
postprocess.params0.x = 1;
|
||||
postprocess.params0.y = 0;
|
||||
device->PushConstants(&postprocess, sizeof(postprocess), cmd);
|
||||
|
||||
const GPUResource* resarray[] = {
|
||||
&res.texture_temporal[temporal_output],
|
||||
&res.texture_temporal_variance[temporal_output],
|
||||
};
|
||||
device->BindResources(resarray, 0, arraysize(resarray), cmd);
|
||||
|
||||
const GPUResource* uavs[] = {
|
||||
&res.texture_bilateral_temp,
|
||||
};
|
||||
device->BindUAVs(uavs, 0, arraysize(uavs), cmd);
|
||||
|
||||
{
|
||||
GPUBarrier barriers[] = {
|
||||
GPUBarrier::Image(&res.texture_bilateral_temp, res.texture_bilateral_temp.desc.layout, ResourceState::UNORDERED_ACCESS),
|
||||
};
|
||||
device->Barrier(barriers, arraysize(barriers), cmd);
|
||||
}
|
||||
|
||||
device->Dispatch(
|
||||
(res.texture_bilateral_temp.GetDesc().width + POSTPROCESS_BLOCKSIZE - 1) / POSTPROCESS_BLOCKSIZE,
|
||||
(res.texture_bilateral_temp.GetDesc().height + POSTPROCESS_BLOCKSIZE - 1) / POSTPROCESS_BLOCKSIZE,
|
||||
1,
|
||||
cmd
|
||||
);
|
||||
|
||||
{
|
||||
GPUBarrier barriers[] = {
|
||||
GPUBarrier::Memory(),
|
||||
GPUBarrier::Image(&res.texture_bilateral_temp, ResourceState::UNORDERED_ACCESS, res.texture_bilateral_temp.desc.layout),
|
||||
};
|
||||
device->Barrier(barriers, arraysize(barriers), cmd);
|
||||
}
|
||||
}
|
||||
|
||||
// Vertical:
|
||||
{
|
||||
postprocess.params0.x = 0;
|
||||
postprocess.params0.y = 1;
|
||||
device->PushConstants(&postprocess, sizeof(postprocess), cmd);
|
||||
|
||||
const GPUResource* resarray[] = {
|
||||
&res.texture_bilateral_temp,
|
||||
&res.texture_temporal_variance[temporal_output],
|
||||
};
|
||||
device->BindResources(resarray, 0, arraysize(resarray), cmd);
|
||||
|
||||
const GPUResource* uavs[] = {
|
||||
&output,
|
||||
};
|
||||
device->BindUAVs(uavs, 0, arraysize(uavs), cmd);
|
||||
|
||||
{
|
||||
GPUBarrier barriers[] = {
|
||||
GPUBarrier::Image(&output, output.desc.layout, ResourceState::UNORDERED_ACCESS),
|
||||
};
|
||||
device->Barrier(barriers, arraysize(barriers), cmd);
|
||||
}
|
||||
|
||||
device->Dispatch(
|
||||
(output.GetDesc().width + POSTPROCESS_BLOCKSIZE - 1) / POSTPROCESS_BLOCKSIZE,
|
||||
(output.GetDesc().height + POSTPROCESS_BLOCKSIZE - 1) / POSTPROCESS_BLOCKSIZE,
|
||||
1,
|
||||
cmd
|
||||
);
|
||||
|
||||
{
|
||||
GPUBarrier barriers[] = {
|
||||
GPUBarrier::Image(&output, ResourceState::UNORDERED_ACCESS, output.desc.layout),
|
||||
};
|
||||
device->Barrier(barriers, arraysize(barriers), cmd);
|
||||
}
|
||||
}
|
||||
|
||||
device->EventEnd(cmd);
|
||||
}
|
||||
|
||||
res.frame++;
|
||||
|
||||
wi::profiler::EndRange(profilerRange);
|
||||
device->EventEnd(cmd);
|
||||
}
|
||||
void CreateRTReflectionResources(RTReflectionResources& res, XMUINT2 resolution)
|
||||
{
|
||||
res.frame = 0;
|
||||
@@ -10262,6 +10558,7 @@ void Postprocess_RTReflection(
|
||||
const Texture& output,
|
||||
CommandList cmd,
|
||||
float range,
|
||||
float roughnessCutoff,
|
||||
uint8_t instanceInclusionMask
|
||||
)
|
||||
{
|
||||
@@ -10285,6 +10582,7 @@ void Postprocess_RTReflection(
|
||||
postprocess.resolution_rcp.x = 1.0f / postprocess.resolution.x;
|
||||
postprocess.resolution_rcp.y = 1.0f / postprocess.resolution.y;
|
||||
rtreflection_range = range;
|
||||
rtreflection_roughness_cutoff = roughnessCutoff;
|
||||
rtreflection_frame = (float)res.frame;
|
||||
std::memcpy(&postprocess.params1.x, &instanceInclusionMask, sizeof(instanceInclusionMask));
|
||||
|
||||
@@ -10642,7 +10940,8 @@ void Postprocess_SSR(
|
||||
const SSRResources& res,
|
||||
const Texture& input,
|
||||
const Texture& output,
|
||||
CommandList cmd
|
||||
CommandList cmd,
|
||||
float roughnessCutoff
|
||||
)
|
||||
{
|
||||
device->EventBegin("Postprocess_SSR", cmd);
|
||||
@@ -10651,6 +10950,10 @@ void Postprocess_SSR(
|
||||
|
||||
BindCommonResources(cmd);
|
||||
|
||||
PostProcess postprocess;
|
||||
ssr_roughness_cutoff = roughnessCutoff;
|
||||
ssr_frame = (float)res.frame;
|
||||
|
||||
// Compute tile classification (horizontal):
|
||||
{
|
||||
device->EventBegin("SSR Tile Classification - Horizontal", cmd);
|
||||
@@ -10690,6 +10993,7 @@ void Postprocess_SSR(
|
||||
{
|
||||
device->EventBegin("SSR Tile Classification - Vertical", cmd);
|
||||
device->BindComputeShader(&shaders[CSTYPE_POSTPROCESS_SSR_TILEMAXROUGHNESS_VERTICAL], cmd);
|
||||
device->PushConstants(&postprocess, sizeof(postprocess), cmd);
|
||||
|
||||
const GPUResource* resarray[] = {
|
||||
&res.texture_tile_minmax_roughness_horizontal,
|
||||
@@ -10754,8 +11058,6 @@ void Postprocess_SSR(
|
||||
device->EventEnd(cmd);
|
||||
}
|
||||
|
||||
PostProcess postprocess;
|
||||
|
||||
// Depth hierarchy:
|
||||
{
|
||||
device->EventBegin("SSR Depth hierarchy pass", cmd);
|
||||
@@ -10843,14 +11145,14 @@ void Postprocess_SSR(
|
||||
postprocess.resolution.y = desc.height / 2;
|
||||
postprocess.resolution_rcp.x = 1.0f / postprocess.resolution.x;
|
||||
postprocess.resolution_rcp.y = 1.0f / postprocess.resolution.y;
|
||||
ssr_roughness_cutoff = roughnessCutoff;
|
||||
ssr_frame = (float)res.frame;
|
||||
|
||||
// Factor to scale ratio between hierarchy and trace pass
|
||||
postprocess.params1.x = (float)postprocess.resolution.x / (float)res.texture_depth_hierarchy.GetDesc().width;
|
||||
postprocess.params1.y = (float)postprocess.resolution.y / (float)res.texture_depth_hierarchy.GetDesc().height;
|
||||
postprocess.params1.z = 1.0f / postprocess.params1.x;
|
||||
postprocess.params1.w = 1.0f / postprocess.params1.y;
|
||||
ssr_frame = (float)res.frame;
|
||||
device->PushConstants(&postprocess, sizeof(postprocess), cmd);
|
||||
|
||||
// Raytrace pass:
|
||||
{
|
||||
@@ -10888,9 +11190,11 @@ void Postprocess_SSR(
|
||||
device->DispatchIndirect(&res.buffer_tile_tracing_statistics, INDIRECT_OFFSET_EARLYEXIT, cmd);
|
||||
|
||||
device->BindComputeShader(&shaders[CSTYPE_POSTPROCESS_SSR_RAYTRACE_CHEAP], cmd);
|
||||
device->PushConstants(&postprocess, sizeof(postprocess), cmd);
|
||||
device->DispatchIndirect(&res.buffer_tile_tracing_statistics, INDIRECT_OFFSET_CHEAP, cmd);
|
||||
|
||||
device->BindComputeShader(&shaders[CSTYPE_POSTPROCESS_SSR_RAYTRACE], cmd);
|
||||
device->PushConstants(&postprocess, sizeof(postprocess), cmd);
|
||||
device->DispatchIndirect(&res.buffer_tile_tracing_statistics, INDIRECT_OFFSET_EXPENSIVE, cmd);
|
||||
|
||||
{
|
||||
@@ -10911,12 +11215,12 @@ void Postprocess_SSR(
|
||||
postprocess.resolution.y = desc.height;
|
||||
postprocess.resolution_rcp.x = 1.0f / postprocess.resolution.x;
|
||||
postprocess.resolution_rcp.y = 1.0f / postprocess.resolution.y;
|
||||
device->PushConstants(&postprocess, sizeof(postprocess), cmd);
|
||||
|
||||
// Resolve pass:
|
||||
{
|
||||
device->EventBegin("SSR Resolve pass", cmd);
|
||||
device->BindComputeShader(&shaders[CSTYPE_POSTPROCESS_SSR_RESOLVE], cmd);
|
||||
device->PushConstants(&postprocess, sizeof(postprocess), cmd);
|
||||
|
||||
const GPUResource* resarray[] = {
|
||||
&res.texture_rayIndirectSpecular,
|
||||
@@ -10968,6 +11272,7 @@ void Postprocess_SSR(
|
||||
{
|
||||
device->EventBegin("SSR Temporal pass", cmd);
|
||||
device->BindComputeShader(&shaders[CSTYPE_POSTPROCESS_SSR_TEMPORAL], cmd);
|
||||
device->PushConstants(&postprocess, sizeof(postprocess), cmd);
|
||||
|
||||
const GPUResource* resarray[] = {
|
||||
&res.texture_resolve,
|
||||
@@ -13530,6 +13835,14 @@ uint32_t GetDDGIRayCount()
|
||||
{
|
||||
return DDGI_RAYCOUNT;
|
||||
}
|
||||
void SetDDGIBlendSpeed(float value)
|
||||
{
|
||||
DDGI_BLEND_SPEED = value;
|
||||
}
|
||||
float GetDDGIBlendSpeed()
|
||||
{
|
||||
return DDGI_BLEND_SPEED;
|
||||
}
|
||||
void SetGIBoost(float value)
|
||||
{
|
||||
GI_BOOST = value;
|
||||
|
||||
@@ -474,6 +474,25 @@ namespace wi::renderer
|
||||
float power = 1.0f,
|
||||
uint8_t instanceInclusionMask = 0xFF
|
||||
);
|
||||
struct RTDiffuseResources
|
||||
{
|
||||
mutable int frame = 0;
|
||||
wi::graphics::Texture texture_rayIndirectDiffuse;
|
||||
wi::graphics::Texture texture_spatial;
|
||||
wi::graphics::Texture texture_spatial_variance;
|
||||
wi::graphics::Texture texture_temporal[2];
|
||||
wi::graphics::Texture texture_temporal_variance[2];
|
||||
wi::graphics::Texture texture_bilateral_temp;
|
||||
};
|
||||
void CreateRTDiffuseResources(RTDiffuseResources& res, XMUINT2 resolution);
|
||||
void Postprocess_RTDiffuse(
|
||||
const RTDiffuseResources& res,
|
||||
const wi::scene::Scene& scene,
|
||||
const wi::graphics::Texture& output,
|
||||
wi::graphics::CommandList cmd,
|
||||
float range = 1000.0f,
|
||||
uint8_t instanceInclusionMask = 0xFF
|
||||
);
|
||||
struct RTReflectionResources
|
||||
{
|
||||
mutable int frame = 0;
|
||||
@@ -494,6 +513,7 @@ namespace wi::renderer
|
||||
const wi::graphics::Texture& output,
|
||||
wi::graphics::CommandList cmd,
|
||||
float range = 1000.0f,
|
||||
float roughnessCutoff = 0.5f,
|
||||
uint8_t instanceInclusionMask = 0xFF
|
||||
);
|
||||
struct SSRResources
|
||||
@@ -521,7 +541,8 @@ namespace wi::renderer
|
||||
const SSRResources& res,
|
||||
const wi::graphics::Texture& input,
|
||||
const wi::graphics::Texture& output,
|
||||
wi::graphics::CommandList cmd
|
||||
wi::graphics::CommandList cmd,
|
||||
float roughnessCutoff = 0.6f
|
||||
);
|
||||
struct RTShadowResources
|
||||
{
|
||||
@@ -848,6 +869,8 @@ namespace wi::renderer
|
||||
bool GetDDGIDebugEnabled();
|
||||
void SetDDGIRayCount(uint32_t value);
|
||||
uint32_t GetDDGIRayCount();
|
||||
void SetDDGIBlendSpeed(float value);
|
||||
float GetDDGIBlendSpeed();
|
||||
void SetGIBoost(float value);
|
||||
float GetGIBoost();
|
||||
void Workaround( const int bug, wi::graphics::CommandList cmd);
|
||||
|
||||
@@ -961,6 +961,7 @@ namespace wi::scene
|
||||
int texture_ao_index = -1;
|
||||
int texture_ssr_index = -1;
|
||||
int texture_rtshadow_index = -1;
|
||||
int texture_rtdiffuse_index = -1;
|
||||
int texture_surfelgi_index = -1;
|
||||
int buffer_entitytiles_opaque_index = -1;
|
||||
int buffer_entitytiles_transparent_index = -1;
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace wi::version
|
||||
// minor features, major updates, breaking compatibility changes
|
||||
const int minor = 71;
|
||||
// minor bug fixes, alterations, refactors, updates
|
||||
const int revision = 37;
|
||||
const int revision = 38;
|
||||
|
||||
const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user