diff --git a/Documentation/ScriptingAPI-Documentation.md b/Documentation/ScriptingAPI-Documentation.md index e81a5c0d4..ff4216ab5 100644 --- a/Documentation/ScriptingAPI-Documentation.md +++ b/Documentation/ScriptingAPI-Documentation.md @@ -627,6 +627,7 @@ A 3D scene can either be rendered by a Forward or Deferred render path, or path It inherits functions from RenderPath2D, so it can render a 2D overlay. - [void-constructor]RenderPath3D() - SetSSAOEnabled(bool value) +- SetHBAOEnabled(bool value) - SetSSREnabled(bool value) - SetShadowsEnabled(bool value) - SetReflectionsEnabled(bool value) diff --git a/Editor/PostprocessWindow.cpp b/Editor/PostprocessWindow.cpp index 0cd0214f4..56eb303d0 100644 --- a/Editor/PostprocessWindow.cpp +++ b/Editor/PostprocessWindow.cpp @@ -61,10 +61,20 @@ PostprocessWindow::PostprocessWindow(wiGUI* gui, RenderPath3D* comp) : GUI(gui), }); ppWindow->AddWidget(ssaoCheckBox); + hbaoCheckBox = new wiCheckBox("HBAO: "); + hbaoCheckBox->SetTooltip("Special optimized version of Screen Space Ambient Occlusion. Range and Samplecount parameters don't apply."); + hbaoCheckBox->SetScriptTip("RenderPath3D::SetSSAOEnabled(bool value)"); + hbaoCheckBox->SetPos(XMFLOAT2(x + 100, y)); + hbaoCheckBox->SetCheck(component->getHBAOEnabled()); + hbaoCheckBox->OnClick([&](wiEventArgs args) { + component->setHBAOEnabled(args.bValue); + }); + ppWindow->AddWidget(hbaoCheckBox); + ssaoRangeSlider = new wiSlider(0, 2, 1, 1000, "Range: "); ssaoRangeSlider->SetTooltip("Set SSAO Detection range."); ssaoRangeSlider->SetSize(XMFLOAT2(100, 20)); - ssaoRangeSlider->SetPos(XMFLOAT2(x + 100, y)); + ssaoRangeSlider->SetPos(XMFLOAT2(x + 100, y += step)); ssaoRangeSlider->SetValue(component->getSSAORange()); ssaoRangeSlider->OnSlide([&](wiEventArgs args) { component->setSSAORange(args.fValue); diff --git a/Editor/PostprocessWindow.h b/Editor/PostprocessWindow.h index 27f0a3c56..674912e40 100644 --- a/Editor/PostprocessWindow.h +++ b/Editor/PostprocessWindow.h @@ -23,6 +23,7 @@ public: wiCheckBox* lensFlareCheckBox; wiCheckBox* lightShaftsCheckBox; wiCheckBox* ssaoCheckBox; + wiCheckBox* hbaoCheckBox; wiSlider* ssaoRangeSlider; wiSlider* ssaoSampleCountSlider; wiSlider* ssaoPowerSlider; diff --git a/WickedEngine/RenderPath3D.cpp b/WickedEngine/RenderPath3D.cpp index ae2673dee..23eda137f 100644 --- a/WickedEngine/RenderPath3D.cpp +++ b/WickedEngine/RenderPath3D.cpp @@ -228,7 +228,7 @@ void RenderPath3D::ResizeBuffers() { TextureDesc desc; desc.BindFlags = BIND_SHADER_RESOURCE | BIND_UNORDERED_ACCESS; - desc.Format = FORMAT_R16_UNORM; + desc.Format = FORMAT_R32_FLOAT; desc.Width = wiRenderer::GetInternalResolution().x; desc.Height = wiRenderer::GetInternalResolution().y; device->CreateTexture(&desc, nullptr, &rtLinearDepth); @@ -237,7 +237,7 @@ void RenderPath3D::ResizeBuffers() desc.Width = (desc.Width + 1) / 2; desc.Height = (desc.Height + 1) / 2; desc.MipLevels = 5; - desc.Format = FORMAT_R16G16_UNORM; + desc.Format = FORMAT_R32G32_FLOAT; device->CreateTexture(&desc, nullptr, &rtLinearDepth_minmax); device->SetName(&rtLinearDepth_minmax, "rtLinearDepth_minmax"); @@ -428,10 +428,20 @@ void RenderPath3D::RenderLinearDepth(CommandList cmd) const } void RenderPath3D::RenderSSAO(CommandList cmd) const { - if (getSSAOEnabled()) + if (getHBAOEnabled()) + { + wiRenderer::Postprocess_HBAO( + rtLinearDepth_minmax, + rtSSAO[1], + rtSSAO[0], + cmd, + getSSAOPower() + ); + } + else if(getSSAOEnabled()) { wiRenderer::Postprocess_SSAO( - depthBuffer_Copy, + depthBuffer_Copy, rtLinearDepth, rtLinearDepth_minmax, rtSSAO[1], @@ -440,7 +450,7 @@ void RenderPath3D::RenderSSAO(CommandList cmd) const getSSAORange(), getSSAOSampleCount(), getSSAOPower() - ); + ); } } void RenderPath3D::RenderSSR(const Texture& gbuffer1, const Texture& gbuffer2, CommandList cmd) const diff --git a/WickedEngine/RenderPath3D.h b/WickedEngine/RenderPath3D.h index 2479f6f3d..a9582c7b0 100644 --- a/WickedEngine/RenderPath3D.h +++ b/WickedEngine/RenderPath3D.h @@ -27,6 +27,7 @@ private: bool fxaaEnabled = false; bool ssaoEnabled = false; + bool hbaoEnabled = false; bool ssrEnabled = false; bool reflectionsEnabled = true; bool shadowsEnabled = true; @@ -50,7 +51,7 @@ private: uint32_t msaaSampleCount = 1; protected: - wiGraphics::Texture rtReflection; // conains the scene rendered for planar reflections + wiGraphics::Texture rtReflection; // contains the scene rendered for planar reflections wiGraphics::Texture rtSSR; // standard screen-space reflection results wiGraphics::Texture rtSceneCopy; // contains the rendered scene that can be fed into transparent pass for distortion effect wiGraphics::Texture rtSceneCopy_tmp; // temporary for gaussian mipchain @@ -131,6 +132,8 @@ public: constexpr float getChromaticAberrationAmount() const { return chromaticAberrationAmount; } constexpr bool getSSAOEnabled() const { return ssaoEnabled; } + constexpr bool getHBAOEnabled() const { return hbaoEnabled; } + constexpr bool getAOEnabled() const { return getSSAOEnabled() || getHBAOEnabled(); } constexpr bool getSSREnabled() const { return ssrEnabled; } constexpr bool getShadowsEnabled() const { return shadowsEnabled; } constexpr bool getReflectionsEnabled() const { return reflectionsEnabled; } @@ -169,7 +172,8 @@ public: constexpr void setSSAOPower(float value) { ssaoPower = value; } constexpr void setChromaticAberrationAmount(float value) { chromaticAberrationAmount = value; } - constexpr void setSSAOEnabled(bool value){ ssaoEnabled = value; } + constexpr void setSSAOEnabled(bool value) { ssaoEnabled = value; } + constexpr void setHBAOEnabled(bool value){ hbaoEnabled = value; } constexpr void setSSREnabled(bool value){ ssrEnabled = value; } constexpr void setShadowsEnabled(bool value){ shadowsEnabled = value; } constexpr void setReflectionsEnabled(bool value){ reflectionsEnabled = value; } diff --git a/WickedEngine/RenderPath3D_BindLua.cpp b/WickedEngine/RenderPath3D_BindLua.cpp index 4cb8ce1f7..478f41ee1 100644 --- a/WickedEngine/RenderPath3D_BindLua.cpp +++ b/WickedEngine/RenderPath3D_BindLua.cpp @@ -26,6 +26,7 @@ Luna::FunctionType RenderPath3D_BindLua::methods[] = { lunamethod(RenderPath_BindLua, SetLayerMask), lunamethod(RenderPath3D_BindLua, SetSSAOEnabled), + lunamethod(RenderPath3D_BindLua, SetHBAOEnabled), lunamethod(RenderPath3D_BindLua, SetSSREnabled), lunamethod(RenderPath3D_BindLua, SetShadowsEnabled), lunamethod(RenderPath3D_BindLua, SetReflectionsEnabled), @@ -68,6 +69,19 @@ int RenderPath3D_BindLua::SetSSAOEnabled(lua_State* L) wiLua::SError(L, "SetSSAOEnabled(bool value) not enough arguments!"); return 0; } +int RenderPath3D_BindLua::SetHBAOEnabled(lua_State* L) +{ + if (component == nullptr) + { + wiLua::SError(L, "SetHBAOEnabled(bool value) component is null!"); + return 0; + } + if (wiLua::SGetArgCount(L) > 0) + ((RenderPath3D*)component)->setHBAOEnabled(wiLua::SGetBool(L, 1)); + else + wiLua::SError(L, "SetHBAOEnabled(bool value) not enough arguments!"); + return 0; +} int RenderPath3D_BindLua::SetSSREnabled(lua_State* L) { if (component == nullptr) diff --git a/WickedEngine/RenderPath3D_BindLua.h b/WickedEngine/RenderPath3D_BindLua.h index ca8ce8fa6..767126548 100644 --- a/WickedEngine/RenderPath3D_BindLua.h +++ b/WickedEngine/RenderPath3D_BindLua.h @@ -19,6 +19,7 @@ public: RenderPath3D_BindLua(lua_State* L) {} int SetSSAOEnabled(lua_State* L); + int SetHBAOEnabled(lua_State* L); int SetSSREnabled(lua_State* L); int SetShadowsEnabled(lua_State* L); int SetReflectionsEnabled(lua_State* L); diff --git a/WickedEngine/RenderPath3D_Deferred.cpp b/WickedEngine/RenderPath3D_Deferred.cpp index 493775036..798d08455 100644 --- a/WickedEngine/RenderPath3D_Deferred.cpp +++ b/WickedEngine/RenderPath3D_Deferred.cpp @@ -208,7 +208,7 @@ void RenderPath3D_Deferred::Render() const vp.Height = (float)depthBuffer.GetDesc().Height; device->BindViewports(1, &vp, cmd); - device->BindResource(PS, getSSAOEnabled() ? &rtSSAO[0] : wiTextureHelper::getWhite(), TEXSLOT_RENDERPATH_SSAO, cmd); + device->BindResource(PS, getAOEnabled() ? &rtSSAO[0] : wiTextureHelper::getWhite(), TEXSLOT_RENDERPATH_SSAO, cmd); device->BindResource(PS, getSSREnabled() ? &rtSSR : wiTextureHelper::getTransparent(), TEXSLOT_RENDERPATH_SSR, cmd); wiRenderer::DrawDeferredLights(wiRenderer::GetCamera(), depthBuffer_Copy, rtGBuffer[0], rtGBuffer[1], rtGBuffer[2], cmd); @@ -294,7 +294,7 @@ void RenderPath3D_Deferred::RenderDeferredComposition(CommandList cmd) const rtGBuffer[2], lightbuffer_diffuse, lightbuffer_specular, - getSSAOEnabled() ? rtSSAO[0] : *wiTextureHelper::getWhite(), + getAOEnabled() ? rtSSAO[0] : *wiTextureHelper::getWhite(), rtLinearDepth, cmd ); diff --git a/WickedEngine/RenderPath3D_Deferred_BindLua.cpp b/WickedEngine/RenderPath3D_Deferred_BindLua.cpp index e3bea078f..7ef15d0da 100644 --- a/WickedEngine/RenderPath3D_Deferred_BindLua.cpp +++ b/WickedEngine/RenderPath3D_Deferred_BindLua.cpp @@ -25,6 +25,7 @@ Luna::FunctionType RenderPath3D_Deferred_BindLua: lunamethod(RenderPath_BindLua, SetLayerMask), lunamethod(RenderPath3D_BindLua, SetSSAOEnabled), + lunamethod(RenderPath3D_BindLua, SetHBAOEnabled), lunamethod(RenderPath3D_BindLua, SetSSREnabled), lunamethod(RenderPath3D_BindLua, SetShadowsEnabled), lunamethod(RenderPath3D_BindLua, SetReflectionsEnabled), diff --git a/WickedEngine/RenderPath3D_Forward.cpp b/WickedEngine/RenderPath3D_Forward.cpp index cd0b67f21..8c56c604f 100644 --- a/WickedEngine/RenderPath3D_Forward.cpp +++ b/WickedEngine/RenderPath3D_Forward.cpp @@ -170,7 +170,7 @@ void RenderPath3D_Forward::Render() const device->BindViewports(1, &vp, cmd); device->BindResource(PS, getReflectionsEnabled() ? &rtReflection : wiTextureHelper::getTransparent(), TEXSLOT_RENDERPATH_REFLECTION, cmd); - device->BindResource(PS, getSSAOEnabled() ? &rtSSAO[0] : wiTextureHelper::getWhite(), TEXSLOT_RENDERPATH_SSAO, cmd); + device->BindResource(PS, getAOEnabled() ? &rtSSAO[0] : wiTextureHelper::getWhite(), TEXSLOT_RENDERPATH_SSAO, cmd); device->BindResource(PS, getSSREnabled() ? &rtSSR : wiTextureHelper::getTransparent(), TEXSLOT_RENDERPATH_SSR, cmd); wiRenderer::DrawScene(wiRenderer::GetCamera(), getTessellationEnabled(), cmd, RENDERPASS_FORWARD, true, true); wiRenderer::DrawSky(cmd); diff --git a/WickedEngine/RenderPath3D_Forward_BindLua.cpp b/WickedEngine/RenderPath3D_Forward_BindLua.cpp index 8eb60683a..7ffa3c972 100644 --- a/WickedEngine/RenderPath3D_Forward_BindLua.cpp +++ b/WickedEngine/RenderPath3D_Forward_BindLua.cpp @@ -25,6 +25,7 @@ Luna::FunctionType RenderPath3D_Forward_BindLua::m lunamethod(RenderPath_BindLua, SetLayerMask), lunamethod(RenderPath3D_BindLua, SetSSAOEnabled), + lunamethod(RenderPath3D_BindLua, SetHBAOEnabled), lunamethod(RenderPath3D_BindLua, SetSSREnabled), lunamethod(RenderPath3D_BindLua, SetShadowsEnabled), lunamethod(RenderPath3D_BindLua, SetReflectionsEnabled), diff --git a/WickedEngine/RenderPath3D_TiledDeferred.cpp b/WickedEngine/RenderPath3D_TiledDeferred.cpp index 2c828078f..b2f669349 100644 --- a/WickedEngine/RenderPath3D_TiledDeferred.cpp +++ b/WickedEngine/RenderPath3D_TiledDeferred.cpp @@ -104,7 +104,7 @@ void RenderPath3D_TiledDeferred::Render() const RenderDecals(cmd); - device->BindResource(CS, getSSAOEnabled() ? &rtSSAO[0] : wiTextureHelper::getWhite(), TEXSLOT_RENDERPATH_SSAO, cmd); + device->BindResource(CS, getAOEnabled() ? &rtSSAO[0] : wiTextureHelper::getWhite(), TEXSLOT_RENDERPATH_SSAO, cmd); device->BindResource(CS, getSSREnabled() ? &rtSSR : wiTextureHelper::getTransparent(), TEXSLOT_RENDERPATH_SSR, cmd); diff --git a/WickedEngine/RenderPath3D_TiledDeferred_BindLua.cpp b/WickedEngine/RenderPath3D_TiledDeferred_BindLua.cpp index 263642fb4..2824131c8 100644 --- a/WickedEngine/RenderPath3D_TiledDeferred_BindLua.cpp +++ b/WickedEngine/RenderPath3D_TiledDeferred_BindLua.cpp @@ -25,6 +25,7 @@ Luna::FunctionType RenderPath3D_TiledDeferre lunamethod(RenderPath_BindLua, SetLayerMask), lunamethod(RenderPath3D_BindLua, SetSSAOEnabled), + lunamethod(RenderPath3D_BindLua, SetHBAOEnabled), lunamethod(RenderPath3D_BindLua, SetSSREnabled), lunamethod(RenderPath3D_BindLua, SetShadowsEnabled), lunamethod(RenderPath3D_BindLua, SetReflectionsEnabled), diff --git a/WickedEngine/RenderPath3D_TiledForward.cpp b/WickedEngine/RenderPath3D_TiledForward.cpp index 4df3dd3e8..02a1c2024 100644 --- a/WickedEngine/RenderPath3D_TiledForward.cpp +++ b/WickedEngine/RenderPath3D_TiledForward.cpp @@ -100,7 +100,7 @@ void RenderPath3D_TiledForward::Render() const device->BindViewports(1, &vp, cmd); device->BindResource(PS, getReflectionsEnabled() ? &rtReflection : wiTextureHelper::getTransparent(), TEXSLOT_RENDERPATH_REFLECTION, cmd); - device->BindResource(PS, getSSAOEnabled() ? &rtSSAO[0] : wiTextureHelper::getWhite(), TEXSLOT_RENDERPATH_SSAO, cmd); + device->BindResource(PS, getAOEnabled() ? &rtSSAO[0] : wiTextureHelper::getWhite(), TEXSLOT_RENDERPATH_SSAO, cmd); device->BindResource(PS, getSSREnabled() ? &rtSSR : wiTextureHelper::getTransparent(), TEXSLOT_RENDERPATH_SSR, cmd); wiRenderer::DrawScene(wiRenderer::GetCamera(), getTessellationEnabled(), cmd, RENDERPASS_TILEDFORWARD, true, true); wiRenderer::DrawSky(cmd); diff --git a/WickedEngine/RenderPath3D_TiledForward_BindLua.cpp b/WickedEngine/RenderPath3D_TiledForward_BindLua.cpp index 20fcf4f69..71b8deba6 100644 --- a/WickedEngine/RenderPath3D_TiledForward_BindLua.cpp +++ b/WickedEngine/RenderPath3D_TiledForward_BindLua.cpp @@ -25,6 +25,7 @@ Luna::FunctionType RenderPath3D_TiledForward_ lunamethod(RenderPath_BindLua, SetLayerMask), lunamethod(RenderPath3D_BindLua, SetSSAOEnabled), + lunamethod(RenderPath3D_BindLua, SetHBAOEnabled), lunamethod(RenderPath3D_BindLua, SetSSREnabled), lunamethod(RenderPath3D_BindLua, SetShadowsEnabled), lunamethod(RenderPath3D_BindLua, SetReflectionsEnabled), diff --git a/WickedEngine/ShaderInterop_Postprocess.h b/WickedEngine/ShaderInterop_Postprocess.h index 1165290fb..bba8482b9 100644 --- a/WickedEngine/ShaderInterop_Postprocess.h +++ b/WickedEngine/ShaderInterop_Postprocess.h @@ -24,6 +24,12 @@ CBUFFER(PostProcessCB, CBSLOT_RENDERER_POSTPROCESS) #define ssao_samplecount xPPParams0.y #define ssao_power xPPParams0.z +static const uint POSTPROCESS_HBAO_THREADCOUNT = 256; +#define hbao_direction xPPParams0.xy +#define hbao_power xPPParams0.z +#define hbao_uv_to_view_A xPPParams1.xy +#define hbao_uv_to_view_B xPPParams1.zw + static const uint MOTIONBLUR_TILESIZE = 32; #define motionblur_strength xPPParams0.x diff --git a/WickedEngine/WickedEngine_SHADERS.vcxproj b/WickedEngine/WickedEngine_SHADERS.vcxproj index aee6e7a4b..65b3d7ec9 100644 --- a/WickedEngine/WickedEngine_SHADERS.vcxproj +++ b/WickedEngine/WickedEngine_SHADERS.vcxproj @@ -49,14 +49,42 @@ Compute 5.0 + + Compute + 5.0 + Compute 5.0 + + Compute + 5.0 + + + Compute + 5.0 + + + Compute + 5.0 + + + Compute + 5.0 + + + Compute + 5.0 + Compute 5.0 + + Compute + 5.0 + Compute 5.0 @@ -65,6 +93,26 @@ Compute 5.0 + + Compute + 5.0 + + + Compute + 5.0 + + + Compute + 5.0 + + + Compute + 5.0 + + + Compute + 5.0 + Pixel @@ -345,6 +393,10 @@ Compute 5.0 + + Compute + 5.0 + Pixel 5.0 diff --git a/WickedEngine/WickedEngine_SHADERS.vcxproj.filters b/WickedEngine/WickedEngine_SHADERS.vcxproj.filters index a81e5a5eb..310adc4c9 100644 --- a/WickedEngine/WickedEngine_SHADERS.vcxproj.filters +++ b/WickedEngine/WickedEngine_SHADERS.vcxproj.filters @@ -873,6 +873,45 @@ PS + + CS + + + CS + + + CS + + + CS + + + CS + + + CS + + + CS + + + CS + + + CS + + + CS + + + CS + + + CS + + + CS + diff --git a/WickedEngine/blur_bilateral_float3CS.hlsl b/WickedEngine/blur_bilateral_float3CS.hlsl new file mode 100644 index 000000000..41ab9263f --- /dev/null +++ b/WickedEngine/blur_bilateral_float3CS.hlsl @@ -0,0 +1,2 @@ +#define BLUR_FORMAT float3 +#include "blur_bilateral_float4CS.hlsl" diff --git a/WickedEngine/blur_bilateral_wide_float1CS.hlsl b/WickedEngine/blur_bilateral_wide_float1CS.hlsl new file mode 100644 index 000000000..8e21a2d80 --- /dev/null +++ b/WickedEngine/blur_bilateral_wide_float1CS.hlsl @@ -0,0 +1,3 @@ +#define BLUR_FORMAT float +#define BLUR_WIDE +#include "blur_bilateral_float4CS.hlsl" diff --git a/WickedEngine/blur_bilateral_wide_float3CS.hlsl b/WickedEngine/blur_bilateral_wide_float3CS.hlsl new file mode 100644 index 000000000..d11bf18b4 --- /dev/null +++ b/WickedEngine/blur_bilateral_wide_float3CS.hlsl @@ -0,0 +1,3 @@ +#define BLUR_FORMAT float3 +#define BLUR_WIDE +#include "blur_bilateral_float4CS.hlsl" diff --git a/WickedEngine/blur_bilateral_wide_float4CS.hlsl b/WickedEngine/blur_bilateral_wide_float4CS.hlsl new file mode 100644 index 000000000..a5d3ea33b --- /dev/null +++ b/WickedEngine/blur_bilateral_wide_float4CS.hlsl @@ -0,0 +1,2 @@ +#define BLUR_WIDE +#include "blur_bilateral_float4CS.hlsl" diff --git a/WickedEngine/blur_bilateral_wide_unorm1CS.hlsl b/WickedEngine/blur_bilateral_wide_unorm1CS.hlsl new file mode 100644 index 000000000..2e626870e --- /dev/null +++ b/WickedEngine/blur_bilateral_wide_unorm1CS.hlsl @@ -0,0 +1,3 @@ +#define BLUR_FORMAT unorm float +#define BLUR_WIDE +#include "blur_bilateral_float4CS.hlsl" diff --git a/WickedEngine/blur_bilateral_wide_unorm4CS.hlsl b/WickedEngine/blur_bilateral_wide_unorm4CS.hlsl new file mode 100644 index 000000000..9a32fcab4 --- /dev/null +++ b/WickedEngine/blur_bilateral_wide_unorm4CS.hlsl @@ -0,0 +1,3 @@ +#define BLUR_FORMAT unorm float4 +#define BLUR_WIDE +#include "blur_bilateral_float4CS.hlsl" diff --git a/WickedEngine/blur_gaussian_float3CS.hlsl b/WickedEngine/blur_gaussian_float3CS.hlsl new file mode 100644 index 000000000..a3c3b9971 --- /dev/null +++ b/WickedEngine/blur_gaussian_float3CS.hlsl @@ -0,0 +1,2 @@ +#define BLUR_FORMAT float3 +#include "blur_gaussian_float4CS.hlsl" diff --git a/WickedEngine/blur_gaussian_float4CS.hlsl b/WickedEngine/blur_gaussian_float4CS.hlsl index c0c8c4272..407d50da8 100644 --- a/WickedEngine/blur_gaussian_float4CS.hlsl +++ b/WickedEngine/blur_gaussian_float4CS.hlsl @@ -9,7 +9,106 @@ TEXTURE2D(input, BLUR_FORMAT, TEXSLOT_ONDEMAND0); RWTEXTURE2D(output, BLUR_FORMAT, 0); -static const int TILE_BORDER = 4; +// Calculate gaussian weights online: http://dev.theomader.com/gaussian-kernel-calculator/ +#ifdef BLUR_WIDE +static const int GAUSS_KERNEL = 33; +static const float gaussianWeightsNormalized[GAUSS_KERNEL] = { + 0.004013, + 0.005554, + 0.007527, + 0.00999, + 0.012984, + 0.016524, + 0.020594, + 0.025133, + 0.030036, + 0.035151, + 0.040283, + 0.045207, + 0.049681, + 0.053463, + 0.056341, + 0.058141, + 0.058754, + 0.058141, + 0.056341, + 0.053463, + 0.049681, + 0.045207, + 0.040283, + 0.035151, + 0.030036, + 0.025133, + 0.020594, + 0.016524, + 0.012984, + 0.00999, + 0.007527, + 0.005554, + 0.004013 +}; +static const int gaussianOffsets[GAUSS_KERNEL] = { + -16, + -15, + -14, + -13, + -12, + -11, + -10, + -9, + -8, + -7, + -6, + -5, + -4, + -3, + -2, + -1, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, +}; +#else +static const int GAUSS_KERNEL = 9; +static const float gaussianWeightsNormalized[GAUSS_KERNEL] = { + 0.004112, + 0.026563, + 0.100519, + 0.223215, + 0.29118, + 0.223215, + 0.100519, + 0.026563, + 0.004112 +}; +static const int gaussianOffsets[GAUSS_KERNEL] = { + -4, + -3, + -2, + -1, + 0, + 1, + 2, + 3, + 4 +}; +#endif // BLUR_WIDE + +static const int TILE_BORDER = GAUSS_KERNEL / 2; static const int CACHE_SIZE = TILE_BORDER + POSTPROCESS_BLUR_GAUSSIAN_THREADCOUNT + TILE_BORDER; groupshared BLUR_FORMAT color_cache[CACHE_SIZE]; @@ -17,27 +116,6 @@ groupshared BLUR_FORMAT color_cache[CACHE_SIZE]; groupshared float depth_cache[CACHE_SIZE]; #endif // BILATERAL -static const float gaussWeight0 = 1.0f; -static const float gaussWeight1 = 0.9f; -static const float gaussWeight2 = 0.55f; -static const float gaussWeight3 = 0.18f; -static const float gaussWeight4 = 0.1f; -static const float gaussNormalization = 1.0f / (gaussWeight0 + 2.0f * (gaussWeight1 + gaussWeight2 + gaussWeight3 + gaussWeight4)); -static const float gaussianWeightsNormalized[9] = { - gaussWeight4 * gaussNormalization, - gaussWeight3 * gaussNormalization, - gaussWeight2 * gaussNormalization, - gaussWeight1 * gaussNormalization, - gaussWeight0 * gaussNormalization, - gaussWeight1 * gaussNormalization, - gaussWeight2 * gaussNormalization, - gaussWeight3 * gaussNormalization, - gaussWeight4 * gaussNormalization, -}; -static const int gaussianOffsets[9] = { - -4, -3, -2, -1, 0, 1, 2, 3, 4 -}; - [numthreads(POSTPROCESS_BLUR_GAUSSIAN_THREADCOUNT, 1, 1)] void main(uint3 Gid : SV_GroupID, uint groupIndex : SV_GroupIndex) { @@ -81,7 +159,7 @@ void main(uint3 Gid : SV_GroupID, uint groupIndex : SV_GroupIndex) #endif // BILATERAL BLUR_FORMAT color = 0; - for (i = 0; i < 9; ++i) + for (i = 0; i < GAUSS_KERNEL; ++i) { const uint sam = center + gaussianOffsets[i]; const BLUR_FORMAT color2 = color_cache[sam]; diff --git a/WickedEngine/blur_gaussian_wide_float1CS.hlsl b/WickedEngine/blur_gaussian_wide_float1CS.hlsl new file mode 100644 index 000000000..c72fe6875 --- /dev/null +++ b/WickedEngine/blur_gaussian_wide_float1CS.hlsl @@ -0,0 +1,3 @@ +#define BLUR_FORMAT float +#define BLUR_WIDE +#include "blur_gaussian_float4CS.hlsl" diff --git a/WickedEngine/blur_gaussian_wide_float3CS.hlsl b/WickedEngine/blur_gaussian_wide_float3CS.hlsl new file mode 100644 index 000000000..61eddf68e --- /dev/null +++ b/WickedEngine/blur_gaussian_wide_float3CS.hlsl @@ -0,0 +1,3 @@ +#define BLUR_FORMAT float3 +#define BLUR_WIDE +#include "blur_gaussian_float4CS.hlsl" diff --git a/WickedEngine/blur_gaussian_wide_float4CS.hlsl b/WickedEngine/blur_gaussian_wide_float4CS.hlsl new file mode 100644 index 000000000..750ce9315 --- /dev/null +++ b/WickedEngine/blur_gaussian_wide_float4CS.hlsl @@ -0,0 +1,2 @@ +#define BLUR_WIDE +#include "blur_gaussian_float4CS.hlsl" diff --git a/WickedEngine/blur_gaussian_wide_unorm1CS.hlsl b/WickedEngine/blur_gaussian_wide_unorm1CS.hlsl new file mode 100644 index 000000000..131666c5c --- /dev/null +++ b/WickedEngine/blur_gaussian_wide_unorm1CS.hlsl @@ -0,0 +1,3 @@ +#define BLUR_FORMAT unorm float +#define BLUR_WIDE +#include "blur_gaussian_float4CS.hlsl" diff --git a/WickedEngine/blur_gaussian_wide_unorm4CS.hlsl b/WickedEngine/blur_gaussian_wide_unorm4CS.hlsl new file mode 100644 index 000000000..f3aca8ab4 --- /dev/null +++ b/WickedEngine/blur_gaussian_wide_unorm4CS.hlsl @@ -0,0 +1,3 @@ +#define BLUR_FORMAT unorm float4 +#define BLUR_WIDE +#include "blur_gaussian_float4CS.hlsl" diff --git a/WickedEngine/hbaoCS.hlsl b/WickedEngine/hbaoCS.hlsl new file mode 100644 index 000000000..577a86154 --- /dev/null +++ b/WickedEngine/hbaoCS.hlsl @@ -0,0 +1,145 @@ +#include "globals.hlsli" +#include "ShaderInterop_Postprocess.h" + +TEXTURE2D(texture_lineardepth_minmax, float2, TEXSLOT_ONDEMAND0); +TEXTURE2D(texture_horizontalpass, float, TEXSLOT_ONDEMAND1); + +RWTEXTURE2D(output, unorm float, 0); + +// Step size in number of pixels +#define STEP_SIZE 6 +// Number of shared-memory samples per direction +#define NUM_STEPS 16 +// The last sample has weight = exp(-KERNEL_FALLOFF) +#define KERNEL_FALLOFF 3.0f +#define TAN_ANGLE_BIAS 0 +#define DEPTH_FIX 2.0f + +static const int TILE_BORDER = NUM_STEPS * STEP_SIZE; +static const int CACHE_SIZE = TILE_BORDER + POSTPROCESS_HBAO_THREADCOUNT + TILE_BORDER; +groupshared float2 cache[CACHE_SIZE]; + + +float Tangent(float2 V) +{ + // Add an epsilon to avoid any division by zero. + return -V.y / (abs(V.x) + 1.e-6f); +} + +float TanToSin(float x) +{ + return x * rsqrt(x * x + 1.0f); +} + +float Falloff(float sampleId) +{ + float r = sampleId / (NUM_STEPS - 1); + return exp(-KERNEL_FALLOFF * r * r); +} + +float2 MinDiff(float2 P, float2 Pr, float2 Pl) +{ + float2 V1 = Pr - P; + float2 V2 = P - Pl; + return (dot(V1, V1) < dot(V2, V2)) ? V1 : V2; +} + +// Compute the HBAO contribution in a given direction on screen by fetching 2D +// view-space coordinates available in shared memory: +// - (X,Z) for the horizontal directions (approximating Y by a constant). +// - (Y,Z) for the vertical directions (approximating X by a constant). +void IntegrateDirection(inout float ao, + float2 P, + float tanT, + int threadId, + int X0, + int deltaX) +{ + float tanH = tanT; + float sinH = TanToSin(tanH); + float sinT = TanToSin(tanT); + + [unroll] + for (int sampleId = 0; sampleId < NUM_STEPS; ++sampleId) + { + float2 S = cache[threadId + sampleId * deltaX + X0]; + float2 V = S - P; + float tanS = Tangent(V); + float d2 = dot(V, V); + + [flatten] + if ((d2 < DEPTH_FIX) && (tanS > tanH)) + { + // Accumulate AO between the horizon and the sample + float sinS = TanToSin(tanS); + ao += Falloff(sampleId) * (sinS - sinH); + + // Update the current horizon angle + tanH = tanS; + sinH = sinS; + } + } +} + +// Bias tangent angle and compute HBAO in the +X/-X or +Y/-Y directions. +float ComputeHBAO(float2 P, float2 T, int centerId) +{ + float ao = 0; + float tanT = Tangent(T); + IntegrateDirection(ao, P, tanT + TAN_ANGLE_BIAS, centerId, STEP_SIZE, STEP_SIZE); + IntegrateDirection(ao, P, -tanT + TAN_ANGLE_BIAS, centerId, -STEP_SIZE, -STEP_SIZE); + return ao; +} + +[numthreads(POSTPROCESS_HBAO_THREADCOUNT, 1, 1)] +void main(uint3 Gid : SV_GroupID, uint groupIndex : SV_GroupIndex) +{ + const bool horizontal = hbao_direction.y == 0; + + uint2 tile_start = Gid.xy; + [flatten] + if (horizontal) + { + tile_start.x *= POSTPROCESS_HBAO_THREADCOUNT; + } + else + { + tile_start.y *= POSTPROCESS_HBAO_THREADCOUNT; + } + + int i; + for (i = groupIndex; i < CACHE_SIZE; i += POSTPROCESS_HBAO_THREADCOUNT) + { + const uint2 pixel = tile_start + hbao_direction * (i - TILE_BORDER); + const float2 uv = (pixel + 0.5f) * xPPResolution_rcp; + const float z = texture_lineardepth_minmax[tile_start + hbao_direction * (i - TILE_BORDER)].g * g_xCamera_ZFarP; + const float2 xy = (hbao_uv_to_view_A * uv + hbao_uv_to_view_B) * z; + cache[i] = float2(horizontal ? xy.x : xy.y, z); + } + GroupMemoryBarrierWithGroupSync(); + + const uint2 pixel = tile_start + groupIndex * hbao_direction; + if (pixel.x >= xPPResolution.x || pixel.y >= xPPResolution.y) + { + return; + } + + const int center = TILE_BORDER + groupIndex; + + float2 sample_left = cache[center - 1]; + float2 sample_center = cache[center]; + float2 sample_right = cache[center + 1]; + + float2 T = MinDiff(sample_center, sample_right, sample_left); + + float ao = ComputeHBAO(sample_center, T, center); + + if (!horizontal) + { + // vertical pass combines results: + ao = (ao + texture_horizontalpass[pixel]) * 0.25f; + ao = pow(saturate(1 - ao), hbao_power); + } + + output[pixel] = ao; +} diff --git a/WickedEngine/lineardepthCS.hlsl b/WickedEngine/lineardepthCS.hlsl index c5da8f5b7..683dc1d35 100644 --- a/WickedEngine/lineardepthCS.hlsl +++ b/WickedEngine/lineardepthCS.hlsl @@ -4,12 +4,12 @@ TEXTURE2D(input, float, TEXSLOT_ONDEMAND0); -RWTEXTURE2D(output_fullres, unorm float, 0); -RWTEXTURE2D(output_minmax_mip0, unorm float2, 1); -RWTEXTURE2D(output_minmax_mip1, unorm float2, 2); -RWTEXTURE2D(output_minmax_mip2, unorm float2, 3); -RWTEXTURE2D(output_minmax_mip3, unorm float2, 4); -RWTEXTURE2D(output_minmax_mip4, unorm float2, 5); +RWTEXTURE2D(output_fullres, float, 0); +RWTEXTURE2D(output_minmax_mip0, float2, 1); +RWTEXTURE2D(output_minmax_mip1, float2, 2); +RWTEXTURE2D(output_minmax_mip2, float2, 3); +RWTEXTURE2D(output_minmax_mip3, float2, 4); +RWTEXTURE2D(output_minmax_mip4, float2, 5); groupshared float tile_min[POSTPROCESS_LINEARDEPTH_BLOCKSIZE][POSTPROCESS_LINEARDEPTH_BLOCKSIZE]; groupshared float tile_max[POSTPROCESS_LINEARDEPTH_BLOCKSIZE][POSTPROCESS_LINEARDEPTH_BLOCKSIZE]; diff --git a/WickedEngine/wiEnums.h b/WickedEngine/wiEnums.h index 412bc199e..6da548693 100644 --- a/WickedEngine/wiEnums.h +++ b/WickedEngine/wiEnums.h @@ -290,14 +290,27 @@ enum CSTYPES CSTYPE_RAYTRACE_SHADE, CSTYPE_RAYTRACE_TILESORT, CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_FLOAT1, + CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_FLOAT3, CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_FLOAT4, CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_UNORM1, CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_UNORM4, + CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_WIDE_FLOAT1, + CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_WIDE_FLOAT3, + CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_WIDE_FLOAT4, + CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_WIDE_UNORM1, + CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_WIDE_UNORM4, CSTYPE_POSTPROCESS_BLUR_BILATERAL_FLOAT1, + CSTYPE_POSTPROCESS_BLUR_BILATERAL_FLOAT3, CSTYPE_POSTPROCESS_BLUR_BILATERAL_FLOAT4, CSTYPE_POSTPROCESS_BLUR_BILATERAL_UNORM1, CSTYPE_POSTPROCESS_BLUR_BILATERAL_UNORM4, + CSTYPE_POSTPROCESS_BLUR_BILATERAL_WIDE_FLOAT1, + CSTYPE_POSTPROCESS_BLUR_BILATERAL_WIDE_FLOAT3, + CSTYPE_POSTPROCESS_BLUR_BILATERAL_WIDE_FLOAT4, + CSTYPE_POSTPROCESS_BLUR_BILATERAL_WIDE_UNORM1, + CSTYPE_POSTPROCESS_BLUR_BILATERAL_WIDE_UNORM4, CSTYPE_POSTPROCESS_SSAO, + CSTYPE_POSTPROCESS_HBAO, CSTYPE_POSTPROCESS_SSR_RAYTRACE, CSTYPE_POSTPROCESS_SSR_RESOLVE, CSTYPE_POSTPROCESS_SSR_TEMPORAL, diff --git a/WickedEngine/wiRenderer.cpp b/WickedEngine/wiRenderer.cpp index 25fec4c5a..0703b06f2 100644 --- a/WickedEngine/wiRenderer.cpp +++ b/WickedEngine/wiRenderer.cpp @@ -1324,14 +1324,27 @@ void LoadShaders() wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_RAYTRACE_TILESORT], "raytrace_tilesortCS.cso"); }); wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_FLOAT1], "blur_gaussian_float1CS.cso"); }); + wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_FLOAT3], "blur_gaussian_float3CS.cso"); }); wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_FLOAT4], "blur_gaussian_float4CS.cso"); }); wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_UNORM1], "blur_gaussian_unorm1CS.cso"); }); wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_UNORM4], "blur_gaussian_unorm4CS.cso"); }); + wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_WIDE_FLOAT1], "blur_gaussian_wide_float1CS.cso"); }); + wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_WIDE_FLOAT3], "blur_gaussian_wide_float3CS.cso"); }); + wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_WIDE_FLOAT4], "blur_gaussian_wide_float4CS.cso"); }); + wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_WIDE_UNORM1], "blur_gaussian_wide_unorm1CS.cso"); }); + wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_WIDE_UNORM4], "blur_gaussian_wide_unorm4CS.cso"); }); wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_BILATERAL_FLOAT1], "blur_bilateral_float1CS.cso"); }); + wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_BILATERAL_FLOAT3], "blur_bilateral_float3CS.cso"); }); wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_BILATERAL_FLOAT4], "blur_bilateral_float4CS.cso"); }); wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_BILATERAL_UNORM1], "blur_bilateral_unorm1CS.cso"); }); wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_BILATERAL_UNORM4], "blur_bilateral_unorm4CS.cso"); }); + wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_BILATERAL_WIDE_FLOAT1], "blur_bilateral_wide_float1CS.cso"); }); + wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_BILATERAL_WIDE_FLOAT3], "blur_bilateral_wide_float3CS.cso"); }); + wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_BILATERAL_WIDE_FLOAT4], "blur_bilateral_wide_float4CS.cso"); }); + wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_BILATERAL_WIDE_UNORM1], "blur_bilateral_wide_unorm1CS.cso"); }); + wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_BLUR_BILATERAL_WIDE_UNORM4], "blur_bilateral_wide_unorm4CS.cso"); }); wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_SSAO], "ssaoCS.cso"); }); + wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_HBAO], "hbaoCS.cso"); }); wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_SSR_RAYTRACE], "ssr_raytraceCS.cso"); }); wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_SSR_RESOLVE], "ssr_resolveCS.cso"); }); wiJobSystem::Execute(ctx, [] { LoadShader(CS, computeShaders[CSTYPE_POSTPROCESS_SSR_TEMPORAL], "ssr_temporalCS.cso"); }); @@ -8537,7 +8550,8 @@ void Postprocess_Blur_Gaussian( const Texture& output, CommandList cmd, int mip_src, - int mip_dst + int mip_dst, + bool wide ) { GraphicsDevice* device = GetDevice(); @@ -8548,21 +8562,23 @@ void Postprocess_Blur_Gaussian( { case FORMAT_R16_UNORM: case FORMAT_R8_UNORM: - cs = CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_UNORM1; + cs = wide ? CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_WIDE_UNORM1 : CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_UNORM1; break; case FORMAT_R16_FLOAT: case FORMAT_R32_FLOAT: - cs = CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_FLOAT1; + cs = wide ? CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_WIDE_FLOAT1 : CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_FLOAT1; break; case FORMAT_R16G16B16A16_UNORM: case FORMAT_R8G8B8A8_UNORM: case FORMAT_R10G10B10A2_UNORM: - cs = CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_UNORM4; + cs = wide ? CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_WIDE_UNORM4 : CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_UNORM4; break; case FORMAT_R11G11B10_FLOAT: + cs = wide ? CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_WIDE_FLOAT3 : CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_FLOAT3; + break; case FORMAT_R16G16B16A16_FLOAT: case FORMAT_R32G32B32A32_FLOAT: - cs = CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_FLOAT4; + cs = wide ? CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_WIDE_FLOAT4 : CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_FLOAT4; break; default: assert(0); // implement format! @@ -8645,7 +8661,8 @@ void Postprocess_Blur_Bilateral( CommandList cmd, float depth_threshold, int mip_src, - int mip_dst + int mip_dst, + bool wide ) { GraphicsDevice* device = GetDevice(); @@ -8657,21 +8674,23 @@ void Postprocess_Blur_Bilateral( { case FORMAT_R16_UNORM: case FORMAT_R8_UNORM: - cs = CSTYPE_POSTPROCESS_BLUR_BILATERAL_UNORM1; + cs = wide ? CSTYPE_POSTPROCESS_BLUR_BILATERAL_WIDE_UNORM1 : CSTYPE_POSTPROCESS_BLUR_BILATERAL_UNORM1; break; case FORMAT_R16_FLOAT: case FORMAT_R32_FLOAT: - cs = CSTYPE_POSTPROCESS_BLUR_BILATERAL_FLOAT1; + cs = wide ? CSTYPE_POSTPROCESS_BLUR_BILATERAL_WIDE_FLOAT1 : CSTYPE_POSTPROCESS_BLUR_BILATERAL_FLOAT1; break; case FORMAT_R16G16B16A16_UNORM: case FORMAT_R8G8B8A8_UNORM: case FORMAT_R10G10B10A2_UNORM: - cs = CSTYPE_POSTPROCESS_BLUR_BILATERAL_UNORM4; + cs = wide ? CSTYPE_POSTPROCESS_BLUR_BILATERAL_WIDE_UNORM4 : CSTYPE_POSTPROCESS_BLUR_BILATERAL_UNORM4; break; case FORMAT_R11G11B10_FLOAT: + cs = wide ? CSTYPE_POSTPROCESS_BLUR_BILATERAL_WIDE_FLOAT3 : CSTYPE_POSTPROCESS_BLUR_BILATERAL_FLOAT3; + break; case FORMAT_R16G16B16A16_FLOAT: case FORMAT_R32G32B32A32_FLOAT: - cs = CSTYPE_POSTPROCESS_BLUR_BILATERAL_FLOAT4; + cs = wide ? CSTYPE_POSTPROCESS_BLUR_BILATERAL_WIDE_FLOAT4 : CSTYPE_POSTPROCESS_BLUR_BILATERAL_FLOAT4; break; default: assert(0); // implement format! @@ -8803,7 +8822,103 @@ void Postprocess_SSAO( device->Barrier(&GPUBarrier::Memory(), 1, cmd); device->UnbindUAVs(0, arraysize(uavs), cmd); - Postprocess_Blur_Bilateral(output, lineardepth, temp, output, cmd, 1.2f); + Postprocess_Blur_Bilateral(output, lineardepth_minmax, temp, output, cmd, 1.2f, -1, -1, true); + + wiProfiler::EndRange(prof_range); + device->EventEnd(cmd); +} +void Postprocess_HBAO( + const Texture& lineardepth_minmax, + const Texture& temp, + const Texture& output, + CommandList cmd, + float power +) +{ + GraphicsDevice* device = GetDevice(); + + device->EventBegin("Postprocess_HBAO", cmd); + auto prof_range = wiProfiler::BeginRangeGPU("HBAO", cmd); + + device->UnbindResources(TEXSLOT_RENDERPATH_SSAO, 1, cmd); + + device->BindComputeShader(&computeShaders[CSTYPE_POSTPROCESS_HBAO], cmd); + + device->BindResource(CS, &lineardepth_minmax, TEXSLOT_ONDEMAND0, cmd); + + const TextureDesc& desc = output.GetDesc(); + + PostProcessCB cb; + cb.xPPResolution.x = desc.Width; + cb.xPPResolution.y = desc.Height; + cb.xPPResolution_rcp.x = 1.0f / cb.xPPResolution.x; + cb.xPPResolution_rcp.y = 1.0f / cb.xPPResolution.y; + cb.xPPParams0.x = 1; + cb.xPPParams0.y = 0; + cb.hbao_power = power; + + const CameraComponent& camera = GetCamera(); + const float FocalLenX = 1.0f / tanf(camera.fov * 0.5f) * ((float)cb.xPPResolution.y / (float)cb.xPPResolution.x); + const float FocalLenY = 1.0f / tanf(camera.fov * 0.5f); + const float InvFocalLenX = 1.0f / FocalLenX; + const float InvFocalLenY = 1.0f / FocalLenY; + const float UVToViewAX = 2.0f * InvFocalLenX; + const float UVToViewAY = -2.0f * InvFocalLenY; + const float UVToViewBX = -1.0f * InvFocalLenX; + const float UVToViewBY = 1.0f * InvFocalLenY; + cb.xPPParams1.x = UVToViewAX; + cb.xPPParams1.y = UVToViewAY; + cb.xPPParams1.z = UVToViewBX; + cb.xPPParams1.w = UVToViewBY; + + device->UpdateBuffer(&constantBuffers[CBTYPE_POSTPROCESS], &cb, cmd); + device->BindConstantBuffer(CS, &constantBuffers[CBTYPE_POSTPROCESS], CB_GETBINDSLOT(PostProcessCB), cmd); + + // horizontal pass: + { + device->BindResource(CS, wiTextureHelper::getWhite(), TEXSLOT_ONDEMAND1, cmd); + const GPUResource* uavs[] = { + &temp, + }; + device->BindUAVs(CS, uavs, 0, arraysize(uavs), cmd); + + device->Dispatch( + (cb.xPPResolution.x + POSTPROCESS_HBAO_THREADCOUNT - 1) / POSTPROCESS_HBAO_THREADCOUNT, + cb.xPPResolution.y, + 1, + cmd + ); + + device->Barrier(&GPUBarrier::Memory(), 1, cmd); + device->UnbindUAVs(0, arraysize(uavs), cmd); + } + + // vertical pass: + { + cb.xPPParams0.x = 0; + cb.xPPParams0.y = 1; + device->UpdateBuffer(&constantBuffers[CBTYPE_POSTPROCESS], &cb, cmd); + device->BindConstantBuffer(CS, &constantBuffers[CBTYPE_POSTPROCESS], CB_GETBINDSLOT(PostProcessCB), cmd); + + device->BindResource(CS, &temp, TEXSLOT_ONDEMAND1, cmd); + const GPUResource* uavs[] = { + &output, + }; + device->BindUAVs(CS, uavs, 0, arraysize(uavs), cmd); + + device->Dispatch( + cb.xPPResolution.x, + (cb.xPPResolution.y + POSTPROCESS_HBAO_THREADCOUNT - 1) / POSTPROCESS_HBAO_THREADCOUNT, + 1, + cmd + ); + + device->Barrier(&GPUBarrier::Memory(), 1, cmd); + device->UnbindUAVs(0, arraysize(uavs), cmd); + device->UnbindResources(TEXSLOT_ONDEMAND1, 1, cmd); + } + + Postprocess_Blur_Bilateral(output, lineardepth_minmax, temp, output, cmd, 1.2f, -1, -1, true); wiProfiler::EndRange(prof_range); device->EventEnd(cmd); diff --git a/WickedEngine/wiRenderer.h b/WickedEngine/wiRenderer.h index 5b8c9454f..0c374d977 100644 --- a/WickedEngine/wiRenderer.h +++ b/WickedEngine/wiRenderer.h @@ -174,7 +174,8 @@ namespace wiRenderer const wiGraphics::Texture& output, wiGraphics::CommandList cmd, int mip_src = -1, - int mip_dst = -1 + int mip_dst = -1, + bool wide = false ); void Postprocess_Blur_Bilateral( const wiGraphics::Texture& input, @@ -184,7 +185,8 @@ namespace wiRenderer wiGraphics::CommandList cmd, float depth_threshold = 1.0f, int mip_src = -1, - int mip_dst = -1 + int mip_dst = -1, + bool wide = false ); void Postprocess_SSAO( const wiGraphics::Texture& depthbuffer, @@ -197,6 +199,13 @@ namespace wiRenderer uint32_t samplecount = 16, float power = 2.0f ); + void Postprocess_HBAO( + const wiGraphics::Texture& lineardepth_minmax, + const wiGraphics::Texture& temp, + const wiGraphics::Texture& output, + wiGraphics::CommandList cmd, + float power = 2.0f + ); void Postprocess_SSR( const wiGraphics::Texture& input, const wiGraphics::Texture& depthbuffer, diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index 0d0747916..41b6d3245 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -9,7 +9,7 @@ namespace wiVersion // minor features, major updates const int minor = 38; // minor bug fixes, alterations, refactors, updates - const int revision = 22; + const int revision = 23; long GetVersion() diff --git a/features.txt b/features.txt index af23d4aeb..4dd2a776f 100644 --- a/features.txt +++ b/features.txt @@ -49,7 +49,7 @@ Controller feedback (vibration, LED) Backlog: log,input,scripting Gamma correct, HDR rendering Resource Manager -Screen Space Ambient Occlusion +Screen Space Ambient Occlusion (SSAO, HBAO) Screen Space Reflections Skin shader (Subsurface scattering) Stencil layering