From 748a28bb5a9b4905165aee4df2cb9df9c3e385cb Mon Sep 17 00:00:00 2001 From: shun-iwasawa Date: Aug 09 2022 03:56:34 +0000 Subject: sampling size for gradient warp iwa fx --- diff --git a/stuff/config/current.txt b/stuff/config/current.txt index 7855ea9..a630fd0 100644 --- a/stuff/config/current.txt +++ b/stuff/config/current.txt @@ -1205,6 +1205,7 @@ "STD_iwa_GradientWarpFx.h_maxlen" "H Length" "STD_iwa_GradientWarpFx.v_maxlen" "V Length" "STD_iwa_GradientWarpFx.scale" "Scale" + "STD_iwa_GradientWarpFx.sampling_size" "Sampling Size" "STD_iwa_MotionBlurCompFx" "Motion Blur Iwa" "STD_iwa_MotionBlurCompFx.hardness" "Hardness" diff --git a/stuff/profiles/layouts/fxs/STD_iwa_GradientWarpFx.xml b/stuff/profiles/layouts/fxs/STD_iwa_GradientWarpFx.xml index 629917a..19dadb7 100644 --- a/stuff/profiles/layouts/fxs/STD_iwa_GradientWarpFx.xml +++ b/stuff/profiles/layouts/fxs/STD_iwa_GradientWarpFx.xml @@ -3,5 +3,6 @@ h_maxlen v_maxlen scale + sampling_size diff --git a/toonz/sources/stdfx/iwa_gradientwarpfx.cpp b/toonz/sources/stdfx/iwa_gradientwarpfx.cpp index b387945..ee63dac 100644 --- a/toonz/sources/stdfx/iwa_gradientwarpfx.cpp +++ b/toonz/sources/stdfx/iwa_gradientwarpfx.cpp @@ -80,19 +80,33 @@ void Iwa_GradientWarpFx::setOutputRaster(float4 *srcMem, const RASTER dstRas, //------------------------------------ Iwa_GradientWarpFx::Iwa_GradientWarpFx() - : m_h_maxlen(0.0), m_v_maxlen(0.0), m_scale(1.0) { + : m_h_maxlen(0.0), m_v_maxlen(0.0), m_scale(1.0), m_sampling_size(1.0) { /*- 共通パラメータのバインド -*/ addInputPort("Source", m_source); addInputPort("Warper", m_warper); bindParam(this, "h_maxlen", m_h_maxlen); bindParam(this, "v_maxlen", m_v_maxlen); bindParam(this, "scale", m_scale); + bindParam(this, "sampling_size", m_sampling_size); m_h_maxlen->setMeasureName("fxLength"); m_v_maxlen->setMeasureName("fxLength"); m_h_maxlen->setValueRange(-100.0, 100.0); m_v_maxlen->setValueRange(-100.0, 100.0); m_scale->setValueRange(1.0, 100.0); + m_sampling_size->setMeasureName("fxLength"); + m_sampling_size->setValueRange(0.1, 20.0); + + // Version 1: sampling distance had been always 1 pixel. + // Version 2: sampling distance can be specified with the parameter. + // this must be called after binding the parameters (see onFxVersionSet()) + setFxVersion(2); +} + +//-------------------------------------------- + +void Iwa_GradientWarpFx::onFxVersionSet() { + getParams()->getParamVar("sampling_size")->setIsHidden(getFxVersion() == 1); } //------------------------------------ @@ -119,14 +133,20 @@ void Iwa_GradientWarpFx::doCompute(TTile &tile, double frame, double scale = m_scale->getValue(frame); + double sampling_size = m_sampling_size->getValue(frame); + double grad_factor = 1. / sampling_size; + sampling_size *= k; + /*- ワープ距離が0なら、ソース画像をそのまま返す -*/ if (hLength == 0.0 && vLength == 0.0) { m_source->compute(tile, frame, settings); return; } - int margin = static_cast( - ceil((std::abs(hLength) < std::abs(vLength)) ? std::abs(vLength) : std::abs(hLength))); + int margin = static_cast(ceil((std::abs(hLength) < std::abs(vLength)) + ? std::abs(vLength) + : std::abs(hLength))); + margin = std::max(margin, static_cast(std::ceil(sampling_size)) + 1); /*- 素材計算範囲を計算 -*/ /*- 出力範囲 -*/ @@ -190,7 +210,8 @@ void Iwa_GradientWarpFx::doCompute(TTile &tile, double frame, result_host_ras->lock(); result_host = (float4 *)result_host_ras->getRawData(); doCompute_CPU(tile, frame, settings, hLength, vLength, margin, enlargedDim, - source_host, warper_host, result_host); + source_host, warper_host, result_host, sampling_size, + grad_factor); /*- ポインタ入れ替え -*/ source_host = result_host; @@ -218,25 +239,52 @@ void Iwa_GradientWarpFx::doCompute(TTile &tile, double frame, Fx計算 ------------------------------------*/ -void Iwa_GradientWarpFx::doCompute_CPU(TTile &tile, const double frame, - const TRenderSettings &settings, - double hLength, double vLength, - int margin, TDimensionI &enlargedDim, - float4 *source_host, float *warper_host, - float4 *result_host) { +void Iwa_GradientWarpFx::doCompute_CPU( + TTile &tile, const double frame, const TRenderSettings &settings, + double hLength, double vLength, int margin, TDimensionI &enlargedDim, + float4 *source_host, float *warper_host, float4 *result_host, + double sampling_size, double grad_factor) { + auto lerp = [](float val0, float val1, double ratio) -> float { + return val0 * (1.f - ratio) + val1 * ratio; + }; + float4 *res_p = result_host + margin * enlargedDim.lx + margin; - float *warp_up = warper_host + (margin + 1) * enlargedDim.lx + margin; - float *warp_down = warper_host + (margin - 1) * enlargedDim.lx + margin; - float *warp_right = warper_host + margin * enlargedDim.lx + 1 + margin; - float *warp_left = warper_host + margin * enlargedDim.lx - 1 + margin; + if (getFxVersion() == 1) { + sampling_size = 1.0; + grad_factor = 1.0; + } + int size_i = static_cast(std::floor(sampling_size)); + double ratio = sampling_size - (double)size_i; + + float *warp_up_0 = warper_host + (margin + size_i) * enlargedDim.lx + margin; + float *warp_up_1 = + warper_host + (margin + size_i + 1) * enlargedDim.lx + margin; + + float *warp_down_0 = + warper_host + (margin - size_i) * enlargedDim.lx + margin; + float *warp_down_1 = + warper_host + (margin - size_i - 1) * enlargedDim.lx + margin; + + float *warp_right_0 = warper_host + margin * enlargedDim.lx + size_i + margin; + float *warp_right_1 = + warper_host + margin * enlargedDim.lx + size_i + 1 + margin; + + float *warp_left_0 = warper_host + margin * enlargedDim.lx - size_i + margin; + float *warp_left_1 = + warper_host + margin * enlargedDim.lx - size_i - 1 + margin; for (int j = margin; j < enlargedDim.ly - margin; j++) { - for (int i = margin; i < enlargedDim.lx - margin; - i++, res_p++, warp_up++, warp_down++, warp_right++, warp_left++) { + for (int i = margin; i < enlargedDim.lx - margin; i++, res_p++, warp_up_0++, + warp_up_1++, warp_down_0++, warp_down_1++, warp_right_0++, + warp_right_1++, warp_left_0++, warp_left_1++) { /*- 勾配を得る -*/ - float2 grad = {static_cast((*warp_right) - (*warp_left)), - static_cast((*warp_up) - (*warp_down))}; + float2 grad = { + lerp(*warp_right_0 - *warp_left_0, *warp_right_1 - *warp_left_1, + ratio), + lerp(*warp_up_0 - *warp_down_0, *warp_up_1 - *warp_down_1, ratio)}; + grad.x *= grad_factor; + grad.y *= grad_factor; /*- 参照点 -*/ float2 samplePos = {static_cast(i + grad.x * hLength), static_cast(j + grad.y * vLength)}; @@ -260,10 +308,14 @@ void Iwa_GradientWarpFx::doCompute_CPU(TTile &tile, const double frame, } res_p += 2 * margin; - warp_up += 2 * margin; - warp_down += 2 * margin; - warp_right += 2 * margin; - warp_left += 2 * margin; + warp_up_0 += 2 * margin; + warp_up_1 += 2 * margin; + warp_down_0 += 2 * margin; + warp_down_1 += 2 * margin; + warp_right_0 += 2 * margin; + warp_right_1 += 2 * margin; + warp_left_0 += 2 * margin; + warp_left_1 += 2 * margin; } } diff --git a/toonz/sources/stdfx/iwa_gradientwarpfx.h b/toonz/sources/stdfx/iwa_gradientwarpfx.h index 6629390..cd9b756 100644 --- a/toonz/sources/stdfx/iwa_gradientwarpfx.h +++ b/toonz/sources/stdfx/iwa_gradientwarpfx.h @@ -33,6 +33,7 @@ protected: TDoubleParamP m_scale; /*- ワープ量を増やすスカラー値。この値はマージン値には影響しない -*/ + TDoubleParamP m_sampling_size; void get_render_real_hv(const double frame, const TAffine affine, double &h_maxlen, double &v_maxlen); @@ -57,7 +58,8 @@ protected: const TRenderSettings &settings, double hLength, double vLength, int margin, TDimensionI &enlargedDim, float4 *source_host, float *warper_host, - float4 *result_host); + float4 *result_host, double sampling_size, + double grad_factor); float4 getSourceVal_CPU(float4 *source_host, TDimensionI &enlargedDim, int pos_x, int pos_y); @@ -74,6 +76,8 @@ public: const TRenderSettings &info) override; bool canHandle(const TRenderSettings &info, double frame) override; + + void onFxVersionSet() final override; }; #endif \ No newline at end of file