mirror of
https://bitbucket.org/mfeemster/fractorium.git
synced 2025-06-30 21:36:33 -04:00
--User changes
-Add two new variations, hyperbolic and hypershift2. -Allow for animating final xforms. -More detailed diagnostics when any action in the OpenCL renderer fails. -Allow for creating an OpenCL renderer which does not share a texture with the main window, and instead manually copies its final output image from GPU to CPU then back to GPU. --Bug fixes -Text was not properly being copied out of the Info | Bounds text box. --Code changes -Remove Renderer::AccumulatorToFinalImage(v4F* pixels, size_t finalOffset), it's no longer needed or makes sense. -Controllers no longer keep track of shared status, it's kept inside the renderers. -Make getter functions in FractoriumOptionsDialog be public.
This commit is contained in:
@ -407,6 +407,8 @@ uint Timing::m_ProcessorCount;
|
||||
EXPORTPREPOSTREGVAR(Sphereblur, T) \
|
||||
EXPORTPREPOSTREGVAR(Cpow3, T) \
|
||||
EXPORTPREPOSTREGVAR(Concentric, T) \
|
||||
EXPORTPREPOSTREGVAR(Hyperbolic, T) \
|
||||
EXPORTPREPOSTREGVAR(Hypershift2, T) \
|
||||
template EMBER_API class PostSmartcropVariation<T>; /*Only implemented as post.*/ \
|
||||
EXPORTPREPOSTREGVAR(DCBubble, T) \
|
||||
EXPORTPREPOSTREGVAR(DCCarpet, T) \
|
||||
|
@ -998,17 +998,19 @@ public:
|
||||
/// <param name="angle">The angle to rotate by</param>
|
||||
void RotateAffines(T angle)
|
||||
{
|
||||
for (size_t i = 0; i < XformCount(); i++)//Only look at normal xforms, exclude final.
|
||||
size_t i = 0;
|
||||
|
||||
while (auto xform = GetTotalXform(i++))//Flam3 only allowed animation with normal xforms. This has been changed to allow animations of final xforms.
|
||||
{
|
||||
//Don't rotate xforms with animate set to 0.
|
||||
if (m_Xforms[i].m_Animate == 0)
|
||||
if (xform->m_Animate == 0)
|
||||
continue;
|
||||
|
||||
//Assume that if there are no variations, then it's a padding xform.
|
||||
if (m_Xforms[i].Empty() && m_AffineInterp != eAffineInterp::AFFINE_INTERP_LOG)
|
||||
if (xform->Empty() && m_AffineInterp != eAffineInterp::AFFINE_INTERP_LOG)
|
||||
continue;
|
||||
|
||||
m_Xforms[i].m_Affine.Rotate(angle * DEG_2_RAD_T);
|
||||
xform->m_Affine.Rotate(angle * DEG_2_RAD_T);
|
||||
//Don't rotate post.
|
||||
}
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ static void sincos(float x, float* s, float* c)
|
||||
|
||||
namespace EmberNs
|
||||
{
|
||||
#define EMBER_VERSION "1.0.0.7"
|
||||
#define EMBER_VERSION "1.0.0.8"
|
||||
#define EPS6 T(1e-6)
|
||||
#define EPS std::numeric_limits<T>::epsilon()//Apoplugin.h uses -20, but it's more mathematically correct to do it this way.
|
||||
#define ISAAC_SIZE 4
|
||||
|
@ -1093,7 +1093,8 @@ eRenderStatus Renderer<T, bucketT>::GaussianDensityFilter()
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Thin wrapper around AccumulatorToFinalImage().
|
||||
/// Produce a final, visible image by clipping, gamma correcting and spatial filtering the color values
|
||||
/// in the density filtering buffer and save to the passed in buffer.
|
||||
/// </summary>
|
||||
/// <param name="pixels">The pixel vector to allocate and store the final image in</param>
|
||||
/// <param name="finalOffset">Offset in the buffer to store the pixels to</param>
|
||||
@ -1101,31 +1102,20 @@ eRenderStatus Renderer<T, bucketT>::GaussianDensityFilter()
|
||||
template <typename T, typename bucketT>
|
||||
eRenderStatus Renderer<T, bucketT>::AccumulatorToFinalImage(vector<v4F>& pixels, size_t finalOffset)
|
||||
{
|
||||
if (PrepFinalAccumVector(pixels))
|
||||
return AccumulatorToFinalImage(pixels.data(), finalOffset);
|
||||
|
||||
return eRenderStatus::RENDER_ERROR;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Produce a final, visible image by clipping, gamma correcting and spatial filtering the color values
|
||||
/// in the density filtering buffer and save to the passed in buffer.
|
||||
/// </summary>
|
||||
/// <param name="pixels">The pre-allocated pixel buffer to store the final image in</param>
|
||||
/// <param name="finalOffset">Offset in the buffer to store the pixels to. Default: 0.</param>
|
||||
/// <returns>True if not prematurely aborted, else false.</returns>
|
||||
template <typename T, typename bucketT>
|
||||
eRenderStatus Renderer<T, bucketT>::AccumulatorToFinalImage(v4F* pixels, size_t finalOffset)
|
||||
{
|
||||
if (!pixels)
|
||||
return eRenderStatus::RENDER_ERROR;
|
||||
|
||||
EnterFinalAccum();
|
||||
|
||||
if (!PrepFinalAccumVector(pixels))
|
||||
{
|
||||
LeaveFinalAccum();
|
||||
return eRenderStatus::RENDER_ERROR;
|
||||
}
|
||||
|
||||
//Timing t(4);
|
||||
size_t filterWidth = m_SpatialFilter->FinalFilterWidth();
|
||||
bucketT g, linRange, vibrancy;
|
||||
Color<bucketT> background;
|
||||
pixels += finalOffset;
|
||||
auto p = pixels.data();
|
||||
p += finalOffset;
|
||||
PrepFinalAccumVals(background, g, linRange, vibrancy);//After this, background has been scaled from 0-1 to 0-255.
|
||||
|
||||
//If early clip, go through the entire accumulator and perform gamma correction first.
|
||||
@ -1165,7 +1155,7 @@ eRenderStatus Renderer<T, bucketT>::AccumulatorToFinalImage(v4F* pixels, size_t
|
||||
size_t pixelsRowStart = (m_YAxisUp ? ((FinalRasH() - j) - 1) : j) * FinalRasW();//Pull out of inner loop for optimization.
|
||||
size_t y = m_DensityFilterOffset + (j * Supersample());//Start at the beginning row of each super sample block.
|
||||
size_t clampedFilterH = std::min(filterWidth, m_SuperRasH - y);//Make sure the filter doesn't go past the bottom of the gutter.
|
||||
auto pv4T = pixels + pixelsRowStart;
|
||||
auto pv4T = p + pixelsRowStart;
|
||||
|
||||
for (size_t i = 0; i < FinalRasW(); i++, pv4T++)
|
||||
{
|
||||
@ -1210,11 +1200,11 @@ eRenderStatus Renderer<T, bucketT>::AccumulatorToFinalImage(v4F* pixels, size_t
|
||||
{
|
||||
for (i = 0; i < FinalRasW(); i++)
|
||||
{
|
||||
auto p = pixels + (i + j * FinalRasW());
|
||||
p->r = m_TempEmber.m_Palette[i * 256 / FinalRasW()][0];
|
||||
p->g = m_TempEmber.m_Palette[i * 256 / FinalRasW()][1];
|
||||
p->b = m_TempEmber.m_Palette[i * 256 / FinalRasW()][2];
|
||||
p->a = 1;
|
||||
auto pp = p + (i + j * FinalRasW());
|
||||
pp->r = m_TempEmber.m_Palette[i * 256 / FinalRasW()][0];
|
||||
pp->g = m_TempEmber.m_Palette[i * 256 / FinalRasW()][1];
|
||||
pp->b = m_TempEmber.m_Palette[i * 256 / FinalRasW()][2];
|
||||
pp->a = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -77,7 +77,6 @@ protected:
|
||||
virtual eRenderStatus LogScaleDensityFilter(bool forceOutput = false);
|
||||
virtual eRenderStatus GaussianDensityFilter();
|
||||
virtual eRenderStatus AccumulatorToFinalImage(vector<v4F>& pixels, size_t finalOffset);
|
||||
virtual eRenderStatus AccumulatorToFinalImage(v4F* pixels, size_t finalOffset);
|
||||
virtual EmberStats Iterate(size_t iterCount, size_t temporalSample);
|
||||
virtual void ComputeCurves();
|
||||
|
||||
|
@ -514,6 +514,13 @@ size_t RendererBase::ThreadCount() const { return m_ThreadsToUse; }
|
||||
/// <returns>eRendererType::CPU_RENDERER</returns>
|
||||
eRendererType RendererBase::RendererType() const { return eRendererType::CPU_RENDERER; }
|
||||
|
||||
/// <summary>
|
||||
/// Get whether the renderer uses a shared texture with OpenGL.
|
||||
/// This only applies to the OpenCL renderer (which can be shared or unshared), so it's always false in the base.
|
||||
/// </summary>
|
||||
/// <returns>True if shared, else false. Always false in the base.</returns>
|
||||
bool RendererBase::Shared() const { return false; }
|
||||
|
||||
/// <summary>
|
||||
/// //Non-virtual threading control.
|
||||
/// </summary>
|
||||
|
@ -164,6 +164,7 @@ public:
|
||||
//Virtual render properties, getters and setters.
|
||||
virtual size_t ThreadCount() const;
|
||||
virtual eRendererType RendererType() const;
|
||||
virtual bool Shared() const;
|
||||
|
||||
//Abstract render properties, getters only.
|
||||
virtual size_t TemporalSamples() const = 0;
|
||||
|
@ -197,6 +197,8 @@ enum class eVariationId : et
|
||||
VAR_HOLE ,
|
||||
VAR_HORSESHOE ,
|
||||
VAR_HYPERBOLIC ,
|
||||
VAR_HYPERCROP ,
|
||||
VAR_HYPERSHIFT2 ,
|
||||
VAR_HYPERTILE ,
|
||||
VAR_HYPERTILE1 ,
|
||||
VAR_HYPERTILE2 ,
|
||||
@ -540,6 +542,8 @@ enum class eVariationId : et
|
||||
VAR_PRE_HOLE,
|
||||
VAR_PRE_HORSESHOE,
|
||||
VAR_PRE_HYPERBOLIC,
|
||||
VAR_PRE_HYPERCROP,
|
||||
VAR_PRE_HYPERSHIFT2,
|
||||
VAR_PRE_HYPERTILE,
|
||||
VAR_PRE_HYPERTILE1,
|
||||
VAR_PRE_HYPERTILE2,
|
||||
@ -883,6 +887,8 @@ enum class eVariationId : et
|
||||
VAR_POST_HOLE,
|
||||
VAR_POST_HORSESHOE,
|
||||
VAR_POST_HYPERBOLIC,
|
||||
VAR_POST_HYPERCROP,
|
||||
VAR_POST_HYPERSHIFT2,
|
||||
VAR_POST_HYPERTILE,
|
||||
VAR_POST_HYPERTILE1,
|
||||
VAR_POST_HYPERTILE2,
|
||||
|
@ -359,6 +359,8 @@ VariationList<T>::VariationList()
|
||||
ADDPREPOSTREGVAR(Sphereblur)
|
||||
ADDPREPOSTREGVAR(Cpow3)
|
||||
ADDPREPOSTREGVAR(Concentric)
|
||||
ADDPREPOSTREGVAR(Hypercrop)
|
||||
ADDPREPOSTREGVAR(Hypershift2)
|
||||
//ADDPREPOSTREGVAR(LinearXZ)
|
||||
//ADDPREPOSTREGVAR(LinearYZ)
|
||||
//DC are special.
|
||||
|
@ -1487,12 +1487,6 @@ public:
|
||||
|
||||
PARVARCOPY(CrobVariation)
|
||||
|
||||
/// <summary>
|
||||
/// Functions the specified helper.
|
||||
/// </summary>
|
||||
/// <param name="helper">The helper.</param>
|
||||
/// <param name="outPoint">The out point.</param>
|
||||
/// <param name="rand">The rand.</param>
|
||||
virtual void Func(IteratorHelper<T>& helper, Point<T>& outPoint, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand) override
|
||||
{
|
||||
T gradTmp, secTmp, xTmp = 0, yTmp = 0;
|
||||
|
@ -2013,6 +2013,256 @@ private:
|
||||
T m_Zblur;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// hypercrop.
|
||||
/// </summary>
|
||||
template <typename T>
|
||||
class HypercropVariation : public ParametricVariation<T>
|
||||
{
|
||||
public:
|
||||
HypercropVariation(T weight = 1.0) : ParametricVariation<T>("hypercrop", eVariationId::VAR_HYPERCROP, weight, false, false, false, false, true)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
PARVARCOPY(HypercropVariation)
|
||||
|
||||
virtual void Func(IteratorHelper<T>& helper, Point<T>& outPoint, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand) override
|
||||
{
|
||||
T fx = helper.In.x;
|
||||
T fy = helper.In.y;
|
||||
T fz = helper.In.z;
|
||||
T a0 = T(M_PI) / m_N;
|
||||
T len = 1 / Zeps(std::cos(a0));
|
||||
T d = m_Rad * std::sin(a0) * len;
|
||||
T angle = Floor<T>(helper.m_PrecalcAtanyx * m_Coeff) / m_Coeff + T(M_PI) / m_N;
|
||||
T x0 = std::cos(angle) * len;
|
||||
T y0 = std::sin(angle) * len;
|
||||
|
||||
if (std::sqrt(Sqr(helper.In.x - x0) + Sqr(helper.In.y - y0)) < d)
|
||||
{
|
||||
if (m_Zero > 1.5)
|
||||
{
|
||||
fx = x0;
|
||||
fy = y0;
|
||||
fz = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_Zero > 0.5)
|
||||
{
|
||||
fx = 0;
|
||||
fy = 0;
|
||||
fz = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
T rangle = std::atan2(helper.In.y - y0, helper.In.x - x0);
|
||||
fx = x0 + std::cos(rangle) * d;
|
||||
fy = y0 + std::sin(rangle) * d;
|
||||
fz = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
helper.Out.x = fx * m_Weight;
|
||||
helper.Out.y = fy * m_Weight;
|
||||
helper.Out.z = fz * m_Weight;
|
||||
}
|
||||
|
||||
virtual string OpenCLString() const override
|
||||
{
|
||||
ostringstream ss, ss2;
|
||||
intmax_t i = 0, varIndex = IndexInXform();
|
||||
ss2 << "_" << XformIndexInEmber() << "]";
|
||||
string index = ss2.str();
|
||||
string weight = WeightDefineString();
|
||||
string n = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
string rad = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
string zero = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
string coeff = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
ss << "\t{\n"
|
||||
<< "\t\treal_t fx = vIn.x;\n"
|
||||
<< "\t\treal_t fy = vIn.y;\n"
|
||||
<< "\t\treal_t fz = vIn.z;\n"
|
||||
<< "\t\treal_t a0 = M_PI / " << n << ";\n"
|
||||
<< "\t\treal_t len = 1 / Zeps(cos(a0));\n"
|
||||
<< "\t\treal_t d = " << rad << " * sin(a0) * len;\n"
|
||||
<< "\t\treal_t angle = floor(precalcAtanyx * " << coeff << ") / " << coeff << " + M_PI / " << n << ";\n"
|
||||
<< "\t\treal_t x0 = cos(angle) * len;\n"
|
||||
<< "\t\treal_t y0 = sin(angle) * len;\n"
|
||||
<< "\n"
|
||||
<< "\t\tif (sqrt(Sqr(vIn.x - x0) + Sqr(vIn.y - y0)) < d)\n"
|
||||
<< "\t\t{\n"
|
||||
<< "\t\t if (" << zero << " > 1.5)\n"
|
||||
<< "\t\t {\n"
|
||||
<< "\t\t fx = x0;\n"
|
||||
<< "\t\t fy = y0;\n"
|
||||
<< "\t\t fz = 0;\n"
|
||||
<< "\t\t }\n"
|
||||
<< "\t\t else\n"
|
||||
<< "\t\t {\n"
|
||||
<< "\t\t if (" << zero << " > 0.5)\n"
|
||||
<< "\t\t {\n"
|
||||
<< "\t\t fx = 0;\n"
|
||||
<< "\t\t fy = 0;\n"
|
||||
<< "\t\t fz = 0;\n"
|
||||
<< "\t\t }\n"
|
||||
<< "\t\t else\n"
|
||||
<< "\t\t {\n"
|
||||
<< "\t\t real_t rangle = atan2(vIn.y - y0, vIn.x - x0);\n"
|
||||
<< "\t\t fx = x0 + cos(rangle) * d;\n"
|
||||
<< "\t\t fy = y0 + sin(rangle) * d;\n"
|
||||
<< "\t\t fz = 0;\n"
|
||||
<< "\t\t }\n"
|
||||
<< "\t\t }\n"
|
||||
<< "\t\t}\n"
|
||||
<< "\n"
|
||||
<< "\t\tvOut.x = fx * " << weight << ";\n"
|
||||
<< "\t\tvOut.y = fy * " << weight << ";\n"
|
||||
<< "\t\tvOut.z = fz * " << weight << ";\n"
|
||||
<< "\t}\n";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
virtual void Precalc() override
|
||||
{
|
||||
m_N = Zeps(m_N);
|
||||
m_Coeff = Zeps<T>(m_N * T(0.5) / T(M_PI));
|
||||
}
|
||||
|
||||
virtual vector<string> OpenCLGlobalFuncNames() const override
|
||||
{
|
||||
return vector<string> { "Zeps", "Sqr" };
|
||||
}
|
||||
|
||||
protected:
|
||||
void Init()
|
||||
{
|
||||
string prefix = Prefix();
|
||||
m_Params.clear();
|
||||
m_Params.push_back(ParamWithName<T>(&m_N, prefix + "hypercrop_n", 4));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Rad, prefix + "hypercrop_rad", 1));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Zero, prefix + "hypercrop_zero"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_Coeff, prefix + "hypercrop_coeff"));//Precalc.
|
||||
}
|
||||
|
||||
private:
|
||||
T m_N;
|
||||
T m_Rad;
|
||||
T m_Zero;
|
||||
T m_Coeff;//Precalc.
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// hypershift2.
|
||||
/// </summary>
|
||||
template <typename T>
|
||||
class Hypershift2Variation : public ParametricVariation<T>
|
||||
{
|
||||
public:
|
||||
Hypershift2Variation(T weight = 1.0) : ParametricVariation<T>("hypershift2", eVariationId::VAR_HYPERSHIFT2, weight)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
PARVARCOPY(Hypershift2Variation)
|
||||
|
||||
virtual void Func(IteratorHelper<T>& helper, Point<T>& outPoint, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand) override
|
||||
{
|
||||
T fx = helper.In.x * m_Scale2;
|
||||
T fy = helper.In.y * m_Scale2;
|
||||
T rad = 1 / Zeps(fx * fx + fy * fy);
|
||||
T x = rad * fx + m_Shift;
|
||||
T y = rad * fy;
|
||||
rad = m_Weight * m_Scale / Zeps(x * x + y * y);
|
||||
T angle = ((rand.Rand() % int(m_P)) * 2 + 1) * T(M_PI) / m_P;
|
||||
T X = rad * x + m_Shift;
|
||||
T Y = rad * y;
|
||||
T cosa = std::cos(angle);
|
||||
T sina = std::sin(angle);
|
||||
|
||||
if (m_VarType == eVariationType::VARTYPE_REG)
|
||||
outPoint.m_X = outPoint.m_Y = outPoint.m_Z = 0;//This variation assigns, instead of summing, so order will matter.
|
||||
|
||||
helper.Out.x = cosa * X - sina * Y;
|
||||
helper.Out.y = sina * X + cosa * Y;
|
||||
helper.Out.z = helper.In.z * rad;
|
||||
}
|
||||
|
||||
virtual string OpenCLString() const override
|
||||
{
|
||||
ostringstream ss, ss2;
|
||||
intmax_t i = 0, varIndex = IndexInXform();
|
||||
ss2 << "_" << XformIndexInEmber() << "]";
|
||||
string index = ss2.str();
|
||||
string weight = WeightDefineString();
|
||||
string p = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
string q = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
string shift = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
string scale = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
string scale2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
ss << "\t{\n"
|
||||
<< "\t\treal_t fx = vIn.x * " << scale2 << ";\n"
|
||||
<< "\t\treal_t fy = vIn.y * " << scale2 << ";\n"
|
||||
<< "\t\treal_t rad = 1 / Zeps(fx * fx + fy * fy);\n"
|
||||
<< "\t\treal_t x = rad * fx + " << shift << ";\n"
|
||||
<< "\t\treal_t y = rad * fy;\n"
|
||||
<< "\t\trad = " << weight << " * " << shift << " / Zeps(x * x + y * y);\n"
|
||||
<< "\t\treal_t angle = ((MwcNext(mwc) % (int)" << p << ") * 2 + 1) * M_PI / " << p << ";\n"
|
||||
<< "\t\treal_t X = rad * x + " << shift << ";\n"
|
||||
<< "\t\treal_t Y = rad * y;\n"
|
||||
<< "\t\treal_t cosa = cos(angle);\n"
|
||||
<< "\t\treal_t sina = sin(angle);\n";
|
||||
|
||||
if (m_VarType == eVariationType::VARTYPE_REG)
|
||||
ss << "\t\toutPoint->m_X = outPoint->m_Y = outPoint->m_Z = 0;\n";
|
||||
|
||||
ss << "\t\tvOut.x = cosa * X - sina * Y;\n"
|
||||
<< "\t\tvOut.y = sina * X + cosa * Y;\n"
|
||||
<< "\t\tvOut.z = vIn.z * rad;\n"
|
||||
<< "\t}\n";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
virtual void Precalc() override
|
||||
{
|
||||
T pq = T(M_PI) / m_Q;
|
||||
T pp = T(M_PI) / m_P;
|
||||
T spq = std::sin(pq);
|
||||
T spp = std::sin(pp);
|
||||
m_Shift = std::sin(T(M_PI) * T(0.5) - pq - pp);
|
||||
m_Shift = m_Shift / std::sqrt(1 - Sqr(spq) - Sqr(spp));
|
||||
m_Scale2 = 1 / std::sqrt(Sqr(sin(T(M_PI) / 2 + pp)) / Sqr(spq) - 1);
|
||||
m_Scale2 = m_Scale2 * (std::sin(T(M_PI) / 2 + pp) / spq - 1);
|
||||
m_Scale = 1 - m_Shift * m_Shift;
|
||||
}
|
||||
|
||||
virtual vector<string> OpenCLGlobalFuncNames() const override
|
||||
{
|
||||
return vector<string> { "Zeps" };
|
||||
}
|
||||
|
||||
protected:
|
||||
void Init()
|
||||
{
|
||||
string prefix = Prefix();
|
||||
m_Params.clear();
|
||||
m_Params.push_back(ParamWithName<T>(&m_P, prefix + "hypershift2_p", 3, eParamType::INTEGER_NONZERO));
|
||||
m_Params.push_back(ParamWithName<T>(&m_Q, prefix + "hypershift2_q", 7, eParamType::INTEGER_NONZERO));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_Shift, prefix + "hypershift2_shift"));//Precalc.
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_Scale, prefix + "hypershift2_scale"));
|
||||
m_Params.push_back(ParamWithName<T>(true, &m_Scale2, prefix + "hypershift2_scale2"));
|
||||
}
|
||||
|
||||
private:
|
||||
T m_P;
|
||||
T m_Q;
|
||||
T m_Shift;//Precalc.
|
||||
T m_Scale;
|
||||
T m_Scale2;
|
||||
};
|
||||
|
||||
MAKEPREPOSTPARVAR(Splits3D, splits3D, SPLITS3D)
|
||||
MAKEPREPOSTPARVAR(Waves2B, waves2b, WAVES2B)
|
||||
MAKEPREPOSTPARVAR(JacCn, jac_cn, JAC_CN)
|
||||
@ -2035,4 +2285,6 @@ MAKEPREPOSTPARVAR(Helix, helix, HELIX)
|
||||
MAKEPREPOSTPARVAR(Sphereblur, sphereblur, SPHEREBLUR)
|
||||
MAKEPREPOSTPARVAR(Cpow3, cpow3, CPOW3)
|
||||
MAKEPREPOSTPARVAR(Concentric, concentric, CONCENTRIC)
|
||||
MAKEPREPOSTPARVAR(Hypercrop, hypercrop, HYPERCROP)
|
||||
MAKEPREPOSTPARVAR(Hypershift2, hypershift2, HYPERSHIFT2)
|
||||
}
|
||||
|
Reference in New Issue
Block a user