diff --git a/Editor/PostprocessWindow.cpp b/Editor/PostprocessWindow.cpp index 5353c1430..b729f3885 100644 --- a/Editor/PostprocessWindow.cpp +++ b/Editor/PostprocessWindow.cpp @@ -18,10 +18,10 @@ PostprocessWindow::PostprocessWindow(wiGUI* gui, RenderPath3D* comp) : GUI(gui), float screenH = (float)wiRenderer::GetDevice()->GetScreenHeight(); ppWindow = new wiWindow(GUI, "PostProcess Window"); - ppWindow->SetSize(XMFLOAT2(360, 660)); + ppWindow->SetSize(XMFLOAT2(400, 660)); GUI->AddWidget(ppWindow); - float x = 110; + float x = 150; float y = 0; exposureSlider = new wiSlider(0.0f, 3.0f, 1, 10000, "Exposure: "); @@ -295,8 +295,27 @@ PostprocessWindow::PostprocessWindow(wiGUI* gui, RenderPath3D* comp) : GUI(gui), }); ppWindow->AddWidget(outlineThicknessSlider); + chromaticaberrationCheckBox = new wiCheckBox("Chromatic Aberration: "); + chromaticaberrationCheckBox->SetTooltip("Toggle the full screen chromatic aberration effect. This simulates lens distortion at screen edges."); + chromaticaberrationCheckBox->SetPos(XMFLOAT2(x, y += 35)); + chromaticaberrationCheckBox->SetCheck(component->getOutlineEnabled()); + chromaticaberrationCheckBox->OnClick([&](wiEventArgs args) { + component->setChromaticAberrationEnabled(args.bValue); + }); + ppWindow->AddWidget(chromaticaberrationCheckBox); - ppWindow->Translate(XMFLOAT3(screenW - 500, 50, 0)); + chromaticaberrationSlider = new wiSlider(0, 4, 1.0f, 1000, "Amount: "); + chromaticaberrationSlider->SetTooltip("The lens distortion amount."); + chromaticaberrationSlider->SetSize(XMFLOAT2(100, 20)); + chromaticaberrationSlider->SetPos(XMFLOAT2(x + 100, y)); + chromaticaberrationSlider->SetValue(component->getChromaticAberrationAmount()); + chromaticaberrationSlider->OnSlide([&](wiEventArgs args) { + component->setChromaticAberrationAmount(args.fValue); + }); + ppWindow->AddWidget(chromaticaberrationSlider); + + + ppWindow->Translate(XMFLOAT3(screenW - 550, 50, 0)); ppWindow->SetVisible(false); } diff --git a/Editor/PostprocessWindow.h b/Editor/PostprocessWindow.h index 72dadd856..0ece1be09 100644 --- a/Editor/PostprocessWindow.h +++ b/Editor/PostprocessWindow.h @@ -42,6 +42,8 @@ public: wiCheckBox* outlineCheckBox; wiSlider* outlineThresholdSlider; wiSlider* outlineThicknessSlider; + wiCheckBox* chromaticaberrationCheckBox; + wiSlider* chromaticaberrationSlider; }; diff --git a/Editor/WeatherWindow.cpp b/Editor/WeatherWindow.cpp index d5b680f30..8cf1a70d2 100644 --- a/Editor/WeatherWindow.cpp +++ b/Editor/WeatherWindow.cpp @@ -18,7 +18,7 @@ WeatherWindow::WeatherWindow(wiGUI* gui) : GUI(gui) float screenH = (float)wiRenderer::GetDevice()->GetScreenHeight(); - weatherWindow = new wiWindow(GUI, "World Window"); + weatherWindow = new wiWindow(GUI, "Weather Window"); weatherWindow->SetSize(XMFLOAT2(760, 820)); GUI->AddWidget(weatherWindow); @@ -140,11 +140,25 @@ WeatherWindow::WeatherWindow(wiGUI* gui) : GUI(gui) + wiButton* preset0Button = new wiButton("WeatherPreset - Default"); + preset0Button->SetTooltip("Apply this weather preset to the world."); + preset0Button->SetSize(XMFLOAT2(240, 30)); + preset0Button->SetPos(XMFLOAT2(x - 100, y += step * 2)); + preset0Button->OnClick([=](wiEventArgs args) { + + Scene& scene = wiSceneSystem::GetScene(); + scene.weathers.Clear(); + scene.weather = WeatherComponent(); + + InvalidateProbes(); + + }); + weatherWindow->AddWidget(preset0Button); wiButton* preset1Button = new wiButton("WeatherPreset - Daytime"); preset1Button->SetTooltip("Apply this weather preset to the world."); preset1Button->SetSize(XMFLOAT2(240, 30)); - preset1Button->SetPos(XMFLOAT2(x - 100, y += step * 2)); + preset1Button->SetPos(XMFLOAT2(x - 100, y += step)); preset1Button->OnClick([=](wiEventArgs args) { auto& weather = GetWeather(); diff --git a/WickedEngine/RenderPath3D.cpp b/WickedEngine/RenderPath3D.cpp index 77048d06d..8f4102a55 100644 --- a/WickedEngine/RenderPath3D.cpp +++ b/WickedEngine/RenderPath3D.cpp @@ -697,5 +697,13 @@ void RenderPath3D::RenderPostprocessChain(const Texture2D& srcSceneRT, const Tex SwapPtr(rt_read, rt_write); device->UnbindResources(TEXSLOT_ONDEMAND0, 1, cmd); } + + if (getChromaticAberrationEnabled()) + { + wiRenderer::Postprocess_Chromatic_Aberration(*rt_read, *rt_write, cmd, getChromaticAberrationAmount()); + + SwapPtr(rt_read, rt_write); + device->UnbindResources(TEXSLOT_ONDEMAND0, 1, cmd); + } } } diff --git a/WickedEngine/RenderPath3D.h b/WickedEngine/RenderPath3D.h index 7c808d3bd..b0358ab3d 100644 --- a/WickedEngine/RenderPath3D.h +++ b/WickedEngine/RenderPath3D.h @@ -18,6 +18,7 @@ private: XMFLOAT3 outlineColor = XMFLOAT3(0, 0, 0); float ssaoRange = 1.0f; UINT ssaoSampleCount = 16; + float chromaticAberrationAmount = 2.0f; bool fxaaEnabled = false; bool ssaoEnabled = false; @@ -39,6 +40,7 @@ private: bool tessellationEnabled = false; bool sharpenFilterEnabled = false; bool outlineEnabled = false; + bool chromaticAberrationEnabled = false; const wiGraphics::Texture2D* colorGradingTex = nullptr; @@ -74,6 +76,7 @@ protected: ldr_postprocess_count += sharpenFilterEnabled ? 1 : 0; ldr_postprocess_count += colorGradingEnabled ? 1 : 0; ldr_postprocess_count += fxaaEnabled ? 1 : 0; + ldr_postprocess_count += chromaticAberrationEnabled ? 1 : 0; int rt_index = ldr_postprocess_count % 2; return &rtPostprocess_LDR[rt_index]; } @@ -112,6 +115,7 @@ public: inline XMFLOAT3 getOutlineColor() const { return outlineColor; } inline float getSSAORange() const { return ssaoRange; } inline UINT getSSAOSampleCount() const { return ssaoSampleCount; } + inline float getChromaticAberrationAmount() const { return chromaticAberrationAmount; } inline bool getSSAOEnabled() const { return ssaoEnabled; } inline bool getSSREnabled() const { return ssrEnabled; } @@ -133,6 +137,7 @@ public: inline bool getTessellationEnabled() const { return tessellationEnabled && wiRenderer::GetDevice()->CheckCapability(wiGraphics::GraphicsDevice::GRAPHICSDEVICE_CAPABILITY_TESSELLATION); } inline bool getSharpenFilterEnabled() const { return sharpenFilterEnabled && getSharpenFilterAmount() > 0; } inline bool getOutlineEnabled() const { return outlineEnabled; } + inline bool getChromaticAberrationEnabled() const { return chromaticAberrationEnabled; } inline const wiGraphics::Texture2D* getColorGradingTexture() const { return colorGradingTex; } @@ -149,6 +154,7 @@ public: inline void setOutlineColor(const XMFLOAT3& value) { outlineColor = value; } inline void setSSAORange(float value) { ssaoRange = value; } inline void setSSAOSampleCount(UINT value) { ssaoSampleCount = value; } + inline void setChromaticAberrationAmount(float value) { chromaticAberrationAmount = value; } inline void setSSAOEnabled(bool value){ ssaoEnabled = value; } inline void setSSREnabled(bool value){ ssrEnabled = value; } @@ -170,6 +176,7 @@ public: inline void setTessellationEnabled(bool value) { tessellationEnabled = value; } inline void setSharpenFilterEnabled(bool value) { sharpenFilterEnabled = value; } inline void setOutlineEnabled(bool value) { outlineEnabled = value; } + inline void setChromaticAberrationEnabled(bool value) { chromaticAberrationEnabled = value; } inline void setColorGradingTexture(const wiGraphics::Texture2D* tex) { colorGradingTex = tex; } diff --git a/WickedEngine/WickedEngine_SHADERS.vcxproj b/WickedEngine/WickedEngine_SHADERS.vcxproj index 36cccedc1..e2784263a 100644 --- a/WickedEngine/WickedEngine_SHADERS.vcxproj +++ b/WickedEngine/WickedEngine_SHADERS.vcxproj @@ -68,6 +68,10 @@ Pixel + + Compute + 5.0 + Pixel diff --git a/WickedEngine/WickedEngine_SHADERS.vcxproj.filters b/WickedEngine/WickedEngine_SHADERS.vcxproj.filters index 6306f5c4a..469e02be9 100644 --- a/WickedEngine/WickedEngine_SHADERS.vcxproj.filters +++ b/WickedEngine/WickedEngine_SHADERS.vcxproj.filters @@ -807,6 +807,9 @@ PS + + CS + diff --git a/WickedEngine/chromatic_aberrationCS.hlsl b/WickedEngine/chromatic_aberrationCS.hlsl new file mode 100644 index 000000000..8c5018006 --- /dev/null +++ b/WickedEngine/chromatic_aberrationCS.hlsl @@ -0,0 +1,27 @@ +#include "globals.hlsli" +#include "ShaderInterop_Postprocess.h" + +TEXTURE2D(input, float4, TEXSLOT_ONDEMAND0); + +RWTEXTURE2D(output, unorm 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 amount = xPPParams0.x; + + const float2 distortion = (uv - 0.5f) * amount * xPPResolution_rcp; + + const float2 uv_R = uv + float2(1, 1) * distortion; + const float2 uv_G = uv + float2(0, 0) * distortion; + const float2 uv_B = uv - float2(1, 1) * distortion; + + const float R = input.SampleLevel(sampler_linear_clamp, uv_R, 0).r; + const float G = input.SampleLevel(sampler_linear_clamp, uv_G, 0).g; + const float B = input.SampleLevel(sampler_linear_clamp, uv_B, 0).b; + + const float4 color = float4(R, G, B, 1); + + output[DTid.xy] = color; +} diff --git a/WickedEngine/wiEnums.h b/WickedEngine/wiEnums.h index 02013ea78..46dedab91 100644 --- a/WickedEngine/wiEnums.h +++ b/WickedEngine/wiEnums.h @@ -306,6 +306,7 @@ enum CSTYPES CSTYPE_POSTPROCESS_LINEARDEPTH, CSTYPE_POSTPROCESS_SHARPEN, CSTYPE_POSTPROCESS_TONEMAP, + CSTYPE_POSTPROCESS_CHROMATIC_ABERRATION, CSTYPE_LAST }; diff --git a/WickedEngine/wiRenderer.cpp b/WickedEngine/wiRenderer.cpp index 92124f9e4..e347a1101 100644 --- a/WickedEngine/wiRenderer.cpp +++ b/WickedEngine/wiRenderer.cpp @@ -2167,6 +2167,7 @@ void LoadShaders() computeShaders[CSTYPE_POSTPROCESS_LINEARDEPTH] = static_cast(wiResourceManager::GetShaderManager().add(SHADERPATH + "lineardepthCS.cso", wiResourceManager::COMPUTESHADER)); computeShaders[CSTYPE_POSTPROCESS_SHARPEN] = static_cast(wiResourceManager::GetShaderManager().add(SHADERPATH + "sharpenCS.cso", wiResourceManager::COMPUTESHADER)); computeShaders[CSTYPE_POSTPROCESS_TONEMAP] = static_cast(wiResourceManager::GetShaderManager().add(SHADERPATH + "tonemapCS.cso", wiResourceManager::COMPUTESHADER)); + computeShaders[CSTYPE_POSTPROCESS_CHROMATIC_ABERRATION] = static_cast(wiResourceManager::GetShaderManager().add(SHADERPATH + "chromatic_aberrationCS.cso", wiResourceManager::COMPUTESHADER)); hullShaders[HSTYPE_OBJECT] = static_cast(wiResourceManager::GetShaderManager().add(SHADERPATH + "objectHS.cso", wiResourceManager::HULLSHADER)); @@ -9342,6 +9343,52 @@ void Postprocess_Tonemap( device->BindUAVs(CS, uavs, 0, ARRAYSIZE(uavs), cmd); + device->Dispatch( + (desc.Width + POSTPROCESS_BLOCKSIZE - 1) / POSTPROCESS_BLOCKSIZE, + (desc.Height + POSTPROCESS_BLOCKSIZE - 1) / POSTPROCESS_BLOCKSIZE, + 1, + cmd + ); + + device->UAVBarrier(uavs, ARRAYSIZE(uavs), cmd); + device->UnbindUAVs(0, ARRAYSIZE(uavs), cmd); + + device->EventEnd(cmd); +} +void Postprocess_Chromatic_Aberration( + const Texture2D& input, + const Texture2D& output, + CommandList cmd, + float amount +) +{ + GraphicsDevice* device = GetDevice(); + + device->EventBegin("Postprocess_Chromatic_Aberration", cmd); + + device->BindRenderTargets(0, nullptr, nullptr, cmd); + + device->BindComputeShader(computeShaders[CSTYPE_POSTPROCESS_CHROMATIC_ABERRATION], cmd); + + device->BindResource(CS, &input, 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 = amount; + device->UpdateBuffer(&constantBuffers[CBTYPE_POSTPROCESS], &cb, cmd); + device->BindConstantBuffer(CS, &constantBuffers[CBTYPE_POSTPROCESS], CB_GETBINDSLOT(PostProcessCB), cmd); + + const GPUResource* uavs[] = { + &output, + }; + device->BindUAVs(CS, uavs, 0, ARRAYSIZE(uavs), cmd); + + device->Dispatch( (desc.Width + POSTPROCESS_BLOCKSIZE - 1) / POSTPROCESS_BLOCKSIZE, (desc.Height + POSTPROCESS_BLOCKSIZE - 1) / POSTPROCESS_BLOCKSIZE, diff --git a/WickedEngine/wiRenderer.h b/WickedEngine/wiRenderer.h index 87b821a01..ed74383ff 100644 --- a/WickedEngine/wiRenderer.h +++ b/WickedEngine/wiRenderer.h @@ -300,6 +300,12 @@ namespace wiRenderer wiGraphics::CommandList cmd, float exposure ); + void Postprocess_Chromatic_Aberration( + const wiGraphics::Texture2D& input, + const wiGraphics::Texture2D& output, + wiGraphics::CommandList cmd, + float amount = 1.0f + ); // Build the scene BVH on GPU that can be used by ray traced rendering void BuildSceneBVH(wiGraphics::CommandList cmd); diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index 6f975c490..284023999 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -9,7 +9,7 @@ namespace wiVersion // minor features, major updates const int minor = 28; // minor bug fixes, alterations, refactors, updates - const int revision = 21; + const int revision = 22; long GetVersion()