bloom iwa fx (#492)
Signed-off-by: Jeremy Bullock <jcbullock@gmail.com> Co-authored-by: shun-iwasawa <shun.iwasawa@ghibli.jp>
This commit is contained in:
parent
918ffa8fd8
commit
0bb97d6c31
6 changed files with 375 additions and 0 deletions
|
@ -1347,6 +1347,12 @@
|
||||||
<item>"STD_iwa_FractalNoiseFx.dynamicIntensity" "Dynamic Intensity" </item>
|
<item>"STD_iwa_FractalNoiseFx.dynamicIntensity" "Dynamic Intensity" </item>
|
||||||
<item>"STD_iwa_FractalNoiseFx.alphaRendering" "Alpha Rendering" </item>
|
<item>"STD_iwa_FractalNoiseFx.alphaRendering" "Alpha Rendering" </item>
|
||||||
|
|
||||||
|
<item>"STD_iwa_BloomFx" "Bloom Iwa" </item>
|
||||||
|
<item>"STD_iwa_BloomFx.gamma" "Gamma" </item>
|
||||||
|
<item>"STD_iwa_BloomFx.gain" "Gain" </item>
|
||||||
|
<item>"STD_iwa_BloomFx.size" "Size" </item>
|
||||||
|
<item>"STD_iwa_BloomFx.alpha_rendering" "Alpha Rendering" </item>
|
||||||
|
|
||||||
<!------------------------------ Tiled Particles Iwa ------------------------------------------->
|
<!------------------------------ Tiled Particles Iwa ------------------------------------------->
|
||||||
|
|
||||||
<item>STD_iwa_TiledParticlesFx "Tiled Particles Iwa" </item>
|
<item>STD_iwa_TiledParticlesFx "Tiled Particles Iwa" </item>
|
||||||
|
|
8
stuff/profiles/layouts/fxs/STD_iwa_BloomFx.xml
Normal file
8
stuff/profiles/layouts/fxs/STD_iwa_BloomFx.xml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<fxlayout>
|
||||||
|
<page name="Bloom Iwa">
|
||||||
|
<control>gamma</control>
|
||||||
|
<control>gain</control>
|
||||||
|
<control>size</control>
|
||||||
|
<control>alpha_rendering</control>
|
||||||
|
</page>
|
||||||
|
</fxlayout>
|
|
@ -125,6 +125,7 @@
|
||||||
STD_iwa_SoapBubbleFx
|
STD_iwa_SoapBubbleFx
|
||||||
STD_targetSpotFx
|
STD_targetSpotFx
|
||||||
STD_iwa_GlareFx
|
STD_iwa_GlareFx
|
||||||
|
STD_iwa_BloomFx
|
||||||
</Light>
|
</Light>
|
||||||
<Matte>
|
<Matte>
|
||||||
STD_erodeDilateFx
|
STD_erodeDilateFx
|
||||||
|
|
|
@ -83,6 +83,10 @@ set(HEADERS
|
||||||
iwa_fractalnoisefx.h
|
iwa_fractalnoisefx.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(OpenCV_FOUND)
|
||||||
|
list(APPEND HEADERS iwa_bloomfx.h)
|
||||||
|
endif()
|
||||||
|
|
||||||
set(SOURCES
|
set(SOURCES
|
||||||
adjustlevelsfx.cpp
|
adjustlevelsfx.cpp
|
||||||
artcontourfx.cpp
|
artcontourfx.cpp
|
||||||
|
@ -270,6 +274,10 @@ set(SOURCES
|
||||||
iwa_fractalnoisefx.cpp
|
iwa_fractalnoisefx.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(OpenCV_FOUND)
|
||||||
|
list(APPEND SOURCES iwa_bloomfx.cpp)
|
||||||
|
endif()
|
||||||
|
|
||||||
set(OBJCSOURCES
|
set(OBJCSOURCES
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -306,3 +314,7 @@ include_directories(
|
||||||
_find_toonz_library(TNZLIBS "tnzcore;tnzbase;toonzlib")
|
_find_toonz_library(TNZLIBS "tnzcore;tnzbase;toonzlib")
|
||||||
|
|
||||||
target_link_libraries(tnzstdfx Qt5::Core Qt5::Gui Qt5::OpenGL ${GL_LIB} ${GLEW_LIB} ${TNZLIBS} ${PTHREAD_LIBRARY})
|
target_link_libraries(tnzstdfx Qt5::Core Qt5::Gui Qt5::OpenGL ${GL_LIB} ${GLEW_LIB} ${TNZLIBS} ${PTHREAD_LIBRARY})
|
||||||
|
|
||||||
|
if(OpenCV_FOUND)
|
||||||
|
target_link_libraries(tnzstdfx ${OpenCV_LIBS})
|
||||||
|
endif()
|
||||||
|
|
299
toonz/sources/stdfx/iwa_bloomfx.cpp
Normal file
299
toonz/sources/stdfx/iwa_bloomfx.cpp
Normal file
|
@ -0,0 +1,299 @@
|
||||||
|
#include "iwa_bloomfx.h"
|
||||||
|
|
||||||
|
#include "tparamuiconcept.h"
|
||||||
|
|
||||||
|
#include <QVector>
|
||||||
|
#include <QPair>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
// convert sRGB color space to power space
|
||||||
|
template <typename T = double>
|
||||||
|
inline T to_linear_color_space(T nonlinear_color, T exposure, T gamma) {
|
||||||
|
return std::pow(nonlinear_color, gamma) / exposure;
|
||||||
|
}
|
||||||
|
// convert power space to sRGB color space
|
||||||
|
template <typename T = double>
|
||||||
|
inline T to_nonlinear_color_space(T linear_color, T exposure, T gamma) {
|
||||||
|
return std::pow(linear_color * exposure, T(1) / gamma);
|
||||||
|
}
|
||||||
|
template <class T = double>
|
||||||
|
const T &clamp(const T &v, const T &lo, const T &hi) {
|
||||||
|
assert(!(hi < lo));
|
||||||
|
return (v < lo) ? lo : (hi < v) ? hi : v;
|
||||||
|
}
|
||||||
|
|
||||||
|
void blurByRotate(cv::Mat &mat) {
|
||||||
|
double angle = 45.0;
|
||||||
|
|
||||||
|
int size = std::ceil(std::sqrt(mat.cols * mat.cols + mat.rows * mat.rows));
|
||||||
|
int width = ((size - mat.cols) % 2 == 0) ? size : size + 1;
|
||||||
|
int height = ((size - mat.rows) % 2 == 0) ? size : size + 1;
|
||||||
|
|
||||||
|
cv::Point2f center((mat.cols - 1) / 2.0, (mat.rows - 1) / 2.0);
|
||||||
|
|
||||||
|
cv::Mat rot = cv::getRotationMatrix2D(center, angle, 1.0);
|
||||||
|
rot.at<double>(0, 2) += (width - mat.cols) / 2.0;
|
||||||
|
rot.at<double>(1, 2) += (height - mat.rows) / 2.0;
|
||||||
|
|
||||||
|
cv::Mat tmp;
|
||||||
|
cv::warpAffine(mat, tmp, rot, cv::Size(width, height));
|
||||||
|
|
||||||
|
center = cv::Point2f((width - 1) / 2.0, (height - 1) / 2.0);
|
||||||
|
rot = cv::getRotationMatrix2D(center, -angle, 1.0);
|
||||||
|
rot.at<double>(0, 2) += (mat.cols - width) / 2.0;
|
||||||
|
rot.at<double>(1, 2) += (mat.rows - height) / 2.0;
|
||||||
|
|
||||||
|
cv::warpAffine(tmp, mat, rot, mat.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
//--------------------------------------------
|
||||||
|
// Iwa_BloomFx
|
||||||
|
//--------------------------------------------
|
||||||
|
Iwa_BloomFx::Iwa_BloomFx()
|
||||||
|
: m_gamma(2.2), m_gain(2.0), m_size(100.0), m_alpha_rendering(false) {
|
||||||
|
addInputPort("Source", m_source);
|
||||||
|
bindParam(this, "gamma", m_gamma);
|
||||||
|
bindParam(this, "gain", m_gain);
|
||||||
|
bindParam(this, "size", m_size);
|
||||||
|
bindParam(this, "alpha_rendering", m_alpha_rendering);
|
||||||
|
|
||||||
|
m_gamma->setValueRange(0.1, 5.0);
|
||||||
|
m_gain->setValueRange(0.1, 10.0);
|
||||||
|
m_size->setValueRange(0.1, 1024.0);
|
||||||
|
|
||||||
|
m_size->setMeasureName("fxLength");
|
||||||
|
}
|
||||||
|
//------------------------------------------------
|
||||||
|
|
||||||
|
double Iwa_BloomFx::getSizePixelAmount(const double val, const TAffine affine) {
|
||||||
|
/*--- Convert to vector --- */
|
||||||
|
TPointD vect;
|
||||||
|
vect.x = val;
|
||||||
|
vect.y = 0.0;
|
||||||
|
/*--- Apply geometrical transformation ---*/
|
||||||
|
// For the following lines I referred to lines 586-592 of
|
||||||
|
// sources/stdfx/motionblurfx.cpp
|
||||||
|
TAffine aff(affine);
|
||||||
|
aff.a13 = aff.a23 = 0; /* ignore translation */
|
||||||
|
vect = aff * vect;
|
||||||
|
/*--- return the length of the vector ---*/
|
||||||
|
return sqrt(vect.x * vect.x + vect.y * vect.y);
|
||||||
|
}
|
||||||
|
//------------------------------------------------
|
||||||
|
|
||||||
|
template <typename RASTER, typename PIXEL>
|
||||||
|
void Iwa_BloomFx::setSourceTileToMat(const RASTER ras, cv::Mat &imgMat,
|
||||||
|
const double gamma) {
|
||||||
|
double maxi = static_cast<double>(PIXEL::maxChannelValue); // 255or65535
|
||||||
|
for (int j = 0; j < ras->getLy(); j++) {
|
||||||
|
const PIXEL *pix = ras->pixels(j);
|
||||||
|
cv::Vec3f *mat_p = imgMat.ptr<cv::Vec3f>(j);
|
||||||
|
for (int i = 0; i < ras->getLx(); i++, pix++, mat_p++) {
|
||||||
|
double pix_a = static_cast<double>(pix->m) / maxi;
|
||||||
|
if (pix_a <= 0.0) {
|
||||||
|
*mat_p = cv::Vec3f(0, 0, 0);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
double bgra[3];
|
||||||
|
bgra[0] = static_cast<double>(pix->b) / maxi;
|
||||||
|
bgra[1] = static_cast<double>(pix->g) / maxi;
|
||||||
|
bgra[2] = static_cast<double>(pix->r) / maxi;
|
||||||
|
for (int c = 0; c < 3; c++) {
|
||||||
|
// assuming that the source image is premultiplied
|
||||||
|
bgra[c] = to_linear_color_space(bgra[c] / pix_a, 1.0, gamma) * pix_a;
|
||||||
|
}
|
||||||
|
*mat_p = cv::Vec3f(bgra[0], bgra[1], bgra[2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//------------------------------------------------
|
||||||
|
template <typename RASTER, typename PIXEL>
|
||||||
|
void Iwa_BloomFx::setMatToOutput(const RASTER ras, const RASTER srcRas,
|
||||||
|
cv::Mat &ingMat, const double gamma,
|
||||||
|
const double gain, const bool withAlpha,
|
||||||
|
const int margin) {
|
||||||
|
double maxi = static_cast<double>(PIXEL::maxChannelValue); // 255or65535
|
||||||
|
for (int j = 0; j < ras->getLy(); j++) {
|
||||||
|
cv::Vec3f const *mat_p = ingMat.ptr<cv::Vec3f>(j);
|
||||||
|
PIXEL *pix = ras->pixels(j);
|
||||||
|
PIXEL *srcPix = srcRas->pixels(j + margin) + margin;
|
||||||
|
|
||||||
|
for (int i = 0; i < ras->getLx(); i++, pix++, srcPix++, mat_p++) {
|
||||||
|
double nonlinear_b =
|
||||||
|
to_nonlinear_color_space((double)(*mat_p)[0] * gain, 1.0, gamma);
|
||||||
|
double nonlinear_g =
|
||||||
|
to_nonlinear_color_space((double)(*mat_p)[1] * gain, 1.0, gamma);
|
||||||
|
double nonlinear_r =
|
||||||
|
to_nonlinear_color_space((double)(*mat_p)[2] * gain, 1.0, gamma);
|
||||||
|
|
||||||
|
nonlinear_b = clamp(nonlinear_b, 0.0, 1.0);
|
||||||
|
nonlinear_g = clamp(nonlinear_g, 0.0, 1.0);
|
||||||
|
nonlinear_r = clamp(nonlinear_r, 0.0, 1.0);
|
||||||
|
|
||||||
|
pix->r = (typename PIXEL::Channel)(nonlinear_r * (maxi + 0.999999));
|
||||||
|
pix->g = (typename PIXEL::Channel)(nonlinear_g * (maxi + 0.999999));
|
||||||
|
pix->b = (typename PIXEL::Channel)(nonlinear_b * (maxi + 0.999999));
|
||||||
|
if (withAlpha) {
|
||||||
|
double chan_a =
|
||||||
|
std::max(std::max(nonlinear_b, nonlinear_g), nonlinear_r);
|
||||||
|
pix->m = std::max((typename PIXEL::Channel)(chan_a * (maxi + 0.999999)),
|
||||||
|
srcPix->m);
|
||||||
|
} else
|
||||||
|
pix->m = (typename PIXEL::Channel)(PIXEL::maxChannelValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------
|
||||||
|
|
||||||
|
void Iwa_BloomFx::doCompute(TTile &tile, double frame,
|
||||||
|
const TRenderSettings &settings) {
|
||||||
|
// If the source is not connected, then do nothing
|
||||||
|
if (!m_source.isConnected()) {
|
||||||
|
tile.getRaster()->clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// obtain parameters
|
||||||
|
double gamma = m_gamma->getValue(frame);
|
||||||
|
double gain = m_gain->getValue(frame);
|
||||||
|
double size = getSizePixelAmount(m_size->getValue(frame), settings.m_affine);
|
||||||
|
bool withAlpha = m_alpha_rendering->getValue();
|
||||||
|
|
||||||
|
int margin = static_cast<int>(std::ceil(size));
|
||||||
|
TRectD _rect(tile.m_pos, TDimensionD(tile.getRaster()->getLx(),
|
||||||
|
tile.getRaster()->getLy()));
|
||||||
|
_rect = _rect.enlarge(static_cast<double>(margin));
|
||||||
|
TDimensionI dimSrc(static_cast<int>(_rect.getLx() + 0.5),
|
||||||
|
static_cast<int>(_rect.getLy() + 0.5));
|
||||||
|
|
||||||
|
// obtain the source tile
|
||||||
|
TTile sourceTile;
|
||||||
|
m_source->allocateAndCompute(sourceTile, _rect.getP00(), dimSrc,
|
||||||
|
tile.getRaster(), frame, settings);
|
||||||
|
|
||||||
|
// set the source image to cvMat, converting to linear color space
|
||||||
|
cv::Mat imgMat(cv::Size(dimSrc.lx, dimSrc.ly), CV_32FC3);
|
||||||
|
TRaster32P ras32 = tile.getRaster();
|
||||||
|
TRaster64P ras64 = tile.getRaster();
|
||||||
|
if (ras32)
|
||||||
|
setSourceTileToMat<TRaster32P, TPixel32>(sourceTile.getRaster(), imgMat,
|
||||||
|
gamma);
|
||||||
|
else if (ras64)
|
||||||
|
setSourceTileToMat<TRaster64P, TPixel64>(sourceTile.getRaster(), imgMat,
|
||||||
|
gamma);
|
||||||
|
|
||||||
|
// compute size and intensity ratios of resampled layers
|
||||||
|
// resample size is reduced from the specified size, taking into account
|
||||||
|
// that the gaussian blur (x 2) and the blur by rotation resampling (x sqrt2)
|
||||||
|
double no_blur_size = size / (2 * 1.5);
|
||||||
|
// find the mimimum "power of 2" value which is the same as or larger than the
|
||||||
|
// filter size
|
||||||
|
int level = 1;
|
||||||
|
double power_of_2 = 1.0;
|
||||||
|
while (1) {
|
||||||
|
if (power_of_2 >= no_blur_size) break;
|
||||||
|
level++;
|
||||||
|
power_of_2 *= 2.0;
|
||||||
|
}
|
||||||
|
// store the size of resampled layers
|
||||||
|
QVector<cv::Size> sizes;
|
||||||
|
double tmp_filterSize = no_blur_size;
|
||||||
|
double width = static_cast<double>(imgMat.size().width);
|
||||||
|
double height = static_cast<double>(imgMat.size().height);
|
||||||
|
for (int lvl = 0; lvl < level - 1; lvl++) {
|
||||||
|
int tmp_w = static_cast<int>(std::ceil(width / tmp_filterSize));
|
||||||
|
int tmp_h = static_cast<int>(std::ceil(height / tmp_filterSize));
|
||||||
|
sizes.push_front(cv::Size(tmp_w, tmp_h));
|
||||||
|
tmp_filterSize *= 0.5;
|
||||||
|
}
|
||||||
|
sizes.push_front(imgMat.size());
|
||||||
|
|
||||||
|
// the filter is based on the nearest power-of-2 sized one with an adjustment
|
||||||
|
// reducing the sizes and increasing the intensity with this ratio
|
||||||
|
double ratio = power_of_2 / no_blur_size;
|
||||||
|
// base filter sizes will be 1, 2, 4, ... 2^(level-1)
|
||||||
|
// intensity of the filter with sizes > 2
|
||||||
|
double intensity_all = power_of_2 / (power_of_2 * 2.0 - 1.0);
|
||||||
|
// intensity of the filter with size 1, so that the amount of the filter at
|
||||||
|
// the center point is always 1.0
|
||||||
|
double intensity_front = 1.0 - (1.0 - intensity_all) * ratio;
|
||||||
|
|
||||||
|
std::vector<cv::Mat> dst(level);
|
||||||
|
cv::Size const ksize(3, 3);
|
||||||
|
|
||||||
|
cv::Mat tmp;
|
||||||
|
int i;
|
||||||
|
// for each level of filter (from larger to smaller)
|
||||||
|
for (i = 0; i < level;) {
|
||||||
|
// scaling down the size
|
||||||
|
if (i) {
|
||||||
|
cv::resize(imgMat, tmp, sizes[i], 0.0, 0.0, cv::INTER_AREA);
|
||||||
|
imgMat = tmp;
|
||||||
|
}
|
||||||
|
// gaussian blur
|
||||||
|
cv::GaussianBlur(imgMat, dst[i], ksize, 0.0);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
// for each level of filter (from smaller to larger)
|
||||||
|
for (--i; i > 0; --i) {
|
||||||
|
// scaling up the size
|
||||||
|
cv::resize(dst[i], tmp, dst[i - 1].size());
|
||||||
|
// blur by rotational resampling in order to reduce box-shaped artifact
|
||||||
|
blurByRotate(tmp);
|
||||||
|
// add to the upper resampled image
|
||||||
|
if (i > 1)
|
||||||
|
dst[i - 1] += tmp;
|
||||||
|
else
|
||||||
|
imgMat = dst[0] * intensity_front + tmp * intensity_all;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the subimage without margin
|
||||||
|
cv::Rect roi(cv::Point(margin, margin),
|
||||||
|
cv::Size(tile.getRaster()->getLx(), tile.getRaster()->getLy()));
|
||||||
|
imgMat = imgMat(roi);
|
||||||
|
|
||||||
|
// set the result to the tile, converting to rgb channel values
|
||||||
|
if (ras32)
|
||||||
|
setMatToOutput<TRaster32P, TPixel32>(tile.getRaster(),
|
||||||
|
sourceTile.getRaster(), imgMat, gamma,
|
||||||
|
gain, withAlpha, margin);
|
||||||
|
else if (ras64)
|
||||||
|
setMatToOutput<TRaster64P, TPixel64>(tile.getRaster(),
|
||||||
|
sourceTile.getRaster(), imgMat, gamma,
|
||||||
|
gain, withAlpha, margin);
|
||||||
|
}
|
||||||
|
//------------------------------------------------
|
||||||
|
|
||||||
|
bool Iwa_BloomFx::doGetBBox(double frame, TRectD &bBox,
|
||||||
|
const TRenderSettings &info) {
|
||||||
|
if (!m_source.isConnected()) {
|
||||||
|
bBox = TRectD();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool ret = m_source->doGetBBox(frame, bBox, info);
|
||||||
|
int margin = static_cast<int>(
|
||||||
|
std::ceil(getSizePixelAmount(m_size->getValue(frame), info.m_affine)));
|
||||||
|
if (margin > 0) {
|
||||||
|
bBox = bBox.enlarge(static_cast<double>(margin));
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
//------------------------------------------------
|
||||||
|
|
||||||
|
bool Iwa_BloomFx::canHandle(const TRenderSettings &info, double frame) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//------------------------------------------------
|
||||||
|
|
||||||
|
void Iwa_BloomFx::getParamUIs(TParamUIConcept *&concepts, int &length) {
|
||||||
|
concepts = new TParamUIConcept[length = 1];
|
||||||
|
|
||||||
|
concepts[0].m_type = TParamUIConcept::RADIUS;
|
||||||
|
concepts[0].m_label = "Size";
|
||||||
|
concepts[0].m_params.push_back(m_size);
|
||||||
|
}
|
||||||
|
//------------------------------------------------
|
||||||
|
|
||||||
|
FX_PLUGIN_IDENTIFIER(Iwa_BloomFx, "iwa_BloomFx")
|
49
toonz/sources/stdfx/iwa_bloomfx.h
Normal file
49
toonz/sources/stdfx/iwa_bloomfx.h
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*------------
|
||||||
|
Iwa_BloomFx
|
||||||
|
Based on the LightBloom plugin fx by Dwango, with modifications as follows:
|
||||||
|
- parameters are reduced & simplified to gamma, gain and size
|
||||||
|
- reduced the block noise appeared especially when the gamma is with higher
|
||||||
|
value
|
||||||
|
- enabled to render alpha gradation
|
||||||
|
- enabled to adjust size with the viewer gadget
|
||||||
|
--------------*/
|
||||||
|
|
||||||
|
#ifndef IWA_BLOOMFX_H
|
||||||
|
#define IWA_BLOOMFX_H
|
||||||
|
|
||||||
|
#include "stdfx.h"
|
||||||
|
#include "tfxparam.h"
|
||||||
|
#include <opencv2/opencv.hpp>
|
||||||
|
|
||||||
|
class Iwa_BloomFx : public TStandardRasterFx {
|
||||||
|
FX_PLUGIN_DECLARATION(Iwa_BloomFx)
|
||||||
|
protected:
|
||||||
|
TRasterFxPort m_source;
|
||||||
|
TDoubleParamP m_gamma;
|
||||||
|
TDoubleParamP m_gain;
|
||||||
|
TDoubleParamP m_size;
|
||||||
|
TBoolParamP m_alpha_rendering;
|
||||||
|
|
||||||
|
double getSizePixelAmount(const double val, const TAffine affine);
|
||||||
|
template <typename RASTER, typename PIXEL>
|
||||||
|
void setSourceTileToMat(const RASTER ras, cv::Mat &ingMat,
|
||||||
|
const double gamma);
|
||||||
|
|
||||||
|
template <typename RASTER, typename PIXEL>
|
||||||
|
void setMatToOutput(const RASTER ras, const RASTER srcRas, cv::Mat &ingMat,
|
||||||
|
const double gamma, const double gain,
|
||||||
|
const bool withAlpha, const int margin);
|
||||||
|
|
||||||
|
public:
|
||||||
|
Iwa_BloomFx();
|
||||||
|
void doCompute(TTile &tile, double frame,
|
||||||
|
const TRenderSettings &settings) override;
|
||||||
|
bool doGetBBox(double frame, TRectD &bBox,
|
||||||
|
const TRenderSettings &info) override;
|
||||||
|
bool canHandle(const TRenderSettings &info, double frame) override;
|
||||||
|
void getParamUIs(TParamUIConcept *&concepts, int &length) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in a new issue