diff --git a/Editor/PostprocessWindow.cpp b/Editor/PostprocessWindow.cpp
index 55f70c2ab..4f0f1bea2 100644
--- a/Editor/PostprocessWindow.cpp
+++ b/Editor/PostprocessWindow.cpp
@@ -132,7 +132,7 @@ PostprocessWindow::PostprocessWindow(wiGUI* gui, RenderPath3D* comp) : GUI(gui),
});
ppWindow->AddWidget(depthOfFieldCheckBox);
- depthOfFieldFocusSlider = new wiSlider(0.01f, 600, 100, 10000, "Focus: ");
+ depthOfFieldFocusSlider = new wiSlider(0.1f, 100, 10, 10000, "Focus: ");
depthOfFieldFocusSlider->SetTooltip("Set the focus distance from the camera. The picture will be sharper near the focus, and blurrier further from it.");
depthOfFieldFocusSlider->SetScriptTip("RenderPath3D::SetDepthOfFieldFocus(float value)");
depthOfFieldFocusSlider->SetSize(XMFLOAT2(100, 20));
@@ -143,16 +143,16 @@ PostprocessWindow::PostprocessWindow(wiGUI* gui, RenderPath3D* comp) : GUI(gui),
});
ppWindow->AddWidget(depthOfFieldFocusSlider);
- depthOfFieldStrengthSlider = new wiSlider(0.01f, 4, 100, 1000, "Strength: ");
- depthOfFieldStrengthSlider->SetTooltip("Set depth of field blur strength.");
- depthOfFieldStrengthSlider->SetScriptTip("RenderPath3D::SetDepthOfFieldStrength(float value)");
- depthOfFieldStrengthSlider->SetSize(XMFLOAT2(100, 20));
- depthOfFieldStrengthSlider->SetPos(XMFLOAT2(x + 100, y += 35));
- depthOfFieldStrengthSlider->SetValue(component->getDepthOfFieldStrength());
- depthOfFieldStrengthSlider->OnSlide([&](wiEventArgs args) {
+ depthOfFieldScaleSlider = new wiSlider(0.01f, 4, 100, 1000, "Scale: ");
+ depthOfFieldScaleSlider->SetTooltip("Set depth of field scale/falloff.");
+ depthOfFieldScaleSlider->SetScriptTip("RenderPath3D::SetDepthOfFieldStrength(float value)");
+ depthOfFieldScaleSlider->SetSize(XMFLOAT2(100, 20));
+ depthOfFieldScaleSlider->SetPos(XMFLOAT2(x + 100, y += 35));
+ depthOfFieldScaleSlider->SetValue(component->getDepthOfFieldStrength());
+ depthOfFieldScaleSlider->OnSlide([&](wiEventArgs args) {
component->setDepthOfFieldStrength(args.fValue);
});
- ppWindow->AddWidget(depthOfFieldStrengthSlider);
+ ppWindow->AddWidget(depthOfFieldScaleSlider);
bloomCheckBox = new wiCheckBox("Bloom: ");
bloomCheckBox->SetTooltip("Enable bloom. The effect adds color bleeding to the brightest parts of the scene.");
diff --git a/Editor/PostprocessWindow.h b/Editor/PostprocessWindow.h
index 0ece1be09..bc43291c9 100644
--- a/Editor/PostprocessWindow.h
+++ b/Editor/PostprocessWindow.h
@@ -31,7 +31,7 @@ public:
wiCheckBox* motionBlurCheckBox;
wiCheckBox* depthOfFieldCheckBox;
wiSlider* depthOfFieldFocusSlider;
- wiSlider* depthOfFieldStrengthSlider;
+ wiSlider* depthOfFieldScaleSlider;
wiCheckBox* bloomCheckBox;
wiSlider* bloomStrengthSlider;
wiCheckBox* fxaaCheckBox;
diff --git a/WickedEngine/WickedEngine_SHADERS.vcxproj b/WickedEngine/WickedEngine_SHADERS.vcxproj
index c4ac5d50a..f2c3e3e02 100644
--- a/WickedEngine/WickedEngine_SHADERS.vcxproj
+++ b/WickedEngine/WickedEngine_SHADERS.vcxproj
@@ -14,6 +14,7 @@
+
@@ -119,14 +120,18 @@
Pixel
-
+
Compute
Compute
5.0
-
+
+ Compute
+ 5.0
+
+
Compute
5.0
@@ -138,6 +143,10 @@
Compute
5.0
+
+ Compute
+ 5.0
+
Pixel
diff --git a/WickedEngine/WickedEngine_SHADERS.vcxproj.filters b/WickedEngine/WickedEngine_SHADERS.vcxproj.filters
index 07df05f8d..d5cfb300f 100644
--- a/WickedEngine/WickedEngine_SHADERS.vcxproj.filters
+++ b/WickedEngine/WickedEngine_SHADERS.vcxproj.filters
@@ -82,6 +82,9 @@
HF
+
+ HF
+
@@ -732,9 +735,6 @@
CS
-
- CS
-
CS
@@ -822,7 +822,16 @@
CS
-
+
+ CS
+
+
+ CS
+
+
+ CS
+
+
CS
diff --git a/WickedEngine/depthoffieldCS.hlsl b/WickedEngine/depthoffieldHF.hlsli
similarity index 51%
rename from WickedEngine/depthoffieldCS.hlsl
rename to WickedEngine/depthoffieldHF.hlsli
index a933a051f..f571bd644 100644
--- a/WickedEngine/depthoffieldCS.hlsl
+++ b/WickedEngine/depthoffieldHF.hlsli
@@ -1,13 +1,33 @@
-#include "globals.hlsli"
-#include "ShaderInterop_Postprocess.h"
+#ifndef WI_DEPTHOFFIELD_HF
+#define WI_DEPTHOFFIELD_HF
-// Implementation based on Jorge Jimenez Siggraph 2014 Next Generation Post Processing in Call of Duty Advanced Warfare
-TEXTURE2D(input, float4, TEXSLOT_ONDEMAND0);
-TEXTURE2D(neighborhood_mindepth_maxcoc, float2, TEXSLOT_ONDEMAND1);
-TEXTURE2D(texture_presort, float4, TEXSLOT_ONDEMAND2);
+#define DOF_DEPTH_SCALE_FOREGROUND (g_xCamera_ZFarP * 0.25f)
+float2 DepthCmp2(float depth, float closestTileDepth)
+{
+ float d = DOF_DEPTH_SCALE_FOREGROUND * (depth - closestTileDepth);
+ float2 depthCmp;
+ depthCmp.x = smoothstep(0.0, 1.0, d); // Background
+ depthCmp.y = 1.0 - depthCmp.x; // Foreground
+ return depthCmp;
-RWTEXTURE2D(output, float4, 0);
+}
+
+#define DOF_SINGLE_PIXEL_RADIUS 0.7071 // length( float2(0.5, 0.5 ) )
+float SampleAlpha(float sampleCoc)
+{
+ return min(rcp(PI * sampleCoc * sampleCoc), rcp(PI * DOF_SINGLE_PIXEL_RADIUS * DOF_SINGLE_PIXEL_RADIUS));
+}
+
+#define DOF_SPREAD_TOE_POWER 2
+float SpreadToe(float offsetCoc, float spreadCmp)
+{
+ return offsetCoc <= 1.0 ? pow(spreadCmp, DOF_SPREAD_TOE_POWER) : spreadCmp;
+}
+float SpreadCmp(float offsetCoc, float sampleCoc, float pixelToSampleUnitsScale)
+{
+ return SpreadToe(offsetCoc, saturate(pixelToSampleUnitsScale * sampleCoc - offsetCoc + 1.0));
+}
#define DOF_RING_COUNT 4
@@ -98,66 +118,4 @@ static const float3 disc[] =
static const uint ringSampleCount[] = { 0, 8, 24, 48, 80 };
static const float ringNormFactor[] = { 1.0, 0.111111, 0.040000, 0.020408, 0.012346 };
-
-#define DOF_SPREAD_TOE_POWER 2
-float SpreadToe(float offsetCoc, float spreadCmp)
-{
- return offsetCoc <= 1.0 ? pow(spreadCmp, DOF_SPREAD_TOE_POWER) : spreadCmp;
-}
-float SpreadCmp(float offsetCoc, float sampleCoc, float pixelToSampleUnitsScale)
-{
- return SpreadToe(offsetCoc, saturate(pixelToSampleUnitsScale * sampleCoc - offsetCoc + 1.0));
-}
-
-#define DOF_SINGLE_PIXEL_RADIUS 0.7071 // length( float2(0.5, 0.5 ) )
-float SampleAlpha(float sampleCoc)
-{
- return min(rcp(PI * sampleCoc * sampleCoc), rcp(PI * DOF_SINGLE_PIXEL_RADIUS * DOF_SINGLE_PIXEL_RADIUS));
-}
-
-[numthreads(POSTPROCESS_BLOCKSIZE, POSTPROCESS_BLOCKSIZE, 1)]
-void main(uint3 DTid : SV_DispatchThreadID)
-{
- const float maxcoc = neighborhood_mindepth_maxcoc[DTid.xy / DEPTHOFFIELD_TILESIZE].y;
-
- const uint ringCount = clamp(ceil(pow(maxcoc, 0.5f) * DOF_RING_COUNT), 1, DOF_RING_COUNT);
- const float spreadScale = ringCount / maxcoc;
- const float2 ringScale = float(ringCount) / float(DOF_RING_COUNT) * maxcoc * xPPResolution_rcp;
-
- const float4 center_color = input[DTid.xy];
- const float3 center_presort = texture_presort[DTid.xy].rgb;
- const float center_coc = center_presort.r;
- const float center_backgroundWeight = center_presort.g;
- const float center_foregroundWeight = center_presort.b;
-
- const float2 uv = (DTid.xy + 0.5f) * xPPResolution_rcp;
-
- float4 background = center_backgroundWeight * float4(center_color.rgb, 1);
- float4 foreground = center_foregroundWeight * float4(center_color.rgb, 1);
- for (uint j = 0; j < ringCount; ++j)
- {
- for (uint i = ringSampleCount[j]; i < ringSampleCount[j + 1]; ++i)
- {
- const float offsetCoc = disc[i].z;
- const float2 uv2 = uv + ringScale * disc[i].xy;
- const float4 color = float4(input.SampleLevel(sampler_point_clamp, uv2, 0).rgb, 1);
- const float3 presort = texture_presort.SampleLevel(sampler_point_clamp, uv2, 0).rgb;
- const float coc = presort.r;
- const float spreadCmp = SpreadCmp(offsetCoc, coc, spreadScale);
- const float backgroundWeight = presort.g * spreadCmp;
- const float foregroundWeight = presort.b * spreadCmp;
- background += backgroundWeight * color;
- foreground += foregroundWeight * color;
- }
- }
- background.rgb *= rcp(max(0.00001, background.a));
- foreground.rgb *= rcp(max(0.00001, foreground.a));
-
- float alpha = saturate(2 * ringNormFactor[ringCount] * rcp(SampleAlpha(maxcoc)) * foreground.a);
- float4 color = float4(lerp(background.rgb, foreground.rgb, alpha), center_color.a);
-
- output[DTid.xy] = color;
- //output[DTid.xy] = alpha;
- //output[DTid.xy] = maxcoc;
- //output[DTid.xy] = float(ringCount) / float(DOF_RING_COUNT);
-}
+#endif // WI_DEPTHOFFIELD_HF
diff --git a/WickedEngine/depthoffield_mainCS.hlsl b/WickedEngine/depthoffield_mainCS.hlsl
new file mode 100644
index 000000000..f30a4c658
--- /dev/null
+++ b/WickedEngine/depthoffield_mainCS.hlsl
@@ -0,0 +1,61 @@
+#include "globals.hlsli"
+#include "ShaderInterop_Postprocess.h"
+#include "depthoffieldHF.hlsli"
+
+// Implementation based on Jorge Jimenez Siggraph 2014 Next Generation Post Processing in Call of Duty Advanced Warfare
+
+TEXTURE2D(neighborhood_mindepth_maxcoc, float2, TEXSLOT_ONDEMAND0);
+TEXTURE2D(texture_presort, float3, TEXSLOT_ONDEMAND1);
+TEXTURE2D(texture_prefilter, float3, TEXSLOT_ONDEMAND2);
+
+RWTEXTURE2D(output_main, float3, 0);
+RWTEXTURE2D(output_alpha, unorm float, 1);
+
+[numthreads(POSTPROCESS_BLOCKSIZE, POSTPROCESS_BLOCKSIZE, 1)]
+void main(uint3 DTid : SV_DispatchThreadID)
+{
+ const float maxcoc = neighborhood_mindepth_maxcoc[2 * DTid.xy / DEPTHOFFIELD_TILESIZE].y;
+
+ const uint ringCount = clamp(ceil(pow(maxcoc, 0.5f) * DOF_RING_COUNT), 1, DOF_RING_COUNT);
+ const float spreadScale = ringCount / maxcoc;
+ const float2 ringScale = float(ringCount) / float(DOF_RING_COUNT) * maxcoc * xPPResolution_rcp;
+
+ const float3 center_color = texture_prefilter[DTid.xy];
+ const float3 center_presort = texture_presort[DTid.xy];
+ const float center_coc = center_presort.r;
+ const float center_backgroundWeight = center_presort.g;
+ const float center_foregroundWeight = center_presort.b;
+
+ const float2 uv = (DTid.xy + 0.5f) * xPPResolution_rcp;
+
+ float4 background = center_backgroundWeight * float4(center_color.rgb, 1);
+ float4 foreground = center_foregroundWeight * float4(center_color.rgb, 1);
+ for (uint j = 0; j < ringCount; ++j)
+ {
+ for (uint i = ringSampleCount[j]; i < ringSampleCount[j + 1]; ++i)
+ {
+ const float offsetCoc = disc[i].z;
+ const float2 uv2 = uv + ringScale * disc[i].xy;
+ const float4 color = float4(texture_prefilter.SampleLevel(sampler_point_clamp, uv2, 0), 1);
+ const float3 presort = texture_presort.SampleLevel(sampler_point_clamp, uv2, 0).rgb;
+ const float coc = presort.r;
+ const float spreadCmp = SpreadCmp(offsetCoc, coc, spreadScale);
+ const float backgroundWeight = presort.g * spreadCmp;
+ const float foregroundWeight = presort.b * spreadCmp;
+ background += backgroundWeight * color;
+ foreground += foregroundWeight * color;
+ }
+ }
+ background.rgb *= rcp(max(0.00001, background.a));
+ foreground.rgb *= rcp(max(0.00001, foreground.a));
+
+ float alpha = saturate(2 * ringNormFactor[ringCount] * rcp(SampleAlpha(maxcoc)) * foreground.a);
+ float3 color = lerp(background.rgb, foreground.rgb, alpha);
+
+ output_main[DTid.xy] = color;
+ output_alpha[DTid.xy] = alpha;
+ //output_main[DTid.xy] = alpha;
+ //output_main[DTid.xy] = maxcoc;
+ //output_main[DTid.xy] = float(ringCount) / float(DOF_RING_COUNT);
+ //output_main[DTid.xy] = center_color;
+}
diff --git a/WickedEngine/depthoffield_postfilterCS.hlsl b/WickedEngine/depthoffield_postfilterCS.hlsl
new file mode 100644
index 000000000..df46ec8a7
--- /dev/null
+++ b/WickedEngine/depthoffield_postfilterCS.hlsl
@@ -0,0 +1,25 @@
+#include "globals.hlsli"
+#include "ShaderInterop_Postprocess.h"
+
+TEXTURE2D(texture_main, float3, TEXSLOT_ONDEMAND0);
+
+RWTEXTURE2D(output_postfilter, float3, 0);
+
+[numthreads(POSTPROCESS_BLOCKSIZE, POSTPROCESS_BLOCKSIZE, 1)]
+void main(uint3 DTid : SV_DispatchThreadID)
+{
+ float3 color = 0;
+ color += texture_main[DTid.xy + int2(-1, -1)];
+ color += texture_main[DTid.xy + int2(0, -1)];
+ color += texture_main[DTid.xy + int2(1, -1)];
+ color += texture_main[DTid.xy + int2(-1, 0)];
+ color += texture_main[DTid.xy + int2(0, 0)];
+ color += texture_main[DTid.xy + int2(1, 0)];
+ color += texture_main[DTid.xy + int2(-1, 1)];
+ color += texture_main[DTid.xy + int2(0, 1)];
+ color += texture_main[DTid.xy + int2(1, 1)];
+ color /= 9.0f;
+
+ output_postfilter[DTid.xy] = color;
+ //output_postfilter[DTid.xy] = texture_main[DTid.xy];
+}
\ No newline at end of file
diff --git a/WickedEngine/depthoffield_prepassCS.hlsl b/WickedEngine/depthoffield_prepassCS.hlsl
new file mode 100644
index 000000000..9d701b552
--- /dev/null
+++ b/WickedEngine/depthoffield_prepassCS.hlsl
@@ -0,0 +1,44 @@
+#include "globals.hlsli"
+#include "ShaderInterop_Postprocess.h"
+#include "depthoffieldHF.hlsli"
+
+TEXTURE2D(input, float4, TEXSLOT_ONDEMAND0);
+TEXTURE2D(neighborhood_mindepth_maxcoc, float2, TEXSLOT_ONDEMAND1);
+
+RWTEXTURE2D(output_presort, float3, 0);
+RWTEXTURE2D(output_prefilter, float3, 1);
+
+[numthreads(POSTPROCESS_BLOCKSIZE, POSTPROCESS_BLOCKSIZE, 1)]
+void main(uint3 DTid : SV_DispatchThreadID)
+{
+ const float mindepth = neighborhood_mindepth_maxcoc[2 * DTid.xy / DEPTHOFFIELD_TILESIZE].x;
+ const float depth0 = texture_lineardepth[2 * DTid.xy + uint2(0, 0)];
+ const float depth1 = texture_lineardepth[2 * DTid.xy + uint2(1, 0)];
+ const float depth2 = texture_lineardepth[2 * DTid.xy + uint2(0, 1)];
+ const float depth3 = texture_lineardepth[2 * DTid.xy + uint2(1, 1)];
+ const float center_depth = max(depth0, max(depth1, max(depth2, depth3)));
+ const float coc = dof_scale * abs(1 - dof_focus / (center_depth * g_xCamera_ZFarP));
+ const float alpha = SampleAlpha(coc);
+ const float2 depthcmp = DepthCmp2(center_depth, mindepth);
+
+ const float2 uv = (DTid.xy + 0.5f) * xPPResolution_rcp;
+
+ output_presort[DTid.xy] = float3(coc, alpha * depthcmp.x, alpha * depthcmp.y);
+
+
+ const float2 ringScale = 2 * coc * xPPResolution_rcp;
+ const float3 center_color = input.SampleLevel(sampler_point_clamp, uv, 0).rgb;
+ float3 prefilter = center_color;
+ for (uint i = ringSampleCount[0]; i < ringSampleCount[1]; ++i)
+ {
+ const float offsetCoc = disc[i].z;
+ const float2 uv2 = uv + ringScale * disc[i].xy;
+ const float depth = texture_lineardepth.SampleLevel(sampler_linear_clamp, uv2, 0);
+ const float3 color = input.SampleLevel(sampler_point_clamp, uv2, 0).rgb;
+ const float weight = saturate(abs(depth - center_depth) * g_xCamera_ZFarP * 2);
+ prefilter += lerp(color, center_color, weight);
+ }
+ prefilter *= ringNormFactor[1];
+
+ output_prefilter[DTid.xy] = prefilter;
+}
diff --git a/WickedEngine/depthoffield_presortCS.hlsl b/WickedEngine/depthoffield_presortCS.hlsl
deleted file mode 100644
index 33cbdcb43..000000000
--- a/WickedEngine/depthoffield_presortCS.hlsl
+++ /dev/null
@@ -1,35 +0,0 @@
-#include "globals.hlsli"
-#include "ShaderInterop_Postprocess.h"
-
-TEXTURE2D(neighborhood_mindepth_maxcoc, float2, TEXSLOT_ONDEMAND0);
-
-RWTEXTURE2D(output, float4, 0);
-
-#define DOF_DEPTH_SCALE_FOREGROUND (g_xCamera_ZFarP * 0.25f)
-float2 DepthCmp2(float depth, float closestTileDepth)
-{
- float d = DOF_DEPTH_SCALE_FOREGROUND * (depth - closestTileDepth);
- float2 depthCmp;
- depthCmp.x = smoothstep(0.0, 1.0, d); // Background
- depthCmp.y = 1.0 - depthCmp.x; // Foreground
- return depthCmp;
-
-}
-
-#define DOF_SINGLE_PIXEL_RADIUS 0.7071 // length( float2(0.5, 0.5 ) )
-float SampleAlpha(float sampleCoc)
-{
- return min(rcp(PI * sampleCoc * sampleCoc), rcp(PI * DOF_SINGLE_PIXEL_RADIUS * DOF_SINGLE_PIXEL_RADIUS));
-}
-
-[numthreads(POSTPROCESS_BLOCKSIZE, POSTPROCESS_BLOCKSIZE, 1)]
-void main(uint3 DTid : SV_DispatchThreadID)
-{
- const float mindepth = neighborhood_mindepth_maxcoc[DTid.xy / DEPTHOFFIELD_TILESIZE].x;
- const float depth = texture_lineardepth[DTid.xy];
- const float coc = dof_scale * abs(1 - dof_focus / (depth * g_xCamera_ZFarP));
- const float alpha = SampleAlpha(coc);
- const float2 depthcmp = DepthCmp2(depth, mindepth);
-
- output[DTid.xy] = float4(coc, alpha * depthcmp.x, alpha * depthcmp.y, 1);
-}
diff --git a/WickedEngine/depthoffield_upsampleCS.hlsl b/WickedEngine/depthoffield_upsampleCS.hlsl
new file mode 100644
index 000000000..064606991
--- /dev/null
+++ b/WickedEngine/depthoffield_upsampleCS.hlsl
@@ -0,0 +1,38 @@
+#include "globals.hlsli"
+#include "ShaderInterop_Postprocess.h"
+#include "depthoffieldHF.hlsli"
+
+TEXTURE2D(input, float4, TEXSLOT_ONDEMAND0);
+TEXTURE2D(texture_postfilter, float3, TEXSLOT_ONDEMAND1);
+TEXTURE2D(texture_alpha, float, TEXSLOT_ONDEMAND2);
+TEXTURE2D(neighborhood_mindepth_maxcoc, float2, TEXSLOT_ONDEMAND3);
+
+RWTEXTURE2D(output, float4, 0);
+
+[numthreads(POSTPROCESS_BLOCKSIZE, POSTPROCESS_BLOCKSIZE, 1)]
+void main(uint3 DTid : SV_DispatchThreadID)
+{
+ const float2 uv = (DTid.xy + 0.5f) * xPPResolution_rcp;
+
+ const float center_depth = texture_lineardepth[DTid.xy];
+ const float maxcoc = neighborhood_mindepth_maxcoc[DTid.xy / DEPTHOFFIELD_TILESIZE].y;
+ float4 fullres = input[DTid.xy];
+ const float3 halfres = texture_postfilter.SampleLevel(sampler_linear_clamp, uv, 0);
+ const float alpha = texture_alpha.SampleLevel(sampler_linear_clamp, uv, 0);
+
+ const float coc = dof_scale * abs(1 - dof_focus / (center_depth * g_xCamera_ZFarP));
+
+ const float backgroundFactor = coc;
+ const float foregroundFactor = maxcoc;
+
+ const float combinedFactor = saturate(lerp(backgroundFactor, foregroundFactor, alpha));
+
+ float4 color = float4(lerp(fullres.rgb, halfres, combinedFactor), fullres.a);
+ //color = backgroundFactor;
+ //color = foregroundFactor;
+ //color = combinedFactor;
+
+ //if (coc < 0.01) color = float4(1, 0, 0, 1);
+
+ output[DTid.xy] = color;
+}
diff --git a/WickedEngine/motionblurCS.hlsl b/WickedEngine/motionblurCS.hlsl
index 4c8fb74b2..65c2cf046 100644
--- a/WickedEngine/motionblurCS.hlsl
+++ b/WickedEngine/motionblurCS.hlsl
@@ -49,7 +49,7 @@ void main(uint3 DTid : SV_DispatchThreadID)
const float2 uv = (DTid.xy + 0.5f) * xPPResolution_rcp;
float seed = 12345;
- const float2 random_direction = rand(seed, uv) * 0.5f + 0.5f;
+ const float random_direction = rand(seed, uv) * 0.5f + 0.5f;
const float2 sampling_direction = neighborhood_velocity * random_direction * xPPResolution_rcp;
diff --git a/WickedEngine/wiEnums.h b/WickedEngine/wiEnums.h
index 520282c25..80a523534 100644
--- a/WickedEngine/wiEnums.h
+++ b/WickedEngine/wiEnums.h
@@ -302,8 +302,10 @@ enum CSTYPES
CSTYPE_POSTPROCESS_DEPTHOFFIELD_TILEMAXCOC_HORIZONTAL,
CSTYPE_POSTPROCESS_DEPTHOFFIELD_TILEMAXCOC_VERTICAL,
CSTYPE_POSTPROCESS_DEPTHOFFIELD_NEIGHBORHOODMAXCOC,
- CSTYPE_POSTPROCESS_DEPTHOFFIELD_PRESORT,
- CSTYPE_POSTPROCESS_DEPTHOFFIELD,
+ CSTYPE_POSTPROCESS_DEPTHOFFIELD_PREPASS,
+ CSTYPE_POSTPROCESS_DEPTHOFFIELD_MAIN,
+ CSTYPE_POSTPROCESS_DEPTHOFFIELD_POSTFILTER,
+ CSTYPE_POSTPROCESS_DEPTHOFFIELD_UPSAMPLE,
CSTYPE_POSTPROCESS_OUTLINE_FLOAT4,
CSTYPE_POSTPROCESS_OUTLINE_UNORM4,
CSTYPE_POSTPROCESS_MOTIONBLUR_TILEMAXVELOCITY_HORIZONTAL,
diff --git a/WickedEngine/wiRenderer.cpp b/WickedEngine/wiRenderer.cpp
index 01a9ad8bb..39880b342 100644
--- a/WickedEngine/wiRenderer.cpp
+++ b/WickedEngine/wiRenderer.cpp
@@ -1381,8 +1381,10 @@ void LoadShaders()
wiJobSystem::Execute(ctx, []{ LoadComputeShader(computeShaders[CSTYPE_POSTPROCESS_DEPTHOFFIELD_TILEMAXCOC_HORIZONTAL], "depthoffield_tileMaxCOC_horizontalCS.cso"); });
wiJobSystem::Execute(ctx, []{ LoadComputeShader(computeShaders[CSTYPE_POSTPROCESS_DEPTHOFFIELD_TILEMAXCOC_VERTICAL], "depthoffield_tileMaxCOC_verticalCS.cso"); });
wiJobSystem::Execute(ctx, []{ LoadComputeShader(computeShaders[CSTYPE_POSTPROCESS_DEPTHOFFIELD_NEIGHBORHOODMAXCOC], "depthoffield_neighborhoodMaxCOCCS.cso"); });
- wiJobSystem::Execute(ctx, []{ LoadComputeShader(computeShaders[CSTYPE_POSTPROCESS_DEPTHOFFIELD_PRESORT], "depthoffield_presortCS.cso"); });
- wiJobSystem::Execute(ctx, []{ LoadComputeShader(computeShaders[CSTYPE_POSTPROCESS_DEPTHOFFIELD], "depthoffieldCS.cso"); });
+ wiJobSystem::Execute(ctx, []{ LoadComputeShader(computeShaders[CSTYPE_POSTPROCESS_DEPTHOFFIELD_PREPASS], "depthoffield_prepassCS.cso"); });
+ wiJobSystem::Execute(ctx, []{ LoadComputeShader(computeShaders[CSTYPE_POSTPROCESS_DEPTHOFFIELD_MAIN], "depthoffield_mainCS.cso"); });
+ wiJobSystem::Execute(ctx, []{ LoadComputeShader(computeShaders[CSTYPE_POSTPROCESS_DEPTHOFFIELD_POSTFILTER], "depthoffield_postfilterCS.cso"); });
+ wiJobSystem::Execute(ctx, []{ LoadComputeShader(computeShaders[CSTYPE_POSTPROCESS_DEPTHOFFIELD_UPSAMPLE], "depthoffield_upsampleCS.cso"); });
wiJobSystem::Execute(ctx, []{ LoadComputeShader(computeShaders[CSTYPE_POSTPROCESS_OUTLINE_FLOAT4], "outlineCS_float4.cso"); });
wiJobSystem::Execute(ctx, []{ LoadComputeShader(computeShaders[CSTYPE_POSTPROCESS_OUTLINE_UNORM4], "outlineCS_unorm4.cso"); });
wiJobSystem::Execute(ctx, []{ LoadComputeShader(computeShaders[CSTYPE_POSTPROCESS_MOTIONBLUR_TILEMAXVELOCITY_HORIZONTAL], "motionblur_tileMaxVelocity_horizontalCS.cso"); });
@@ -8842,6 +8844,10 @@ void Postprocess_DepthOfField(
static Texture texture_tilemax;
static Texture texture_neighborhoodmax;
static Texture texture_presort;
+ static Texture texture_prefilter;
+ static Texture texture_main;
+ static Texture texture_postfilter;
+ static Texture texture_alpha;
if (!init)
{
@@ -8861,15 +8867,20 @@ void Postprocess_DepthOfField(
tile_desc.Height = desc.Height;
device->CreateTexture(&tile_desc, nullptr, &texture_tilemax_horizontal);
}
- if (texture_presort.GetDesc().Width < desc.Width || texture_presort.GetDesc().Height < desc.Height)
+ if (texture_presort.GetDesc().Width != desc.Width/2 || texture_presort.GetDesc().Height != desc.Height/2)
{
TextureDesc presort_desc;
presort_desc.type = TextureDesc::TEXTURE_2D;
- presort_desc.Width = desc.Width;
- presort_desc.Height = desc.Height;
+ presort_desc.Width = desc.Width/2;
+ presort_desc.Height = desc.Height/2;
presort_desc.Format = FORMAT_R11G11B10_FLOAT;
presort_desc.BindFlags = BIND_SHADER_RESOURCE | BIND_UNORDERED_ACCESS;
device->CreateTexture(&presort_desc, nullptr, &texture_presort);
+ device->CreateTexture(&presort_desc, nullptr, &texture_prefilter);
+ device->CreateTexture(&presort_desc, nullptr, &texture_main);
+ device->CreateTexture(&presort_desc, nullptr, &texture_postfilter);
+ presort_desc.Format = FORMAT_R8_UNORM;
+ device->CreateTexture(&presort_desc, nullptr, &texture_alpha);
}
PostProcessCB cb;
@@ -8949,15 +8960,28 @@ void Postprocess_DepthOfField(
device->EventEnd(cmd);
}
- // Presort pass:
- {
- device->EventBegin("Presort", cmd);
- device->BindComputeShader(&computeShaders[CSTYPE_POSTPROCESS_DEPTHOFFIELD_PRESORT], cmd);
+ // Switch to half res:
+ cb.xPPResolution.x = desc.Width / 2;
+ cb.xPPResolution.y = desc.Height / 2;
+ cb.xPPResolution_rcp.x = 1.0f / cb.xPPResolution.x;
+ cb.xPPResolution_rcp.y = 1.0f / cb.xPPResolution.y;
+ device->UpdateBuffer(&constantBuffers[CBTYPE_POSTPROCESS], &cb, cmd);
+ device->BindConstantBuffer(CS, &constantBuffers[CBTYPE_POSTPROCESS], CB_GETBINDSLOT(PostProcessCB), cmd);
- device->BindResource(CS, &texture_neighborhoodmax, TEXSLOT_ONDEMAND0, cmd);
+ // Prepass:
+ {
+ device->EventBegin("Prepass", cmd);
+ device->BindComputeShader(&computeShaders[CSTYPE_POSTPROCESS_DEPTHOFFIELD_PREPASS], cmd);
+
+ const GPUResource* res[] = {
+ &input,
+ &texture_neighborhoodmax
+ };
+ device->BindResources(CS, res, TEXSLOT_ONDEMAND0, arraysize(res), cmd);
const GPUResource* uavs[] = {
&texture_presort,
+ &texture_prefilter,
};
device->BindUAVs(CS, uavs, 0, arraysize(uavs), cmd);
@@ -8975,13 +8999,79 @@ void Postprocess_DepthOfField(
// Main pass:
{
- device->EventBegin("DepthOfField", cmd);
- device->BindComputeShader(&computeShaders[CSTYPE_POSTPROCESS_DEPTHOFFIELD], cmd);
+ device->EventBegin("Main pass", cmd);
+ device->BindComputeShader(&computeShaders[CSTYPE_POSTPROCESS_DEPTHOFFIELD_MAIN], cmd);
+
+ const GPUResource* res[] = {
+ &texture_neighborhoodmax,
+ &texture_presort,
+ &texture_prefilter
+ };
+ device->BindResources(CS, res, TEXSLOT_ONDEMAND0, arraysize(res), cmd);
+
+ const GPUResource* uavs[] = {
+ &texture_main,
+ &texture_alpha
+ };
+ device->BindUAVs(CS, uavs, 0, arraysize(uavs), cmd);
+
+ device->Dispatch(
+ (texture_main.GetDesc().Width + POSTPROCESS_BLOCKSIZE - 1) / POSTPROCESS_BLOCKSIZE,
+ (texture_main.GetDesc().Height + POSTPROCESS_BLOCKSIZE - 1) / POSTPROCESS_BLOCKSIZE,
+ 1,
+ cmd
+ );
+
+ device->Barrier(&GPUBarrier::Memory(), 1, cmd);
+ device->UnbindUAVs(0, arraysize(uavs), cmd);
+ device->EventEnd(cmd);
+ }
+
+ // Post filter:
+ {
+ device->EventBegin("Post filter", cmd);
+ device->BindComputeShader(&computeShaders[CSTYPE_POSTPROCESS_DEPTHOFFIELD_POSTFILTER], cmd);
+
+ const GPUResource* res[] = {
+ &texture_main,
+ };
+ device->BindResources(CS, res, TEXSLOT_ONDEMAND0, arraysize(res), cmd);
+
+ const GPUResource* uavs[] = {
+ &texture_postfilter
+ };
+ device->BindUAVs(CS, uavs, 0, arraysize(uavs), cmd);
+
+ device->Dispatch(
+ (texture_postfilter.GetDesc().Width + POSTPROCESS_BLOCKSIZE - 1) / POSTPROCESS_BLOCKSIZE,
+ (texture_postfilter.GetDesc().Height + POSTPROCESS_BLOCKSIZE - 1) / POSTPROCESS_BLOCKSIZE,
+ 1,
+ cmd
+ );
+
+ device->Barrier(&GPUBarrier::Memory(), 1, cmd);
+ device->UnbindUAVs(0, arraysize(uavs), cmd);
+ device->EventEnd(cmd);
+ }
+
+ // Switch to full res:
+ cb.xPPResolution.x = desc.Width;
+ cb.xPPResolution.y = desc.Height;
+ cb.xPPResolution_rcp.x = 1.0f / cb.xPPResolution.x;
+ cb.xPPResolution_rcp.y = 1.0f / cb.xPPResolution.y;
+ device->UpdateBuffer(&constantBuffers[CBTYPE_POSTPROCESS], &cb, cmd);
+ device->BindConstantBuffer(CS, &constantBuffers[CBTYPE_POSTPROCESS], CB_GETBINDSLOT(PostProcessCB), cmd);
+
+ // Upsample pass:
+ {
+ device->EventBegin("Upsample pass", cmd);
+ device->BindComputeShader(&computeShaders[CSTYPE_POSTPROCESS_DEPTHOFFIELD_UPSAMPLE], cmd);
const GPUResource* res[] = {
&input,
- &texture_neighborhoodmax,
- &texture_presort
+ &texture_postfilter,
+ &texture_alpha,
+ &texture_neighborhoodmax
};
device->BindResources(CS, res, TEXSLOT_ONDEMAND0, arraysize(res), cmd);
diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp
index aae714382..e76af24d5 100644
--- a/WickedEngine/wiVersion.cpp
+++ b/WickedEngine/wiVersion.cpp
@@ -9,7 +9,7 @@ namespace wiVersion
// minor features, major updates
const int minor = 36;
// minor bug fixes, alterations, refactors, updates
- const int revision = 28;
+ const int revision = 29;
long GetVersion()