Commit d4a0c1f9 authored by William Brown's avatar William Brown Committed by Dmitry Kazakov

Flow Update

Summary: Update Alpha Darken Composite Operation to use flow more reasonably

Forum thread: https://forum.kde.org/viewtopic.php?f=288&t=136165&sid=b0322cc336861566b625af479805062b

Reviewers: #krita, dkazakov!
Subscribers: rempt, woltherav, dkazakov, kamathraghavendra, Deevad, ramonmiranda, wbrown
Tags: #krita
Maniphest Tasks: T8576
Differential Revision: https://phabricator.kde.org/D18467
parent 117c1222
......@@ -57,7 +57,7 @@ public:
qint32 srcInc = (params.srcRowStride == 0) ? 0 : channels_nb;
channels_type flow = scale<channels_type>(params.flow);
channels_type opacity = mul(flow, scale<channels_type>(params.opacity));
channels_type opacity = scale<channels_type>(params.opacity);
quint8* dstRowStart = params.dstRowStart;
const quint8* srcRowStart = params.srcRowStart;
const quint8* maskRowStart = params.maskRowStart;
......@@ -89,7 +89,7 @@ public:
if(alpha_pos != -1) {
channels_type fullFlowAlpha;
channels_type averageOpacity = mul(flow, scale<channels_type>(*params.lastOpacity));
channels_type averageOpacity = scale<channels_type>(*params.lastOpacity);
if (averageOpacity > opacity) {
channels_type reverseBlend = KoColorSpaceMaths<channels_type>::divide(dstAlpha, averageOpacity);
......@@ -101,8 +101,10 @@ public:
if (params.flow == 1.0) {
dstAlpha = fullFlowAlpha;
} else {
channels_type zeroFlowAlpha = unionShapeOpacity(srcAlpha, dstAlpha);
channels_type zeroFlowAlpha = dstAlpha;
dstAlpha = lerp(zeroFlowAlpha, fullFlowAlpha, flow);
}
dst[alpha_pos] = dstAlpha;
......
......@@ -29,13 +29,11 @@ struct AlphaDarkenCompositor128 {
struct OptionalParams {
OptionalParams(const KoCompositeOp::ParameterInfo& params)
: flow(params.flow)
, averageOpacity(*params.lastOpacity * params.flow)
, premultipliedOpacity(params.opacity * params.flow)
, averageOpacity(*params.lastOpacity)
{
}
float flow;
float averageOpacity;
float premultipliedOpacity;
};
struct Pixel {
......@@ -83,12 +81,7 @@ struct AlphaDarkenCompositor128 {
msk_norm_alpha = src_alpha;
}
// we don't use directly passed value
Q_UNUSED(opacity);
// instead we should use opacity premultiplied by flow
opacity = oparams.premultipliedOpacity;
Vc::float_v opacity_vec(oparams.premultipliedOpacity);
Vc::float_v opacity_vec(opacity);
src_alpha = msk_norm_alpha * opacity_vec;
......@@ -142,7 +135,7 @@ struct AlphaDarkenCompositor128 {
dst_alpha = fullFlowAlpha;
}
else {
Vc::float_v zeroFlowAlpha = src_alpha + dst_alpha - src_alpha * dst_alpha;
Vc::float_v zeroFlowAlpha = dst_alpha;
Vc::float_v flow_norm_vec(oparams.flow);
dst_alpha = (fullFlowAlpha - zeroFlowAlpha) * flow_norm_vec + zeroFlowAlpha;
}
......@@ -166,9 +159,6 @@ struct AlphaDarkenCompositor128 {
const float uint8Rec1 = 1.0 / 255.0;
float mskAlphaNorm = haveMask ? float(*mask) * uint8Rec1 * src[alpha_pos] : src[alpha_pos];
Q_UNUSED(opacity);
opacity = oparams.premultipliedOpacity;
float srcAlphaNorm = mskAlphaNorm * opacity;
if (dstAlphaNorm != 0) {
......@@ -195,7 +185,7 @@ struct AlphaDarkenCompositor128 {
if (flow == 1.0) {
dst[alpha_pos] = fullFlowAlpha;
} else {
float zeroFlowAlpha = unionShapeOpacity(srcAlphaNorm, dstAlphaNorm);
float zeroFlowAlpha = dstAlphaNorm;
dst[alpha_pos] = lerp(zeroFlowAlpha, fullFlowAlpha, flow);
}
}
......
......@@ -31,13 +31,11 @@ struct AlphaDarkenCompositor32 {
struct OptionalParams {
OptionalParams(const KoCompositeOp::ParameterInfo& params)
: flow(params.flow),
averageOpacity(*params.lastOpacity * params.flow),
premultipliedOpacity(params.opacity * params.flow)
averageOpacity(*params.lastOpacity)
{
}
float flow;
float averageOpacity;
float premultipliedOpacity;
};
/**
......@@ -59,12 +57,7 @@ struct AlphaDarkenCompositor32 {
Vc::float_v src_alpha;
Vc::float_v dst_alpha;
// we don't use directly passed value
Q_UNUSED(opacity);
// instead we should use opacity premultiplied by flow
opacity = oparams.premultipliedOpacity;
Vc::float_v opacity_vec(255.0 * oparams.premultipliedOpacity);
Vc::float_v opacity_vec(255.0 * opacity);
Vc::float_v average_opacity_vec(255.0 * oparams.averageOpacity);
Vc::float_v flow_norm_vec(oparams.flow);
......@@ -170,8 +163,7 @@ struct AlphaDarkenCompositor32 {
if (oparams.flow == 1.0) {
dst_alpha = fullFlowAlpha;
} else {
Vc::float_v zeroFlowAlpha = src_alpha + dst_alpha -
dst_blend * dst_alpha;
Vc::float_v zeroFlowAlpha = dst_alpha;
dst_alpha = (fullFlowAlpha - zeroFlowAlpha) * flow_norm_vec + zeroFlowAlpha;
}
......@@ -196,9 +188,6 @@ struct AlphaDarkenCompositor32 {
float srcAlphaNorm;
float mskAlphaNorm;
Q_UNUSED(opacity);
opacity = oparams.premultipliedOpacity;
if (haveMask) {
mskAlphaNorm = float(*mask) * uint8Rec2 * src[alpha_pos];
srcAlphaNorm = mskAlphaNorm * opacity;
......@@ -234,7 +223,7 @@ struct AlphaDarkenCompositor32 {
if (flow == 1.0) {
dstAlpha = fullFlowAlpha * uint8Max;
} else {
float zeroFlowAlpha = unionShapeOpacity(srcAlphaNorm, dstAlphaNorm);
float zeroFlowAlpha = dstAlphaNorm;
dstAlpha = lerp(zeroFlowAlpha, fullFlowAlpha, flow) * uint8Max;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment