Skip to content

Commit

Permalink
fix bloom (#462)
Browse files Browse the repository at this point in the history
* check upsample max times to avoid invalid frame buffer access

* fix bloom pass orders
  • Loading branch information
T-rvw authored Feb 6, 2024
1 parent 6a39222 commit d38e35c
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 39 deletions.
8 changes: 4 additions & 4 deletions Engine/Source/Editor/EditorApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ void EditorApp::InitEditorCameraEntity()
cameraComponent.SetExposure(1.0f);
cameraComponent.SetGammaCorrection(0.45f);
cameraComponent.SetToneMappingMode(cd::ToneMappingMode::ACES);
cameraComponent.SetBloomDownSampleTImes(4);
cameraComponent.SetBloomDownSampleTimes(4);
cameraComponent.SetBloomIntensity(1.0f);
cameraComponent.SetLuminanceThreshold(1.0f);
cameraComponent.SetBlurTimes(0);
Expand Down Expand Up @@ -543,9 +543,9 @@ void EditorApp::InitEngineRenderers()
pWhiteModelRenderer->SetEnable(false);
AddEngineRenderer(cd::MoveTemp(pWhiteModelRenderer));

auto pParticlerenderer = std::make_unique<engine::ParticleRenderer>(m_pRenderContext->CreateView(), pSceneRenderTarget);
pParticlerenderer->SetSceneWorld(m_pSceneWorld.get());
AddEngineRenderer(cd::MoveTemp(pParticlerenderer));
auto pParticleRenderer = std::make_unique<engine::ParticleRenderer>(m_pRenderContext->CreateView(), pSceneRenderTarget);
pParticleRenderer->SetSceneWorld(m_pSceneWorld.get());
AddEngineRenderer(cd::MoveTemp(pParticleRenderer));

#ifdef ENABLE_DDGI
auto pDDGIRenderer = std::make_unique<engine::DDGIRenderer>(m_pRenderContext->CreateView(), pSceneRenderTarget);
Expand Down
4 changes: 2 additions & 2 deletions Engine/Source/Editor/UILayers/Inspector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ void UpdateComponentWidget<engine::MaterialComponent>(engine::SceneWorld* pScene
cd::Vec3f emissiveColor{ emissiveColorAndFactor.x(), emissiveColorAndFactor.y(), emissiveColorAndFactor.z() };
float emissiveFactor = emissiveColorAndFactor.w();
ImGuiUtils::ImGuiVectorProperty("Color", emissiveColor, cd::Unit::None, cd::Vec3f::Zero(), cd::Vec3f::One(), false, 0.01f);
ImGuiUtils::ImGuiFloatProperty("Factor", emissiveFactor, cd::Unit::None, 0.0f, 10.0f, false, 0.1f);
ImGuiUtils::ImGuiFloatProperty("Factor", emissiveFactor, cd::Unit::None, 0.0f, 10000.0f, false, 0.1f);
emissiveColorAndFactor = cd::Vec4f{ emissiveColor.x(), emissiveColor.y(), emissiveColor.z(), emissiveFactor };
}

Expand Down Expand Up @@ -402,7 +402,7 @@ void UpdateComponentWidget<engine::CameraComponent>(engine::SceneWorld* pSceneWo
ImGuiUtils::ImGuiBoolProperty("Open Blur", pCameraComponent->GetIsBlurEnable());
if (pCameraComponent->GetIsBlurEnable())
{
ImGuiUtils::ImGuiIntProperty("Blur Iteration", pCameraComponent->GetBlurTimes(), cd::Unit::None, 0, 20, false, 1.0f);
ImGuiUtils::ImGuiIntProperty("Blur Iteration", pCameraComponent->GetBlurTimes(), cd::Unit::None, 0, pCameraComponent->GetBlurMaxTimes(), false, 1.0f);
ImGuiUtils::ImGuiFloatProperty("Blur Size", pCameraComponent->GetBlurSize(), cd::Unit::None, 0.0f, 3.0f);
ImGuiUtils::ImGuiIntProperty("Blur Scaling", pCameraComponent->GetBlurScaling(), cd::Unit::None, 1, 4, false, 1.0f);
}
Expand Down
18 changes: 14 additions & 4 deletions Engine/Source/Runtime/ECWorld/CameraComponent.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,13 @@ class CameraComponent final
float GetIsBlurEnable() const { return m_enableBlur; }
void SetBlurEnable(bool blur) { m_enableBloom = blur; }

int& GetBloomDownSampleTimes() { return m_blomDownSampleTimes; }
int GetBloomDownSampleTimes() const { return m_blomDownSampleTimes; }
void SetBloomDownSampleTImes(int downsampletimes) { m_blomDownSampleTimes = downsampletimes; }
int& GetBloomDownSampleTimes() { return m_bloomDownSampleTimes; }
int GetBloomDownSampleTimes() const { return m_bloomDownSampleTimes; }
void SetBloomDownSampleTimes(int times) { m_bloomDownSampleTimes = times; }

int& GetBloomDownSampleMaxTimes() { return m_bloomDownSampleMaxTimes; }
int GetBloomDownSampleMaxTimes() const { return m_bloomDownSampleMaxTimes; }
void SetBloomDownSampleMaxTimes(int maxTimes) { m_bloomDownSampleMaxTimes = maxTimes; }

float& GetBloomIntensity() { return m_bloomIntensity; }
float GetBloomIntensity() const { return m_bloomIntensity; }
Expand All @@ -138,6 +142,10 @@ class CameraComponent final
int GetBlurTimes() const { return m_blurTimes; }
void SetBlurTimes(int blurtimes) { m_blurTimes = blurtimes; }

int& GetBlurMaxTimes() { return m_blurMaxTimes; }
int GetBlurMaxTimes() const { return m_blurMaxTimes; }
void SetBlurMaxTimes(int maxTimes) { m_blurMaxTimes = maxTimes; }

float& GetBlurSize() { return m_blurSize; }
float GetBlurSize() const { return m_blurSize; }
void SetBlurSize(float blursize) { m_blurSize = blursize; }
Expand Down Expand Up @@ -172,10 +180,12 @@ class CameraComponent final
bool m_doConstainAspectRatio;
bool m_enableBloom;
bool m_enableBlur;
int m_blomDownSampleTimes;
int m_bloomDownSampleTimes;
int m_bloomDownSampleMaxTimes;
float m_bloomIntensity;
float m_luminanceThreshold;
int m_blurTimes;
int m_blurMaxTimes = 20;
float m_blurSize;
int m_blurScaling;
#endif
Expand Down
73 changes: 44 additions & 29 deletions Engine/Source/Runtime/Rendering/BloomRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,16 @@ void BloomRenderer::Init()
GetRenderContext()->RegisterShaderProgram(CombineProgramCrc, { "vs_fullscreen", "fs_bloom" });

bgfx::setViewName(GetViewID(), "BloomRenderer");

AllocateViewIDs();
}

void BloomRenderer::Warmup()
void BloomRenderer::AllocateViewIDs()
{
Entity entity = m_pCurrentSceneWorld->GetMainCameraEntity();
CameraComponent* pCameraComponent = m_pCurrentSceneWorld->GetCameraComponent(entity);
assert(pCameraComponent);

for (int i = 0; i < TEX_CHAIN_LEN; i++)
{
m_sampleChainFB[i] = BGFX_INVALID_HANDLE;
Expand All @@ -44,18 +50,24 @@ void BloomRenderer::Warmup()
}
m_startVerticalBlurPassID = GetRenderContext()->CreateView();
m_startHorizontalBlurPassID = GetRenderContext()->CreateView();
for (int i = 0; i < 40 - 2; i++)

int totalBlurTimes = pCameraComponent->GetBlurMaxTimes() * 2;
for (int i = 0; i < totalBlurTimes - 2; i++)
{
GetRenderContext()->CreateView();
}

m_startUpSamplePassID = GetRenderContext()->CreateView();
for (int i = 0; i < TEX_CHAIN_LEN - 2; i++)
{
GetRenderContext()->CreateView();
}
m_combinePassID = GetRenderContext()->CreateView();
m_blitColorPassID = GetRenderContext()->CreateView();
}

void BloomRenderer::Warmup()
{
GetRenderContext()->CreateUniform("s_texture", bgfx::UniformType::Sampler);
GetRenderContext()->CreateUniform("s_bloom", bgfx::UniformType::Sampler);
GetRenderContext()->CreateUniform("s_lightingColor", bgfx::UniformType::Sampler);
Expand Down Expand Up @@ -106,18 +118,26 @@ void BloomRenderer::UpdateView(const float* pViewMatrix, const float* pProjectio
m_width = tempW;
m_height = tempH;

Entity entity = m_pCurrentSceneWorld->GetMainCameraEntity();
CameraComponent* pCameraComponent = m_pCurrentSceneWorld->GetCameraComponent(entity);

constexpr uint64_t tsFlags = 0 | BGFX_TEXTURE_RT | BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP;
for (int ii = 0; ii < TEX_CHAIN_LEN; ++ii)
{
if (bgfx::isValid(m_sampleChainFB[ii]))
{
bgfx::destroy(m_sampleChainFB[ii]);
}
if ((m_height >> ii) < 2 || (m_width >> ii) < 2)

int viewWidth = m_width >> ii;
int viewHeight = m_height >> ii;
if (viewWidth < 2 || viewHeight < 2)
{
pCameraComponent->SetBloomDownSampleMaxTimes(std::max(ii - 1, 0));
break;
}
m_sampleChainFB[ii] = bgfx::createFrameBuffer(m_width >> ii, m_height >> ii, bgfx::TextureFormat::RGBA32F, tsFlags);

m_sampleChainFB[ii] = bgfx::createFrameBuffer(viewWidth, viewHeight, bgfx::TextureFormat::RGBA32F, tsFlags);
}

m_combineFB = bgfx::createFrameBuffer(m_width, m_height, bgfx::TextureFormat::RGBA32F, tsFlags);
Expand Down Expand Up @@ -169,16 +189,11 @@ void BloomRenderer::Render(float deltaTime)
GetRenderContext()->Submit(GetViewID(), "CapTureBrightnessProgram");

// downsample
int sampleTimes = int(pCameraComponent->GetBloomDownSampleTimes());
int sampleTimes = std::min(pCameraComponent->GetBloomDownSampleTimes(), pCameraComponent->GetBloomDownSampleMaxTimes());
int tempshift = 0;
for (int i = 0; i < sampleTimes; ++i)
for (int sampleIndex = 0; sampleIndex < sampleTimes; ++sampleIndex)
{
int shift = i + 1;
if ((m_width >> shift) < 2 || (m_height >> shift) < 2)
{
break;
}

int shift = sampleIndex + 1;
tempshift = shift;
const float pixelSize[4] =
{
Expand All @@ -188,19 +203,20 @@ void BloomRenderer::Render(float deltaTime)
0.0f,
};

bgfx::setViewFrameBuffer(m_startDowmSamplePassID + i, m_sampleChainFB[shift]);
bgfx::setViewRect(m_startDowmSamplePassID + i, 0, 0, m_width >> shift, m_height >> shift);
bgfx::setViewTransform(m_startDowmSamplePassID + i, nullptr, orthoMatrix.begin());
bgfx::setViewFrameBuffer(m_startDowmSamplePassID + sampleIndex, m_sampleChainFB[shift]);
bgfx::setViewName(m_startDowmSamplePassID + sampleIndex, std::format("Downsample_{}", sampleIndex).c_str());
bgfx::setViewRect(m_startDowmSamplePassID + sampleIndex, 0, 0, m_width >> shift, m_height >> shift);
bgfx::setViewTransform(m_startDowmSamplePassID + sampleIndex, nullptr, orthoMatrix.begin());

constexpr StringCrc textureSizeUniformName("u_textureSize");
bgfx::setUniform(GetRenderContext()->GetUniform(textureSizeUniformName), pixelSize);

bgfx::setTexture(0, GetRenderContext()->GetUniform(textureSampler), bgfx::getTexture(m_sampleChainFB[shift - 1]));
bgfx::setTexture(0, GetRenderContext()->GetUniform(textureSampler), bgfx::getTexture(m_sampleChainFB[sampleIndex]));

bgfx::setState(BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A);
Renderer::ScreenSpaceQuad(GetRenderTarget(), false);

GetRenderContext()->Submit(m_startDowmSamplePassID + i, "DownSampleProgram");
GetRenderContext()->Submit(m_startDowmSamplePassID + sampleIndex, "DownSampleProgram");
}

if (pCameraComponent->GetIsBlurEnable() && pCameraComponent->GetBlurTimes() != 0)
Expand All @@ -209,14 +225,9 @@ void BloomRenderer::Render(float deltaTime)
}

// upsample
for (int i = 0; i < sampleTimes; ++i)
for (int sampleIndex = 0; sampleIndex < sampleTimes; ++sampleIndex)
{
int shift = sampleTimes - i - 1;
if ((m_width >> shift) < 2 || (m_height >> shift) < 2)
{
continue;
}

int shift = sampleTimes - sampleIndex - 1;
const float pixelSize[4] =
{
1.0f / static_cast<float>(m_width >> shift),
Expand All @@ -225,17 +236,18 @@ void BloomRenderer::Render(float deltaTime)
0.0f,
};

bgfx::setViewFrameBuffer(m_startUpSamplePassID + i, m_sampleChainFB[shift]);
bgfx::setViewRect(m_startUpSamplePassID + i, 0, 0, m_width >> shift, m_height >> shift);
bgfx::setViewTransform(m_startUpSamplePassID + i, nullptr, orthoMatrix.begin());
bgfx::setViewFrameBuffer(m_startUpSamplePassID + sampleIndex, m_sampleChainFB[shift]);
bgfx::setViewName(m_startUpSamplePassID + sampleIndex, std::format("Upsample_{}", sampleIndex).c_str());
bgfx::setViewRect(m_startUpSamplePassID + sampleIndex, 0, 0, m_width >> shift, m_height >> shift);
bgfx::setViewTransform(m_startUpSamplePassID + sampleIndex, nullptr, orthoMatrix.begin());

constexpr StringCrc textureSizeUniformName("u_textureSize");
bgfx::setUniform(GetRenderContext()->GetUniform(textureSizeUniformName), pixelSize);

constexpr StringCrc bloomIntensityUniformName("u_bloomIntensity");
bgfx::setUniform(GetRenderContext()->GetUniform(bloomIntensityUniformName), &pCameraComponent->GetBloomIntensity());

if (pCameraComponent->GetIsBlurEnable() && pCameraComponent->GetBlurTimes() != 0 && 0 == i)
if (pCameraComponent->GetIsBlurEnable() && pCameraComponent->GetBlurTimes() != 0 && 0 == sampleIndex)
{
bgfx::setTexture(0, GetRenderContext()->GetUniform(textureSampler), bgfx::getTexture(m_blurChainFB[1]));
}
Expand All @@ -247,11 +259,12 @@ void BloomRenderer::Render(float deltaTime)
bgfx::setState(BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A | BGFX_STATE_BLEND_ADD);
Renderer::ScreenSpaceQuad(GetRenderTarget(), false);

GetRenderContext()->Submit(m_startUpSamplePassID + i, "UpSampleProgram");
GetRenderContext()->Submit(m_startUpSamplePassID + sampleIndex, "UpSampleProgram");
}

// combine
bgfx::setViewFrameBuffer(m_combinePassID, m_combineFB);
bgfx::setViewName(m_combinePassID, "CombineBloom");
bgfx::setViewRect(m_combinePassID, 0, 0, m_width, m_height);
bgfx::setViewTransform(m_combinePassID, nullptr, orthoMatrix.begin());

Expand Down Expand Up @@ -294,6 +307,7 @@ void BloomRenderer::Blur(uint16_t width, uint16_t height, int iteration, float b
};

bgfx::setViewFrameBuffer(verticalViewID, m_blurChainFB[0]);
bgfx::setViewName(verticalViewID, "BlurVertical");
bgfx::setViewRect(verticalViewID, 0, 0, width, height);
bgfx::setViewTransform(verticalViewID, nullptr, ortho.begin());

Expand All @@ -313,6 +327,7 @@ void BloomRenderer::Blur(uint16_t width, uint16_t height, int iteration, float b

// vertical
bgfx::setViewFrameBuffer(horizontalViewID, m_blurChainFB[1]);
bgfx::setViewName(horizontalViewID, "BlurHorizontal");
bgfx::setViewRect(horizontalViewID, 0, 0, width, height);
bgfx::setViewTransform(horizontalViewID, nullptr, ortho.begin());

Expand Down
1 change: 1 addition & 0 deletions Engine/Source/Runtime/Rendering/BloomRenderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ namespace engine
void SetSceneWorld(SceneWorld* pSceneWorld) { m_pCurrentSceneWorld = pSceneWorld; }

private:
void AllocateViewIDs();
void Blur(uint16_t width , uint16_t height,int iteration, float blursize, int blurscaling,cd::Matrix4x4 ortho, bgfx::TextureHandle texture);

SceneWorld* m_pCurrentSceneWorld = nullptr;
Expand Down

0 comments on commit d38e35c

Please sign in to comment.