Files
2025-09-18 17:55:52 -04:00

88 lines
3.4 KiB
C++

#include "stdafx.h"
#include "ScreenSpaceEffect.h"
#include "GfxCore/Device.h"
#include "GfxCore/Framebuffer.h"
#include "GfxCore/States.h"
#include "VisualEngine.h"
#include "VisualEngine.h"
#include "ShaderManager.h"
#include "SceneManager.h"
#include "rbx/Profiler.h"
namespace RBX
{
namespace Graphics
{
ShaderProgram* ScreenSpaceEffect::renderFullscreenBegin(DeviceContext* context, VisualEngine* visualEngine, const char* vsName, const char* fsName, const BlendState& blendState, unsigned fbWidth, unsigned fbHeight)
{
ShaderProgram* program = visualEngine->getShaderManager()->getProgram(vsName, fsName).get();
if (program)
{
const float textureSize[] = { fbWidth, fbHeight, 1 / (float)fbWidth, 1 / (float)fbHeight };
context->setRasterizerState(RasterizerState::Cull_None);
context->setBlendState(blendState);
context->setDepthState(DepthState(DepthState::Function_Always, false));
context->bindProgram(program);
context->setConstant(program->getConstantHandle("TextureSize"), textureSize, 1);
}
return program;
}
void ScreenSpaceEffect::renderFullscreenEnd(DeviceContext* context, VisualEngine* visualEngine)
{
context->draw(visualEngine->getSceneManager()->getFullscreenTriangle());
}
void ScreenSpaceEffect::renderBlur(DeviceContext* context, VisualEngine* visualEngine, Framebuffer* fb, Framebuffer* intermediateFB, Texture* texture, Texture* intermediate, float strength)
{
RBXASSERT(texture->getWidth() == intermediate->getWidth() && texture->getHeight() == intermediate->getHeight() && texture->getFormat() == intermediate->getFormat());
RBXPROFILER_SCOPE("Render", "blurRender");
RBXPROFILER_SCOPE("GPU", "blurRender");
// find optimal shader
const char blurSamples[] = { 3, 5, 7 };
char bestBlur = blurSamples[0];
for (int i = 0; i < ARRAYSIZE(blurSamples); ++i)
{
bestBlur = blurSamples[i];
if (strength < blurSamples[i])
break;
}
std::string nameFS = "Blur";
nameFS += (bestBlur + '0');
nameFS += "FS";
context->bindFramebuffer(intermediateFB);
if (ShaderProgram* program = ScreenSpaceEffect::renderFullscreenBegin(context, visualEngine, "PassThroughVS", nameFS.c_str(), BlendState::Mode_None, intermediateFB->getWidth(), intermediateFB->getHeight()))
{
float params[] = { 1.f / texture->getWidth(), 0, strength, 0 };
context->setConstant(program->getConstantHandle("Params1"), params, 1);
context->bindTexture(0, texture, SamplerState(SamplerState::Filter_Linear, SamplerState::Address_Clamp));
ScreenSpaceEffect::renderFullscreenEnd(context, visualEngine);
}
context->bindFramebuffer(fb);
if (ShaderProgram* program = ScreenSpaceEffect::renderFullscreenBegin(context, visualEngine, "PassThroughVS", nameFS.c_str(), BlendState::Mode_None, fb->getWidth(), fb->getHeight()))
{
context->bindTexture(0, intermediate, SamplerState(SamplerState::Filter_Linear, SamplerState::Address_Clamp));
float params[] = { 0, 1.f / texture->getHeight(), strength, 1 };
context->setConstant(program->getConstantHandle("Params1"), params, 1);
ScreenSpaceEffect::renderFullscreenEnd(context, visualEngine);
}
}
}
}