Commit ac2edfc3 authored by AL's avatar AL

an ok on demand blur

parent 9a69a927
......@@ -9,7 +9,7 @@ void BlurManager::AddBlur(float blur)
void BlurManager::UpdateBlur(float dt)
{
pendingBlur *= (blurFalloff*dt);
pendingBlur = pendingBlur*(1.0f - blurFalloff*dt);
float coeff = blurChangeSensitivity * dt;
currentBlur = currentBlur * (1.0f - coeff) + pendingBlur * coeff;
if (currentBlur <= 0.001f)currentBlur = 0.0f;
......
Texture2D tex;
SamplerState splr;
cbuffer Kernel
{
uint nTaps;
float coefficients[15];
}
cbuffer Control
{
bool horizontal;
}
float4 main(float2 uv : Texcoord) : SV_Target
{
uint width, height;
tex.GetDimensions(width, height);
float dx, dy;
if (horizontal)
{
dx = 1.0f / width;
dy = 0.0f;
}
else
{
dx = 0.0f;
dy = 1.0f / height;
}
const int r = nTaps / 2;
float3 acc = { 0.0f, 0.0f, 0.0f };
for (int i = -r; i <= r; i++)
{
const float2 tc = uv + float2(dx * i, dy * i);
const float3 s = tex.Sample(splr, tc).rgb;
const float coef = coefficients[i + r];
acc += s * coef;
}
return float4(acc, 1);
}
\ No newline at end of file
#pragma once
#include "Framework/BindableCommon.h"
#include "Framework/ChiliMath.h"
#include "imgui/imgui.h"
class BlurPack
{
public:
BlurPack(DXGraphics& gfx, int radius = 7, float sigma = 2.6f, std::wstring shader = L"BlurPS.cso") :
shader(gfx, shader),
pcb(gfx, 0u),
ccb(gfx, 1u),
radius(radius),
sigma(sigma)
{
SetKernelGauss(gfx, radius, sigma);
}
void Bind(DXGraphics& gfx) noexcept
{
shader.Bind(gfx);
pcb.Bind(gfx);
ccb.Bind(gfx);
}
void SetHorizontal(DXGraphics& gfx)
{
ccb.Update(gfx, { TRUE });
}
void SetVertical(DXGraphics& gfx)
{
ccb.Update(gfx, { FALSE });
}
void RenderWidgets(DXGraphics& gfx)
{
bool filterChanged = false;
{
const char* items[] = { "Gauss","Box" };
static const char* curItem = items[0];
if (ImGui::BeginCombo("Filter Type", curItem))
{
for (UINT n = 0; n < std::size(items); n++)
{
const bool isSelected = (curItem == items[n]);
if (ImGui::Selectable(items[n], isSelected))
{
filterChanged = true;
curItem = items[n];
if (curItem == items[0])
{
kernelType = KernelType::Gauss;
}
else if (curItem == items[1])
{
kernelType = KernelType::Box;
}
}
if (isSelected)
{
ImGui::SetItemDefaultFocus();
}
}
ImGui::EndCombo();
}
}
bool radChange = ImGui::SliderInt("Radius", &radius, 0, 15);
bool sigChange = ImGui::SliderFloat("Sigma", &sigma, 0.1f, 10.0f);
if (radChange || sigChange || filterChanged)
{
if (kernelType == KernelType::Gauss)
{
SetKernelGauss(gfx, radius, sigma);
}
else if (kernelType == KernelType::Box)
{
SetKernelBox(gfx, radius);
}
}
}
// for more accurate coefs, need to integrate, but meh :/
void SetKernelGauss(DXGraphics& gfx, size_t radius, float sigma) noxnd
{
assert(radius <= maxRadius);
Kernel k;
k.nTaps = (UINT)radius * 2u + 1u;
float sum = 0.0f;
for (UINT i = 0; i < k.nTaps; i++)
{
const auto x = float(i - radius);
const auto g = gauss(x, sigma);
sum += g;
k.coefficients[i].x = g;
}
for (UINT i = 0; i < k.nTaps; i++)
{
k.coefficients[i].x /= sum;
}
pcb.Update(gfx, k);
}
void SetKernelBox(DXGraphics& gfx, int radius) noxnd
{
assert(radius <= maxRadius);
Kernel k;
k.nTaps = radius * 2 + 1;
const float c = 1.0f / k.nTaps;
for (UINT i = 0; i < k.nTaps; i++)
{
k.coefficients[i].x = c;
}
pcb.Update(gfx, k);
}
private:
enum class KernelType
{
Gauss,
Box,
};
static constexpr size_t maxRadius = 15;
int radius;
float sigma;
KernelType kernelType = KernelType::Gauss;
struct Kernel
{
UINT nTaps;
float padding[3];
DirectX::XMFLOAT4 coefficients[maxRadius * 2 + 1];
};
struct Control
{
BOOL horizontal;
float padding[3];
};
Bind::PixelShader shader;
Bind::PixelConstantBuffer<Kernel> pcb;
Bind::PixelConstantBuffer<Control> ccb;
};
\ No newline at end of file
......@@ -131,17 +131,17 @@ int CombatManager::ProcessInput(Keyboard::Event in_event) //why does it return
}
if (in_event.GetCode() == 'J') //for testing
{
BlurManager::AddBlur(0.9f);
BlurManager::AddBlur(0.7f);
}
if (in_event.GetCode() == 'K') //for testing
{
BlurManager::AddBlur(1.2f);
}
if (in_event.GetCode() == 'L') //for testing
{
BlurManager::AddBlur(1.9f);
}
//
//if (in_event.GetCode() == 'K') //for testing
//{
// EH::AddEffect3D(EH::Effect::PlayerSandThrow);
//}
//if (in_event.GetCode() == 'L') //for testing
//{
// EH::AddEffect3D(EH::Effect::PlayerSandStorm);
//}
//if (in_event.GetCode() == 'T') //for testing
//{
// CM::PendScenario(CM::Scenario::GhoulRage);
......
......@@ -179,6 +179,7 @@
<ClInclude Include="AchievementManager.h" />
<ClInclude Include="AchievementsScreen.h" />
<ClInclude Include="BlurManager.h" />
<ClInclude Include="BlurPack.h" />
<ClInclude Include="BufferResource.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
......@@ -576,7 +577,7 @@
<ObjectFileOutput Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(RiftedTimes\Engine)%(Filename).cso</ObjectFileOutput>
<ObjectFileOutput Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(RiftedTimes\Engine)%(Filename).cso</ObjectFileOutput>
</FxCompile>
<FxCompile Include="FunkPS.hlsl">
<FxCompile Include="BlurPS.hlsl">
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Pixel</ShaderType>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Pixel</ShaderType>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Pixel</ShaderType>
......
......@@ -600,6 +600,9 @@
<ClInclude Include="GraphicsResource.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="BlurPack.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Game.cpp">
......@@ -1033,7 +1036,7 @@
<FxCompile Include="FullscreenVS.hlsl">
<Filter>Shaders</Filter>
</FxCompile>
<FxCompile Include="FunkPS.hlsl">
<FxCompile Include="BlurPS.hlsl">
<Filter>Shaders</Filter>
</FxCompile>
</ItemGroup>
......
/******************************************************************************************
* Chili DirectX Framework Version 16.10.01 *
* ChiliMath.h *
* Copyright 2016 PlanetChili <http://www.planetchili.net> *
* *
* This file is part of The Chili DirectX Framework. *
* *
* The Chili DirectX Framework is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* The Chili DirectX Framework is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with The Chili DirectX Framework. If not, see <http://www.gnu.org/licenses/>. *
******************************************************************************************/
#pragma once
#include <math.h>
......@@ -51,4 +30,20 @@ template<typename T>
constexpr T to_rad(T deg)
{
return deg * PI / (T)180.0;
}
template<typename T>
constexpr T gauss(T x, T sigma) noexcept
{
const auto ss = sq(sigma);
return ((T)1.0 / sqrt((T)2.0 * (T)PI_D * ss)) * exp(-sq(x) / ((T)2.0 * ss));
}
template <typename T>
T gaussEX(T x, T m, T s)
{
static const T inv_sqrt_2pi = 0.3989422804014327;
T a = (x - m) / s;
return inv_sqrt_2pi / s * std::exp(-T(0.5) * a * a);
}
\ No newline at end of file
#include "FrameCommander.h"
//#include "../RenderTarget.h"
void FrameCommander::Execute(DXGraphics& gfx, float dt) const noxnd
void FrameCommander::Execute(DXGraphics& gfx, float dt) noxnd
{
ds.Clear(gfx);
//gfx.BindSwapBuffer(ds);
using namespace Bind;
Rasterizer::Resolve(gfx, true)->Bind(gfx); //backface culling is not needed, because there are literary no backfaces
Stencil::Resolve(gfx, Stencil::Mode::Default)->Bind(gfx);
......@@ -18,18 +16,27 @@ void FrameCommander::Execute(DXGraphics& gfx, float dt) const noxnd
}
else
{
rt.BindAsTarget(gfx,ds);
size_t kernelSize = std::max((size_t)2.0f, std::min(size_t(15.0f * blurMod), (size_t)15u));
bp.SetKernelGauss(gfx, kernelSize, 10.0f * blurMod);
rt1.BindAsTarget(gfx, ds);
passes[0].Execute(gfx); //most models
Stencil::Resolve(gfx, Stencil::Mode::ReadOnly)->Bind(gfx); //::HUD
passes[1].Execute(gfx);
// fullscreen funky pass
gfx.BindSwapBuffer();
rt.BindAsTexture(gfx, 0);
// fullscreen blur h-pass
rt2.BindAsTarget(gfx,ds);
rt1.BindAsTexture(gfx, 0);
pVbFull->Bind(gfx);
pIbFull->Bind(gfx);
pVsFull->Bind(gfx);
pPsFull->Bind(gfx);
pLayoutFull->Bind(gfx);
bp.Bind(gfx);
bp.SetHorizontal(gfx);
gfx.DrawIndexed(pIbFull->GetCount());
// fullscreen blur v-pass
gfx.BindSwapBuffer(ds);
rt2.BindAsTexture(gfx, 0u);
bp.SetVertical(gfx);
gfx.DrawIndexed(pIbFull->GetCount());
}
Stencil::Resolve(gfx, Stencil::Mode::HUD)->Bind(gfx); //::HUD
......@@ -41,10 +48,11 @@ void FrameCommander::Execute(DXGraphics& gfx, float dt) const noxnd
FrameCommander::FrameCommander(DXGraphics& gfx) :
gfx(gfx),
ds(gfx, gfx.GetScreenWidth(), gfx.GetScreenHeight()),
rt(gfx, gfx.GetScreenWidth(), gfx.GetScreenHeight())
rt1(gfx, gfx.GetScreenWidth(), gfx.GetScreenHeight()),
rt2(gfx, gfx.GetScreenWidth(), gfx.GetScreenHeight()),
bp(gfx)
{
namespace dx = DirectX;
// setup fullscreen geometry
Dvtx::VertexLayout lay;
lay.Append(Dvtx::VertexLayout::Position2D);
......@@ -58,7 +66,6 @@ FrameCommander::FrameCommander(DXGraphics& gfx) :
pIbFull = Bind::IndexBuffer::Resolve(gfx, L"$Full", std::move(indices));
// setup fullscreen shaders
pPsFull = Bind::PixelShader::Resolve(gfx, L"FunkPS.cso");
pVsFull = Bind::VertexShader::Resolve(gfx, L"FullscreenVS.cso");
pLayoutFull = Bind::InputLayout::Resolve(gfx, lay, pVsFull->GetBytecode());
}
......
......@@ -6,6 +6,7 @@
#include "Pass.h"
#include "../DepthStencil.h"
#include "../RenderTarget.h"
#include "../BlurPack.h"
class FrameCommander //submits drawables
{
......@@ -15,7 +16,7 @@ public:
{
passes[target].Accept( job );
}
void Execute(DXGraphics& gfx, float dt) const noxnd;
void Execute(DXGraphics& gfx, float dt) noxnd;
void Reset() noexcept;
static void SetBlurMod(float blur); //make friend of blur commander or something
private:
......@@ -23,10 +24,11 @@ private:
std::array<Pass, 5> passes;
DXGraphics& gfx;
DepthStencil ds;
RenderTarget rt;
RenderTarget rt1;
RenderTarget rt2;
std::shared_ptr<Bind::VertexBuffer> pVbFull;
std::shared_ptr<Bind::IndexBuffer> pIbFull;
std::shared_ptr<Bind::VertexShader> pVsFull;
std::shared_ptr<Bind::PixelShader> pPsFull;
std::shared_ptr<Bind::InputLayout> pLayoutFull;
BlurPack bp;
};
\ No newline at end of file
Texture2D tex;
SamplerState splr;
static const int r = 3;
static const float divisor = (2 * r + 1) * (2 * r + 1);
float4 main(float2 uv : Texcoord) : SV_Target
{
uint width, height;
tex.GetDimensions(width, height);
const float dx = 1.0f / width;
const float dy = 1.0f / height;
float3 acc = float3(0.0f, 0.0f, 0.0f);
for (int y = -r; y <= r; y++)
{
for (int x = -r; x <= r; x++)
{
const float2 tc = uv + float2(dx * x, dy * y);
acc += tex.Sample(splr, tc).rgb;
}
}
return float4(acc / divisor, 1.0f);
}
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment