22 _bloomRenderTarget = createRenderTarget(0, _bloomColorTexture);
23 _bloomTexture = _bloomColorTexture.get();
26 void RenderPassBloom::destroyRenderTargets(
const int startIndex)
28 for (
int i = std::max(startIndex, 0); i < static_cast<int>(_renderTargets.size()); ++i) {
29 _renderTargets[i].reset();
31 if (startIndex <= 0) {
32 _renderTargets.clear();
33 _ownedTextures.clear();
34 }
else if (startIndex <
static_cast<int>(_renderTargets.size())) {
35 _renderTargets.erase(_renderTargets.begin() + startIndex, _renderTargets.end());
36 if (startIndex <
static_cast<int>(_ownedTextures.size())) {
37 _ownedTextures.erase(_ownedTextures.begin() + startIndex, _ownedTextures.end());
42 void RenderPassBloom::destroyRenderPasses()
47 std::shared_ptr<RenderTarget> RenderPassBloom::createRenderTarget(
const int index,
48 std::shared_ptr<Texture>& outTexture)
const
50 TextureOptions textureOptions;
51 textureOptions.name =
"BloomTexture" + std::to_string(index);
52 textureOptions.width = 1;
53 textureOptions.height = 1;
54 textureOptions.format = _textureFormat;
55 textureOptions.mipmaps =
false;
58 outTexture = std::make_shared<Texture>(
device().get(), textureOptions);
62 RenderTargetOptions options;
63 options.graphicsDevice =
device().get();
64 options.colorBuffer = outTexture.get();
65 options.depth =
false;
66 options.stencil =
false;
67 options.name = textureOptions.name;
68 return device()->createRenderTarget(options);
71 void RenderPassBloom::createRenderTargets(
const int count)
73 _renderTargets.clear();
74 _ownedTextures.clear();
75 for (
int i = 0; i < count; ++i) {
77 _renderTargets.push_back(_bloomRenderTarget);
78 _ownedTextures.push_back(_bloomColorTexture);
80 std::shared_ptr<Texture> tex;
81 _renderTargets.push_back(createRenderTarget(i, tex));
82 _ownedTextures.push_back(std::move(tex));
87 int RenderPassBloom::calcMipLevels(
const uint32_t width,
const uint32_t height,
const int minSize)
const
89 const int minimum = std::max(
static_cast<int>(std::min(width, height)), 1);
90 const float levels = std::log2(
static_cast<float>(minimum)) - std::log2(
static_cast<float>(std::max(minSize, 1)));
91 return std::max(
static_cast<int>(std::floor(levels)), 1);
94 void RenderPassBloom::createRenderPasses(
const int numPasses)
96 Texture* passSourceTexture = _sourceTexture;
97 for (
int i = 0; i < numPasses; ++i) {
98 auto pass = std::make_shared<RenderPassDownsample>(
device(), passSourceTexture);
99 auto options = std::make_shared<RenderPassOptions>();
100 options->resizeSource = std::shared_ptr<Texture>(passSourceTexture, [](Texture*) {});
101 options->scaleX = 0.5f;
102 options->scaleY = 0.5f;
103 pass->init(_renderTargets[i], options);
104 const Color clearBlack(0.0f, 0.0f, 0.0f, 1.0f);
105 pass->setClearColor(&clearBlack);
107 passSourceTexture = _renderTargets[i]->colorBuffer();
110 passSourceTexture = _renderTargets[numPasses - 1]->colorBuffer();
111 for (
int i = numPasses - 2; i >= 0; --i) {
112 auto pass = std::make_shared<RenderPassUpsample>(
device(), passSourceTexture);
113 pass->init(_renderTargets[i]);
115 passSourceTexture = _renderTargets[i]->colorBuffer();
121 if (!_renderTargets.empty() && _renderTargets[0]) {
122 _renderTargets[0]->resize(1, 1);
125 destroyRenderPasses();
126 destroyRenderTargets(1);
133 if (!mutableThis->_sourceTexture) {
137 const int maxNumPasses = calcMipLevels(mutableThis->_sourceTexture->width(), mutableThis->_sourceTexture->height(), 1);
138 const int numPasses = std::clamp(maxNumPasses, 1, mutableThis->_blurLevel);
139 if (
static_cast<int>(mutableThis->_renderTargets.size()) != numPasses) {
140 mutableThis->destroyRenderPasses();
141 mutableThis->destroyRenderTargets(1);
142 mutableThis->createRenderTargets(numPasses);
143 mutableThis->createRenderPasses(numPasses);
void frameUpdate() const override
void onDisable() override
RenderPassBloom(const std::shared_ptr< GraphicsDevice > &device, Texture *sourceTexture, PixelFormat format)
virtual void frameUpdate() const
std::shared_ptr< GraphicsDevice > device() const
RenderPass(const std::shared_ptr< GraphicsDevice > &device)
void addBeforePass(const std::shared_ptr< RenderPass > &renderPass)
GPU texture resource supporting 2D, cubemap, volume, and array formats with mipmap management.