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:
Turánszki János
2022-09-09 13:28:03 +02:00
committed by GitHub
parent 7f56c9202e
commit 5179d75878
32 changed files with 1231 additions and 30 deletions
@@ -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)
+89 -7
View File
@@ -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);
+5
View File
@@ -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;
+4
View File
@@ -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">
+1 -1
View File
@@ -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;
+7
View File
@@ -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)))
{
+216
View File
@@ -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);
}
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -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;
+2 -2
View File
@@ -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)));
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -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;
+2 -3
View File
@@ -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"
+4
View File
@@ -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,
+52 -2
View File
@@ -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;
+15
View File
@@ -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; }
+14
View File
@@ -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)
+1
View File
@@ -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
View File
@@ -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;
+24 -1
View File
@@ -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);
+1
View File
@@ -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;
+1 -1
View File
@@ -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);