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()