glare fx revised - fixed chromatic balance - introduced iris preset - fx version parameter to maintain backward compatibility
This commit is contained in:
parent
be4d0ba3e0
commit
6af69b10e6
8 changed files with 300 additions and 20 deletions
|
@ -1316,9 +1316,16 @@
|
||||||
|
|
||||||
<item>"STD_iwa_GlareFx" "Glare Iwa" </item>
|
<item>"STD_iwa_GlareFx" "Glare Iwa" </item>
|
||||||
<item>"STD_iwa_GlareFx.renderMode" "Render Mode" </item>
|
<item>"STD_iwa_GlareFx.renderMode" "Render Mode" </item>
|
||||||
|
<item>"STD_iwa_GlareFx.irisMode" "Iris Shape" </item>
|
||||||
|
<item>"STD_iwa_GlareFx.irisScale" "Iris Scale" </item>
|
||||||
|
<item>"STD_iwa_GlareFx.irisGearEdgeCount" "Edges" </item>
|
||||||
|
<item>"STD_iwa_GlareFx.irisRandomSeed" "Random Seed" </item>
|
||||||
|
<item>"STD_iwa_GlareFx.irisSymmetry" "Symmetry" </item>
|
||||||
|
<item>"STD_iwa_GlareFx.irisAppearance" "Appearance" </item>
|
||||||
<item>"STD_iwa_GlareFx.intensity" "Intensity" </item>
|
<item>"STD_iwa_GlareFx.intensity" "Intensity" </item>
|
||||||
<item>"STD_iwa_GlareFx.size" "Filter Size" </item>
|
<item>"STD_iwa_GlareFx.size" "Filter Size" </item>
|
||||||
<item>"STD_iwa_GlareFx.rotation" "Filter Rotation" </item>
|
<item>"STD_iwa_GlareFx.rotation" "Filter Rotation" </item>
|
||||||
|
<item>"STD_iwa_GlareFx.aberration" "Chromatic Aberration" </item>
|
||||||
<item>"STD_iwa_GlareFx.noise_factor" "Noise Factor" </item>
|
<item>"STD_iwa_GlareFx.noise_factor" "Noise Factor" </item>
|
||||||
<item>"STD_iwa_GlareFx.noise_size" "Noise Size" </item>
|
<item>"STD_iwa_GlareFx.noise_size" "Noise Size" </item>
|
||||||
<item>"STD_iwa_GlareFx.noise_octave" "Noise Octave" </item>
|
<item>"STD_iwa_GlareFx.noise_octave" "Noise Octave" </item>
|
||||||
|
|
|
@ -1,9 +1,24 @@
|
||||||
<fxlayout help_command="iexplore" help_file="BokehIwa.html">
|
<fxlayout help_command="iexplore" help_file="BokehIwa.html">
|
||||||
<page name="Glare Iwa">
|
<page name="Glare Iwa">
|
||||||
<control>renderMode</control>
|
<control>renderMode</control>
|
||||||
|
<control>irisMode</control>
|
||||||
|
<vbox modeSensitive="irisMode" mode="1,2,3,4">
|
||||||
|
<separator/>
|
||||||
|
<control>irisScale</control>
|
||||||
|
<control>irisSymmetry</control>
|
||||||
|
<control>irisAppearance</control>
|
||||||
|
</vbox>
|
||||||
|
<vbox modeSensitive="irisMode" mode="4">
|
||||||
|
<control>irisGearEdgeCount</control>
|
||||||
|
<control>irisRandomSeed</control>
|
||||||
|
</vbox>
|
||||||
|
<vbox modeSensitive="irisMode" mode="1,2,3,4">
|
||||||
|
<separator/>
|
||||||
|
</vbox>
|
||||||
<control>intensity</control>
|
<control>intensity</control>
|
||||||
<control>size</control>
|
<control>size</control>
|
||||||
<control>rotation</control>
|
<control>rotation</control>
|
||||||
|
<control>aberration</control>
|
||||||
<control>noise_factor</control>
|
<control>noise_factor</control>
|
||||||
<control>noise_size</control>
|
<control>noise_size</control>
|
||||||
<control>noise_octave</control>
|
<control>noise_octave</control>
|
||||||
|
|
|
@ -701,6 +701,9 @@ void TFx::setNewIdentifier() { m_imp->m_id = ++m_imp->m_nextId; }
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
void TFx::loadData(TIStream &is) {
|
void TFx::loadData(TIStream &is) {
|
||||||
|
// default version of fx is 1
|
||||||
|
setFxVersion(1);
|
||||||
|
|
||||||
std::string tagName;
|
std::string tagName;
|
||||||
VersionNumber tnzVersion = is.getVersion();
|
VersionNumber tnzVersion = is.getVersion();
|
||||||
// Prevent to load "params" tag under "super" tag on saving macro fx.
|
// Prevent to load "params" tag under "super" tag on saving macro fx.
|
||||||
|
@ -818,6 +821,10 @@ void TFx::loadData(TIStream &is) {
|
||||||
is >> groupName;
|
is >> groupName;
|
||||||
groupNames.append(groupName);
|
groupNames.append(groupName);
|
||||||
}
|
}
|
||||||
|
} else if (tagName == "fxVersion") {
|
||||||
|
int version = 1;
|
||||||
|
is >> version;
|
||||||
|
setFxVersion(version);
|
||||||
} else {
|
} else {
|
||||||
throw TException("Unknown tag!");
|
throw TException("Unknown tag!");
|
||||||
}
|
}
|
||||||
|
@ -907,6 +914,7 @@ void TFx::saveData(TOStream &os) {
|
||||||
for (i = 0; i < groupNameStack.size(); i++) os << groupNameStack[i];
|
for (i = 0; i < groupNameStack.size(); i++) os << groupNameStack[i];
|
||||||
os.closeChild();
|
os.closeChild();
|
||||||
}
|
}
|
||||||
|
if (getFxVersion() != 1) os.child("fxVersion") << getFxVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
@ -992,6 +1000,14 @@ TFx *TFx::getLinkedFx() const {
|
||||||
return m_imp->m_next->m_fx;
|
return m_imp->m_next->m_fx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
void TFx::setFxVersion(int v) { m_imp->m_attributes.setFxVersion(v); }
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
int TFx::getFxVersion() const { return m_imp->m_attributes.getFxVersion(); }
|
||||||
|
|
||||||
//===================================================
|
//===================================================
|
||||||
//
|
//
|
||||||
// TFxTimeRegion
|
// TFxTimeRegion
|
||||||
|
|
|
@ -503,6 +503,9 @@ public:
|
||||||
// parameter is loaded. Do nothing by default.
|
// parameter is loaded. Do nothing by default.
|
||||||
virtual void onObsoleteParamLoaded(const std::string ¶mName) {}
|
virtual void onObsoleteParamLoaded(const std::string ¶mName) {}
|
||||||
|
|
||||||
|
void setFxVersion(int);
|
||||||
|
int getFxVersion() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Id-related functions
|
// Id-related functions
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,8 @@ class DVAPI TFxAttributes {
|
||||||
|
|
||||||
/*-- MotionBlurなどのFxのために、オブジェクトの軌跡のデータを取得する --*/
|
/*-- MotionBlurなどのFxのために、オブジェクトの軌跡のデータを取得する --*/
|
||||||
QList<TPointD> m_motionPoints;
|
QList<TPointD> m_motionPoints;
|
||||||
|
// to maintain backward compatibility in the fx
|
||||||
|
int m_fxVersion;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TFxAttributes();
|
TFxAttributes();
|
||||||
|
@ -62,6 +64,8 @@ public:
|
||||||
m_motionPoints = motionPoints;
|
m_motionPoints = motionPoints;
|
||||||
}
|
}
|
||||||
QList<TPointD> getMotionPoints() { return m_motionPoints; }
|
QList<TPointD> getMotionPoints() { return m_motionPoints; }
|
||||||
|
void setFxVersion(int version) { m_fxVersion = version; }
|
||||||
|
int getFxVersion() const { return m_fxVersion; };
|
||||||
|
|
||||||
// Group management
|
// Group management
|
||||||
|
|
||||||
|
|
|
@ -12,11 +12,15 @@
|
||||||
#include "iwa_xyz.h"
|
#include "iwa_xyz.h"
|
||||||
#include "iwa_simplexnoise.h"
|
#include "iwa_simplexnoise.h"
|
||||||
|
|
||||||
|
#include <random>
|
||||||
|
|
||||||
#include <QPair>
|
#include <QPair>
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
#include <QReadWriteLock>
|
#include <QReadWriteLock>
|
||||||
#include <QMutexLocker>
|
#include <QMutexLocker>
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
|
#include <QImage>
|
||||||
|
#include <QPainter>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
// FFT coordinate -> Normal corrdinate
|
// FFT coordinate -> Normal corrdinate
|
||||||
|
@ -38,25 +42,55 @@ inline int getCoord(int i, int j, int lx, int ly) {
|
||||||
|
|
||||||
Iwa_GlareFx::Iwa_GlareFx()
|
Iwa_GlareFx::Iwa_GlareFx()
|
||||||
: m_renderMode(new TIntEnumParam(RendeMode_FilterPreview, "Filter Preview"))
|
: m_renderMode(new TIntEnumParam(RendeMode_FilterPreview, "Filter Preview"))
|
||||||
|
, m_irisMode(new TIntEnumParam(Iris_InputImage, "Input Image"))
|
||||||
|
, m_irisScale(0.2)
|
||||||
|
, m_irisGearEdgeCount(10)
|
||||||
|
, m_irisRandomSeed(0)
|
||||||
|
, m_irisSymmetry(1.0)
|
||||||
|
, m_irisAppearance(new TIntEnumParam())
|
||||||
, m_intensity(0.0)
|
, m_intensity(0.0)
|
||||||
, m_size(100.0)
|
, m_size(100.0)
|
||||||
, m_rotation(0.0)
|
, m_rotation(0.0)
|
||||||
|
, m_aberration(1.0)
|
||||||
, m_noise_factor(0.0)
|
, m_noise_factor(0.0)
|
||||||
, m_noise_size(0.5)
|
, m_noise_size(0.5)
|
||||||
, m_noise_octave(new TIntEnumParam(1, "1"))
|
, m_noise_octave(new TIntEnumParam(1, "1"))
|
||||||
, m_noise_evolution(0.0)
|
, m_noise_evolution(0.0)
|
||||||
, m_noise_offset(TPointD(0, 0)) {
|
, m_noise_offset(TPointD(0, 0)) {
|
||||||
|
// Version 1 : lights had been constantly summed in all wavelength
|
||||||
|
// Version 2 : intensities are weighted proportional to 1/(rambda^2)
|
||||||
|
setFxVersion(2);
|
||||||
|
|
||||||
// Bind the common parameters
|
// Bind the common parameters
|
||||||
addInputPort("Source", m_source);
|
addInputPort("Source", m_source);
|
||||||
addInputPort("Iris", m_iris);
|
addInputPort("Iris", m_iris);
|
||||||
|
|
||||||
bindParam(this, "renderMode", m_renderMode);
|
bindParam(this, "renderMode", m_renderMode);
|
||||||
m_renderMode->addItem(RendeMode_Render, "Render");
|
m_renderMode->addItem(RendeMode_Render, "Render");
|
||||||
|
m_renderMode->addItem(RenderMode_Iris, "Iris");
|
||||||
|
|
||||||
|
bindParam(this, "irisMode", m_irisMode);
|
||||||
|
m_irisMode->addItem(Iris_Square, "4 Streaks");
|
||||||
|
m_irisMode->addItem(Iris_Hexagon, "6 Streaks");
|
||||||
|
m_irisMode->addItem(Iris_Octagon, "8 Streaks");
|
||||||
|
m_irisMode->addItem(Iris_GearShape, "Multiple Streaks");
|
||||||
|
|
||||||
|
bindParam(this, "irisScale", m_irisScale);
|
||||||
|
bindParam(this, "irisGearEdgeCount", m_irisGearEdgeCount);
|
||||||
|
bindParam(this, "irisRandomSeed", m_irisRandomSeed);
|
||||||
|
bindParam(this, "irisSymmetry", m_irisSymmetry);
|
||||||
|
bindParam(this, "irisAppearance", m_irisAppearance);
|
||||||
|
m_irisAppearance->addItem(Appearance_ThinLine, "Thin Line");
|
||||||
|
m_irisAppearance->addItem(Appearance_MediumLine, "Medium Line");
|
||||||
|
m_irisAppearance->addItem(Appearance_ThickLine, "Thick Line");
|
||||||
|
m_irisAppearance->addItem(Appearance_Fill, "Filled");
|
||||||
|
m_irisAppearance->setValue(Appearance_MediumLine);
|
||||||
|
|
||||||
bindParam(this, "intensity", m_intensity, false);
|
bindParam(this, "intensity", m_intensity, false);
|
||||||
bindParam(this, "size", m_size, false);
|
bindParam(this, "size", m_size, false);
|
||||||
m_size->setMeasureName("fxLength");
|
m_size->setMeasureName("fxLength");
|
||||||
bindParam(this, "rotation", m_rotation, false);
|
bindParam(this, "rotation", m_rotation, false);
|
||||||
|
bindParam(this, "aberration", m_aberration, false);
|
||||||
|
|
||||||
bindParam(this, "noise_factor", m_noise_factor, false);
|
bindParam(this, "noise_factor", m_noise_factor, false);
|
||||||
bindParam(this, "noise_size", m_noise_size, false);
|
bindParam(this, "noise_size", m_noise_size, false);
|
||||||
|
@ -69,9 +103,15 @@ Iwa_GlareFx::Iwa_GlareFx()
|
||||||
m_noise_offset->getX()->setMeasureName("fxLength");
|
m_noise_offset->getX()->setMeasureName("fxLength");
|
||||||
m_noise_offset->getY()->setMeasureName("fxLength");
|
m_noise_offset->getY()->setMeasureName("fxLength");
|
||||||
|
|
||||||
|
m_irisScale->setValueRange(0.1, 0.8);
|
||||||
|
m_irisGearEdgeCount->setValueRange(3, 50);
|
||||||
|
m_irisSymmetry->setValueRange(0.1, 1.0);
|
||||||
|
m_irisRandomSeed->setValueRange(0, (std::numeric_limits<int>::max)());
|
||||||
|
|
||||||
m_intensity->setValueRange(-5.0, 5.0);
|
m_intensity->setValueRange(-5.0, 5.0);
|
||||||
m_size->setValueRange(10.0, 500.0);
|
m_size->setValueRange(10.0, 1500.0);
|
||||||
m_rotation->setValueRange(-1800, 1800);
|
m_rotation->setValueRange(-1800, 1800);
|
||||||
|
m_aberration->setValueRange(-2.0, 2.0);
|
||||||
m_noise_factor->setValueRange(0.0, 1.0);
|
m_noise_factor->setValueRange(0.0, 1.0);
|
||||||
m_noise_size->setValueRange(0.01, 3.0);
|
m_noise_size->setValueRange(0.01, 3.0);
|
||||||
}
|
}
|
||||||
|
@ -91,12 +131,149 @@ double Iwa_GlareFx::getSizePixelAmount(const double val, const TAffine affine) {
|
||||||
/*--- return the length of the vector ---*/
|
/*--- return the length of the vector ---*/
|
||||||
return sqrt(vect.x * vect.x + vect.y * vect.y);
|
return sqrt(vect.x * vect.x + vect.y * vect.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
|
||||||
|
void Iwa_GlareFx::drawPresetIris(TRaster32P irisRas, double irisSize,
|
||||||
|
const double frame) {
|
||||||
|
QImage img(irisRas->getLx(), irisRas->getLy(),
|
||||||
|
QImage::Format_ARGB32_Premultiplied);
|
||||||
|
img.fill(Qt::black);
|
||||||
|
QPainter painter(&img);
|
||||||
|
painter.setRenderHint(QPainter::Antialiasing, true);
|
||||||
|
painter.translate(
|
||||||
|
QPointF((float)irisRas->getLx() / 2.0, (float)irisRas->getLy() / 2.0));
|
||||||
|
painter.scale(irisSize, irisSize);
|
||||||
|
// shrink a bit
|
||||||
|
painter.scale(0.9, 0.9);
|
||||||
|
|
||||||
|
QPen pen(Qt::white);
|
||||||
|
double lineWidthRatio;
|
||||||
|
int appearance = m_irisAppearance->getValue();
|
||||||
|
if (appearance == Appearance_Fill) {
|
||||||
|
painter.setPen(Qt::NoPen);
|
||||||
|
painter.setBrush(Qt::white);
|
||||||
|
} else {
|
||||||
|
assert(appearance >= 0 && appearance <= 2);
|
||||||
|
pen.setCapStyle(Qt::RoundCap);
|
||||||
|
pen.setJoinStyle(Qt::MiterJoin);
|
||||||
|
double ratio[3] = {0.05, 0.1, 0.2};
|
||||||
|
lineWidthRatio = ratio[appearance];
|
||||||
|
pen.setWidthF(lineWidthRatio);
|
||||||
|
painter.setPen(pen);
|
||||||
|
painter.setBrush(Qt::NoBrush);
|
||||||
|
}
|
||||||
|
|
||||||
|
double symmetry = m_irisSymmetry->getValue(frame);
|
||||||
|
|
||||||
|
switch (m_irisMode->getValue()) {
|
||||||
|
case Iris_Square:
|
||||||
|
painter.scale(1.0, symmetry);
|
||||||
|
painter.drawRect(QRectF(-1.0, -1.0, 2.0, 2.0));
|
||||||
|
break;
|
||||||
|
case Iris_Hexagon: {
|
||||||
|
QPointF p(1.0 - 0.5 * symmetry, symmetry * std::sqrt(3) * 0.5);
|
||||||
|
const QPointF points[6] = {-p, QPointF(-1.0, 0.0), QPointF(-p.x(), p.y()),
|
||||||
|
p, QPointF(1.0, 0.0), QPointF(p.x(), -p.y())};
|
||||||
|
if (appearance != Appearance_Fill) {
|
||||||
|
if (symmetry < 1.0) {
|
||||||
|
painter.drawPolyline(points, 3);
|
||||||
|
painter.drawPolyline(&points[3], 3);
|
||||||
|
}
|
||||||
|
pen.setWidthF(lineWidthRatio * symmetry);
|
||||||
|
painter.setPen(pen);
|
||||||
|
}
|
||||||
|
painter.drawPolygon(points, 6);
|
||||||
|
if (appearance != Appearance_Fill && symmetry < 1.0) {
|
||||||
|
pen.setColor(Qt::black);
|
||||||
|
painter.setPen(pen);
|
||||||
|
painter.setBrush(Qt::NoBrush);
|
||||||
|
painter.drawRect(
|
||||||
|
QRectF(-1.2, -p.y() - symmetry, 2.4, (p.y() + symmetry) * 2.0));
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case Iris_Octagon: {
|
||||||
|
double u = (2 + std::sqrt(2) * (1 - symmetry)) / (2 * std::sqrt(2) + 2);
|
||||||
|
double v = (2 + std::sqrt(2) * (1 + symmetry)) / (2 * std::sqrt(2) + 2);
|
||||||
|
const QPointF points[8] = {QPointF(u, v), QPointF(v, u), QPointF(v, -u),
|
||||||
|
QPointF(u, -v), QPointF(-u, -v), QPointF(-v, -u),
|
||||||
|
QPointF(-v, u), QPointF(-u, v)};
|
||||||
|
if (appearance != Appearance_Fill) {
|
||||||
|
if (symmetry < 1.0) {
|
||||||
|
painter.drawLine(points[0], points[1]);
|
||||||
|
painter.drawLine(points[2], points[3]);
|
||||||
|
painter.drawLine(points[4], points[5]);
|
||||||
|
painter.drawLine(points[6], points[7]);
|
||||||
|
}
|
||||||
|
pen.setWidthF(lineWidthRatio * symmetry);
|
||||||
|
painter.setPen(pen);
|
||||||
|
}
|
||||||
|
painter.drawPolygon(points, 8);
|
||||||
|
if (appearance != Appearance_Fill && symmetry < 1.0) {
|
||||||
|
pen.setColor(Qt::black);
|
||||||
|
painter.setPen(pen);
|
||||||
|
painter.setBrush(Qt::NoBrush);
|
||||||
|
painter.drawRect(QRectF(-v - symmetry, -v - symmetry,
|
||||||
|
(v + symmetry) * 2.0, (v + symmetry) * 2.0));
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case Iris_GearShape: {
|
||||||
|
int edgeCount = (int)std::round(m_irisGearEdgeCount->getValue(frame));
|
||||||
|
QPointF* points = new QPointF[edgeCount * 2];
|
||||||
|
QList<double> thickness;
|
||||||
|
double angleUnit = M_PI / (double)edgeCount;
|
||||||
|
std::mt19937_64 mt;
|
||||||
|
mt.seed(m_irisRandomSeed->getValue());
|
||||||
|
std::uniform_real_distribution<> random_plusminus1(-1.0, 1.0);
|
||||||
|
std::uniform_real_distribution<> random_thickness(symmetry * lineWidthRatio,
|
||||||
|
lineWidthRatio);
|
||||||
|
for (int e = 0; e < edgeCount; e++) {
|
||||||
|
double baseAngle = angleUnit * e * 2.0;
|
||||||
|
double theta =
|
||||||
|
baseAngle + random_plusminus1(mt) * angleUnit * (1.0 - symmetry);
|
||||||
|
points[e * 2] = QPointF(std::cos(theta), std::sin(theta));
|
||||||
|
thickness.append(random_thickness(mt));
|
||||||
|
baseAngle += angleUnit;
|
||||||
|
theta = baseAngle + random_plusminus1(mt) * angleUnit * (1.0 - symmetry);
|
||||||
|
points[e * 2 + 1] = QPointF(0.5 * std::cos(theta), 0.5 * std::sin(theta));
|
||||||
|
thickness.append(random_thickness(mt));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (appearance != Appearance_Fill) {
|
||||||
|
for (int v = 0; v < edgeCount * 2; v++) {
|
||||||
|
int next_v = (v == edgeCount * 2 - 1) ? 0 : v + 1;
|
||||||
|
pen.setWidthF(thickness.at(v));
|
||||||
|
painter.setPen(pen);
|
||||||
|
painter.drawLine(points[v], points[next_v]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
painter.drawPolygon(points, edgeCount * 2);
|
||||||
|
}
|
||||||
|
delete[] points;
|
||||||
|
} break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int j = 0; j < img.height(); j++) {
|
||||||
|
TPixel32* pix = irisRas->pixels(j);
|
||||||
|
QRgb* img_p = (QRgb*)img.scanLine(img.height() - j - 1);
|
||||||
|
for (int i = 0; i < img.width(); i++, img_p++, pix++) {
|
||||||
|
pix->r = (unsigned char)(qRed(*img_p));
|
||||||
|
pix->g = (unsigned char)(qGreen(*img_p));
|
||||||
|
pix->b = (unsigned char)(qBlue(*img_p));
|
||||||
|
pix->m = (unsigned char)(qAlpha(*img_p));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
||||||
|
|
||||||
void Iwa_GlareFx::doCompute(TTile& tile, double frame,
|
void Iwa_GlareFx::doCompute(TTile& tile, double frame,
|
||||||
const TRenderSettings& settings) {
|
const TRenderSettings& settings) {
|
||||||
|
int irisMode = m_irisMode->getValue();
|
||||||
// If the iris is not connected, then do nothing
|
// If the iris is not connected, then do nothing
|
||||||
if (!m_iris.isConnected()) {
|
if (irisMode == Iris_InputImage && !m_iris.isConnected()) {
|
||||||
tile.getRaster()->clear();
|
tile.getRaster()->clear();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -110,16 +287,35 @@ void Iwa_GlareFx::doCompute(TTile& tile, double frame,
|
||||||
|
|
||||||
// Get the original size of Iris image
|
// Get the original size of Iris image
|
||||||
TRectD irisBBox;
|
TRectD irisBBox;
|
||||||
m_iris->getBBox(frame, irisBBox, settings);
|
|
||||||
// Compute the iris tile.
|
|
||||||
TTile irisTile;
|
TTile irisTile;
|
||||||
m_iris->allocateAndCompute(
|
TRasterP irisRas;
|
||||||
irisTile, irisBBox.getP00(),
|
|
||||||
TDimension(static_cast<int>(irisBBox.getLx() + 0.5),
|
|
||||||
static_cast<int>(irisBBox.getLy() + 0.5)),
|
|
||||||
tile.getRaster(), frame, settings);
|
|
||||||
|
|
||||||
double size = getSizePixelAmount(m_size->getValue(frame), settings.m_affine);
|
double size = getSizePixelAmount(m_size->getValue(frame), settings.m_affine);
|
||||||
|
if (irisMode == Iris_InputImage) {
|
||||||
|
m_iris->getBBox(frame, irisBBox, settings);
|
||||||
|
// Compute the iris tile.
|
||||||
|
m_iris->allocateAndCompute(
|
||||||
|
irisTile, irisBBox.getP00(),
|
||||||
|
TDimension(static_cast<int>(irisBBox.getLx() + 0.5),
|
||||||
|
static_cast<int>(irisBBox.getLy() + 0.5)),
|
||||||
|
tile.getRaster(), frame, settings);
|
||||||
|
irisRas = irisTile.getRaster();
|
||||||
|
} else {
|
||||||
|
// obtain iris bbox based on the glare pattern size
|
||||||
|
double irisSize = size * m_irisScale->getValue(frame);
|
||||||
|
irisBBox = TRectD(-irisSize, -irisSize, irisSize, irisSize);
|
||||||
|
int dimIrisRas = int(std::ceil(irisSize) * 2.0);
|
||||||
|
irisRas = TRaster32P(dimIrisRas, dimIrisRas);
|
||||||
|
drawPresetIris(irisRas, irisSize, frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (renderMode == RenderMode_Iris) {
|
||||||
|
TTranslation aff(
|
||||||
|
(double)(tile.getRaster()->getLx() - irisRas->getLx()) * 0.5,
|
||||||
|
(double)(tile.getRaster()->getLy() - irisRas->getLy()) * 0.5);
|
||||||
|
TRop::quickPut(tile.getRaster(), irisRas, aff);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int dimIris = int(std::ceil(size) * 2.0);
|
int dimIris = int(std::ceil(size) * 2.0);
|
||||||
dimIris = kiss_fft_next_fast_size(dimIris);
|
dimIris = kiss_fft_next_fast_size(dimIris);
|
||||||
while ((tile.getRaster()->getSize().lx - dimIris) % 2 != 0)
|
while ((tile.getRaster()->getSize().lx - dimIris) % 2 != 0)
|
||||||
|
@ -140,7 +336,8 @@ void Iwa_GlareFx::doCompute(TTile& tile, double frame,
|
||||||
kissfft_comp_iris_before_ras->lock();
|
kissfft_comp_iris_before_ras->lock();
|
||||||
kissfft_comp_iris_before =
|
kissfft_comp_iris_before =
|
||||||
(kiss_fft_cpx*)kissfft_comp_iris_before_ras->getRawData();
|
(kiss_fft_cpx*)kissfft_comp_iris_before_ras->getRawData();
|
||||||
convertIris(kissfft_comp_iris_before, dimIris, irisBBox, irisTile);
|
|
||||||
|
convertIris(kissfft_comp_iris_before, dimIris, irisBBox, irisRas);
|
||||||
|
|
||||||
// Create the FFT plan for the iris image.
|
// Create the FFT plan for the iris image.
|
||||||
kiss_fftnd_cfg iris_kissfft_plan;
|
kiss_fftnd_cfg iris_kissfft_plan;
|
||||||
|
@ -349,10 +546,20 @@ void Iwa_GlareFx::powerSpectrum2GlarePattern(
|
||||||
glare_xyz_ras->clear();
|
glare_xyz_ras->clear();
|
||||||
|
|
||||||
double irisRadius = double(dimIris / 2);
|
double irisRadius = double(dimIris / 2);
|
||||||
|
double aberration = m_aberration->getValue(frame);
|
||||||
|
|
||||||
|
// old version had summed each wavelength constantly.
|
||||||
|
// it was not physically-collect but keep it in order to maintain backward
|
||||||
|
// compatibility.
|
||||||
|
bool isOldVersion = getFxVersion() < 2;
|
||||||
|
|
||||||
// accumurate xyz values for each optical wavelength
|
// accumurate xyz values for each optical wavelength
|
||||||
for (int ram = 0; ram < 34; ram++) {
|
for (int ram = 0; ram < 34; ram++) {
|
||||||
double rambda = 0.38 + 0.01 * (double)ram;
|
double rambda = 0.38 + 0.01 * (double)ram;
|
||||||
double scale = 0.55 / rambda;
|
// double scale = 0.55 / rambda;
|
||||||
|
double scale = std::pow(0.55 / rambda, aberration);
|
||||||
|
double intensity_scale =
|
||||||
|
(isOldVersion) ? 1.0 : std::pow(0.55 / rambda, 2.0 * aberration);
|
||||||
scale *= irisResizeFactor;
|
scale *= irisResizeFactor;
|
||||||
for (int j = 0; j < dimIris; j++) {
|
for (int j = 0; j < dimIris; j++) {
|
||||||
double j_scaled = (double(j) - irisRadius) * scale + irisRadius;
|
double j_scaled = (double(j) - irisRadius) * scale + irisRadius;
|
||||||
|
@ -369,7 +576,8 @@ void Iwa_GlareFx::powerSpectrum2GlarePattern(
|
||||||
else if (i_scaled > double(dimIris - 1))
|
else if (i_scaled > double(dimIris - 1))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
double gl = lerpGlarePtn(i_scaled, j_scaled, glarePattern_p);
|
double gl =
|
||||||
|
lerpGlarePtn(i_scaled, j_scaled, glarePattern_p) * intensity_scale;
|
||||||
g_xyz_p->x += gl * cie_d65[ram] * xyz[ram * 3 + 0];
|
g_xyz_p->x += gl * cie_d65[ram] * xyz[ram * 3 + 0];
|
||||||
g_xyz_p->y += gl * cie_d65[ram] * xyz[ram * 3 + 1];
|
g_xyz_p->y += gl * cie_d65[ram] * xyz[ram * 3 + 1];
|
||||||
g_xyz_p->z += gl * cie_d65[ram] * xyz[ram * 3 + 2];
|
g_xyz_p->z += gl * cie_d65[ram] * xyz[ram * 3 + 2];
|
||||||
|
@ -634,7 +842,7 @@ bool Iwa_GlareFx::canHandle(const TRenderSettings& info, double frame) {
|
||||||
// Enlarge the iris to the output size.
|
// Enlarge the iris to the output size.
|
||||||
void Iwa_GlareFx::convertIris(kiss_fft_cpx* kissfft_comp_iris_before,
|
void Iwa_GlareFx::convertIris(kiss_fft_cpx* kissfft_comp_iris_before,
|
||||||
const int& dimIris, const TRectD& irisBBox,
|
const int& dimIris, const TRectD& irisBBox,
|
||||||
const TTile& irisTile) {
|
const TRasterP irisRaster) {
|
||||||
// the original size of iris image
|
// the original size of iris image
|
||||||
double2 irisOrgSize = {irisBBox.getLx(), irisBBox.getLy()};
|
double2 irisOrgSize = {irisBBox.getLx(), irisBBox.getLy()};
|
||||||
|
|
||||||
|
@ -655,10 +863,10 @@ void Iwa_GlareFx::convertIris(kiss_fft_cpx* kissfft_comp_iris_before,
|
||||||
if (dimIris % 2 == 1) affOffset += TPointD(0.5, 0.5);
|
if (dimIris % 2 == 1) affOffset += TPointD(0.5, 0.5);
|
||||||
|
|
||||||
aff = TTranslation(resizedIris->getCenterD() + affOffset);
|
aff = TTranslation(resizedIris->getCenterD() + affOffset);
|
||||||
aff *= TTranslation(-(irisTile.getRaster()->getCenterD() + affOffset));
|
aff *= TTranslation(-(irisRaster->getCenterD() + affOffset));
|
||||||
|
|
||||||
// resample the iris
|
// resample the iris
|
||||||
TRop::resample(resizedIris, irisTile.getRaster(), aff);
|
TRop::resample(resizedIris, irisRaster, aff);
|
||||||
|
|
||||||
// accumulated value
|
// accumulated value
|
||||||
float irisValAmount = 0.0;
|
float irisValAmount = 0.0;
|
||||||
|
|
|
@ -35,12 +35,21 @@ class Iwa_GlareFx : public TStandardRasterFx {
|
||||||
protected:
|
protected:
|
||||||
TRasterFxPort m_source;
|
TRasterFxPort m_source;
|
||||||
TRasterFxPort m_iris;
|
TRasterFxPort m_iris;
|
||||||
// rendering mode (filter preview / render)
|
// rendering mode (filter preview / render / iris)
|
||||||
TIntEnumParamP m_renderMode;
|
TIntEnumParamP m_renderMode;
|
||||||
|
TIntEnumParamP m_irisMode;
|
||||||
|
|
||||||
|
TDoubleParamP m_irisScale;
|
||||||
|
TDoubleParamP m_irisGearEdgeCount;
|
||||||
|
TIntParamP m_irisRandomSeed;
|
||||||
|
TDoubleParamP m_irisSymmetry;
|
||||||
|
TIntEnumParamP m_irisAppearance;
|
||||||
|
|
||||||
TDoubleParamP m_intensity;
|
TDoubleParamP m_intensity;
|
||||||
TDoubleParamP m_size;
|
TDoubleParamP m_size;
|
||||||
|
|
||||||
TDoubleParamP m_rotation;
|
TDoubleParamP m_rotation;
|
||||||
|
TDoubleParamP m_aberration;
|
||||||
|
|
||||||
TDoubleParamP m_noise_factor;
|
TDoubleParamP m_noise_factor;
|
||||||
TDoubleParamP m_noise_size;
|
TDoubleParamP m_noise_size;
|
||||||
|
@ -48,15 +57,32 @@ protected:
|
||||||
TDoubleParamP m_noise_evolution;
|
TDoubleParamP m_noise_evolution;
|
||||||
TPointParamP m_noise_offset;
|
TPointParamP m_noise_offset;
|
||||||
|
|
||||||
enum { RendeMode_FilterPreview = 0, RendeMode_Render };
|
enum { RendeMode_FilterPreview = 0, RendeMode_Render, RenderMode_Iris };
|
||||||
|
|
||||||
|
enum {
|
||||||
|
Iris_InputImage = 0,
|
||||||
|
Iris_Square,
|
||||||
|
Iris_Hexagon,
|
||||||
|
Iris_Octagon,
|
||||||
|
Iris_GearShape
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
Appearance_ThinLine,
|
||||||
|
Appearance_MediumLine,
|
||||||
|
Appearance_ThickLine,
|
||||||
|
Appearance_Fill,
|
||||||
|
};
|
||||||
|
|
||||||
double getSizePixelAmount(const double val, const TAffine affine);
|
double getSizePixelAmount(const double val, const TAffine affine);
|
||||||
|
|
||||||
|
void drawPresetIris(TRaster32P irisRas, double irisSize, const double frame);
|
||||||
|
|
||||||
// Resize / flip the iris image according to the size ratio.
|
// Resize / flip the iris image according to the size ratio.
|
||||||
// Normalize the brightness of the iris image.
|
// Normalize the brightness of the iris image.
|
||||||
// Enlarge the iris to the output size.
|
// Enlarge the iris to the output size.
|
||||||
void convertIris(kiss_fft_cpx *kissfft_comp_iris_before, const int &dimIris,
|
void convertIris(kiss_fft_cpx *kissfft_comp_iris_before, const int &dimIris,
|
||||||
const TRectD &irisBBox, const TTile &irisTile);
|
const TRectD &irisBBox, const TRasterP irisRaster);
|
||||||
|
|
||||||
void powerSpectrum2GlarePattern(const double frame, const TAffine affine,
|
void powerSpectrum2GlarePattern(const double frame, const TAffine affine,
|
||||||
kiss_fft_cpx *spectrum, double3 *glare,
|
kiss_fft_cpx *spectrum, double3 *glare,
|
||||||
|
|
|
@ -13,7 +13,8 @@ TFxAttributes::TFxAttributes()
|
||||||
, m_isOpened(false)
|
, m_isOpened(false)
|
||||||
, m_speed()
|
, m_speed()
|
||||||
, m_groupSelector(-1)
|
, m_groupSelector(-1)
|
||||||
, m_passiveCacheDataIdx(-1) {}
|
, m_passiveCacheDataIdx(-1)
|
||||||
|
, m_fxVersion(1) {}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue