Additional Blending Mode - Softlight (Pegtop-Delphi) ,Phoenix, Penumbra Blending Modes series, Negation, Signed Difference, and Interpolate
AbandonedPublic

Authored by rempt on Jun 20 2018, 4:11 AM.

Details

Reviewers
dkazakov
Reptorian
Group Reviewers
Krita
Summary

In this differentials, I have managed to create working blending modes, but they don't work 100% because Interpolate blending mode is another blending mode to be solved like Heat, and Freeze. Only this time, the issue is the reverse of them. In other words, Interpolate work just fine and dandy on float images, but they don't work on integer images, and it's easy to see why. cos(pi*1)=1, and cos(pi*0)=0.

The steps I did to create new blending mode

  • Study the blending modes using Pegtop-Delphi website
  • Categorize them carefully, and understand the blending modes.
  • When I look at the equation for the soft burn ,and soft dodge, I notice that they actually aren't burn and dodge because of their equation similarities. Because of their equation similarities, I have taken the liberty, and decided to call them Penumbra since they are the more appropriate name, and blend v. base shows a penumbra. Even with images, it's pretty clear that these blending modes all involves areas between light and darkness, and they even are better for painting shadows just due to their properties.
  • Then I start coding

For Softlight(Pegtop-Delphi), after many fails, I find the one in the code works pretty well and it actually compiles. A lot of the code involves the necessity of being able to compile, and other forms didn't work out for me. There might be normalization issues, but testing it, I see no difference. Even the Interpolate mode was made with compilation and end result in mind. The new negative modes are more for increasing compatibility with other applications in case the needs for those blending modes arise. The new softlight offers the benefit of preserving more details than other softlight, and therefore it increases usability of Krita.

Diff Detail

Repository
R37 Krita
Lint
Lint Skipped
Unit
Unit Tests Skipped
Reptorian created this revision.Jun 20 2018, 4:11 AM
Restricted Application added a reviewer: Krita. · View Herald TranscriptJun 20 2018, 4:11 AM
Reptorian requested review of this revision.Jun 20 2018, 4:11 AM
Reptorian added a comment.EditedJun 20 2018, 3:37 PM

I think I'll just leave this here :

template<class T>
inline T cfInterpolate(T src, T dst) {
    using namespace Arithmetic;
        typedef typename KoColorSpaceMathsTraits<T>::compositetype composite_type;
    
    composite_type unit = unitValue<T>();
    composite_type h = halfValue<T>();
    composite_type q = h/2;
    composite_type a = dst/unit;
    composite_type b = src/unit;
    composite_type x = pi*a;
    composite_type y = pi*b;

    return clamp<T>(h - q*cos(x) - q*cos(y));
}

That is an attempt, but the issue remains. It only works on float fine and dandy. In theory, this should have worked because x/unitvalue should be either x/255 or x/65535, and values shouldn't have anything to do with the end result. For some reason, it failed.


I also attempted to create 4 new quadratic blending modes. I do have a issue with those. They don't work despite all attempts to get conditions to read right. I copied and paste using HardMix. HardMix mode works, but not these one. I'll figure that out.

template<class T>
inline T cfGleat(T src, T dst) {
    using namespace Arithmetic;
    typedef typename KoColorSpaceMathsTraits<T>::compositetype composite_type;

    const composite_type sum = cfAllanon(src,dst);

    return sum < halfValue<T>() ? cfHeat(src,dst) : cfGlow(src,dst);
}

template<class T>
inline T cfReeze(T src, T dst) {
    using namespace Arithmetic;

    return (cfGleat(dst,src)); 
}

template<class T>
inline T cfHelow(T src, T dst) {
    using namespace Arithmetic;
    typedef typename KoColorSpaceMathsTraits<T>::compositetype composite_type;

    const composite_type sum = cfAllanon(src,dst);

    return sum < halfValue<T>() ? cfGlow(src,dst) : cfHeat(src,dst);
}

template<class T>
inline T cfFrect(T src, T dst) {
    using namespace Arithmetic;

    return (cfHelow(dst,src)); 
}
dkazakov requested changes to this revision.Jun 22 2018, 8:55 AM

Hi, @Reptorian!

Could you please make some painter-targeted explanation of what these modes do and how are they expected to work? We already have quite a lot of blending modes that painters don't understand how to use. Actually, 99% of the painters use 4-5 main blending modes and they don't care about the rest, unless there is a nice good manual/youtube-tutorial on how to use them in real painting pipeline.

Please make short chapters about each new blending mode, as if you were writing a manual for docs.krita.org. Then we will give this documentation and the patch to @Deevad, @timotheegiet and @woltherav so that they could evaluate how useful these modes would be in realworld pipeline.

PS:
Btw, please also do such documentation for Quadratic blending modes. @Deevad has tried them in master, and didn't find them too interesting/useful. He might lack some knowledge about them though...

This revision now requires changes to proceed.Jun 22 2018, 8:55 AM
Reptorian updated this revision to Diff 36539.EditedJun 22 2018, 11:13 PM

The changes I have made to this differentials is to add 4 new quadratic blending modes.


Lighten Blending Modes Group
Softlight (Pegtop-Delphi) : The new softlight mode is based off Pegtop-Delphi blending mode resource. It is a smoother varient of those two blending mode, and has less brightness overall, and without the disadvantage of those two blending modes.

Negative Blending Modes Group

Negation: Subtract the maximum value with two layers, and then apply result to be absolute.

Phoenix: Inverse of the difference between layers

Signed Difference: Subtract the difference between the two layers, and divide that by half. Then, add values by half of the maximum channel value.

Mix Blending Modes Group

Interpolate: Allanon Mode with more contrast with the usage of cosine function. Essentially, a better version of allanon mode for some applications. (Special note: This blending mode currently only works on float images.)

Penumbra A: Originally intended to be a softer version of soft dodge mode, the name was given because base v. blend modes follows the shape of a shadow, and most results falls under the shadow area. That means this mode is useful for painting shadows.

Penumbra B: See Penumbra A for description of what it is used for. The only difference is the two layers are swapped.

Quadratic Blending Modes Group

Note: All of those blending modes use quadratic equations. The square of the top layer divided by the inverse of the bottom layer is the base for all of those blending modes. Most quadratic blending modes do not currently work on float images properly because of negative values. Only Frect, Glow, Helow, and Reflect works properly on all color depth and color space.

Frect: The inverse of the intersection of Reflect, and Freeze mode. See Reflect, and Glow blending modes for potential use of Frect blending mode. The benefit over Reflect blending mode is Frect blending mode have more shadings than Reflect blending mode. Furthermore, this blending mode can be perceived as a smoother version of various light modes with a smooth discontinuity following quadratic forms.

Freeze: Blending of the two layers follows an upside-down curve where black is promiment. (Special note: This blending mode does not work properly on float images)

Gleat: The intersection of Heat, and Glow blending mode. What this results in a much softer version of Photoshop Hard Mix mode that follows quadratic forms. (Special note: This blending mode does not work properly on float images)

Glow:Blending of the two layers follows an upside-down curve where white is promiment. The best application of this blending mode is using it for creation of images where metallic reflections are used and when color adjustment are applied to two layers. This blending mode can also be used to be treated as another light modes with the purpose of darkening or lightening images in mind.

Heat: Blending of the two layers follows an upside-down curve where black is promiment. The formula is the same for freeze, but layers are swapped. (Special note: This blending mode does not work properly on float images, and isn't useful on 16-bit and higher)

Helow: The inverse of the intersection of Heat, and Glow mode. See Reflect, and Glow blending modes for potential use of Frect blending mode. The benefit over Glow blending mode is Helow blending mode have more shadings than Glow blending mode. Furthermore, this blending mode can be perceived as a smoother version of various light modes with a smooth discontinuity following quadratic forms.

Reeze: The intersection of Freeze, and Reflect blending mode. What this results in a much softer version of Photoshop Hard Mix mode that follows quadratic forms. (Special note: This blending mode does not work properly on float images)

Reflect: Blending of the two layers follows an upside-down curve where white is promiment. The best application of this blending mode is using it for creation of images where metallic reflections are used and when color adjustment are applied to two layers. This blending mode can also be used to be treated as another light modes with the purpose of darkening or lightening images in mind.


Another note -

Only Reflect, Glow, and Negation mode are the most used blending modes in all of those group. Negative Blending Modes won't be tested for painting as we all can agree every negative blending modes are rarely used and practical for painting. The other can be tested.

For quadratic mode, considering that they behave more like reflective objects since images goes right through destination layers, there should be a test involving this usage. One test of those blending modes involves testing them using groups where clones of painted layers are used above the target layer with color adjustment filters, and transparency masks in mind. It is also worth nothing that their name comes from how they seem to apply to images.


Here's a document showing different blending modes, and their purpose can be inferred.

I prefer not to try to compare these blending modes one-by-one unless there needs to be more explanations. Note that helow, and frect are similar to other lighten modes without the abrupt changes of flow. They are somewhat similar to the blending modes with more adrupt changes of flow. Like a combined version of various lighten modes, but smoothed. Also, you can tell glow, and reflect might be useful if Color Dodge or Screen is useful for you.

And then, if you look at penumbra blending modes, note that they are pretty smooth, and the result of blending modes seem to show that end result will follow into the penumbra form.

And there's a source here which documents blending modes to a extent -

http://myplace.frontier.com/~chooks9592/manual/html/imblend.html


Findings on Blending Modes

I am finding that frect is like hard overlay mode, but without the downside of colors over 1, and frect is the smoothest blend mode in comparison to blending modes similar to frect.

Helow behaves more like overlay with burn and dodge applied to it. Lighter area on source layer are less affected. Darker source layer areas will be shown to be more affected. The burn here is a lot more subtle than the current color burn.

`For other blend modes continued findings
`
Penumbra series behaves like nothing that exists. They can be similar to some results, but they don't behave like anything else that exists. I have tested many blending modes, and not even close. They're quite more interesting the more one would experiment with.


Even more findings** -

Difference between blending modes are clearer on 16-bit integer. Besides linear dodge, and color dodge. Penumbra mode is the best way to mix images. Overlay is not even viable in certain scenario. With the help of linear dodge to avoid the darkening, the result with helow or frect are much better than overlay (wouldn't help with linear dodge in some cases).

Right now, I'm testing with photographs, and those are what I'm noticing. I wish I can paint to test their viability on painting, but problem is I'm using a linux VM and it's too slow for testing that.

These blending modes I said don't work for 16-bit actually works for them in 16-bit integer. It just that you have to use linear dodge layer to brighten up result.

Reptorian updated this revision to Diff 36586.EditedJun 24 2018, 1:26 AM

I fixed some of the ZX spectrum bug issues. You can apply a slight color adjustment (one value less) on the top part curve on the source layer to eliminate the bug still in Helow. It's not that prominent as color dodge or parallel blending mode, but it can be fixed. Gleat and Heat can't really be saved from those ZX spectrum bug as the bug is very prominent in those. Even with dst ==unit ; return 0, the bug will just show up there.

Reptorian updated this revision to Diff 36589.EditedJun 24 2018, 4:29 AM

Even further fixes to ZX Spectrum bugs. Now, if I can use minimal channel value after zero, that'd be great to avoid division by 0 and being able to avoid color bleeds.

Reptorian updated this revision to Diff 36590.Jun 24 2018, 4:40 AM

Forgot to upload previous file. Here's the actual fix for ZX spectrum. Comment about unable to avoid using if unit then unit, and can't avoid that to avoid div/0 applies here.

Hi, @Reptorian!

I have pushed your patch into a separate branch reptorian/blending-modes, so that the painters could to test it. Please ping @woltherav, @Deevad, @timotheegiet and @scottpetrovic on IRC and point them to your docs, so that they could comment the blending modes here :)

Thank you Reptorian for the new composite ops.
I'll review this week the reptorian/blending-modes branch and comment about the new effects.

Reptorian added a comment.EditedJun 25 2018, 5:55 PM

I did found a solution to the issue of ZX Spectrum by forcing the src and dst to go under unitValue and over zeroValue with the usage of halfvalue, and putting halfvalue over src and dst. HalfValue opacity is set to 1%. This one is based off the quadratic patch before this one, and not this patch. Blending mode is glow in the picture.

is the solution to ZX Spectrum bugs seen in quadratic blend modes. So duplicating dst, and src folder with the content inside those folder where dst used glow blending mode on cfGlow should solve the ZX Spectrum bugs. Tested, there is no ZX Spectrum bug ever no matter what I do. Orders are irrelevant. So, if those quadratic blend modes are acceptable for use, then I believe we can work toward that solution.

Reptorian added a comment.EditedJun 25 2018, 11:31 PM

The solution probably exists within KoColorSpaceMaths.h and the use of elipson which is basically the closest to 0, and eliminating the unitvalue in src is the way most, if not all ZX Spectrum related bugs in color dodge, parallel, and these modes I made would be solved.


I added elipson to the KoColorSpaceMaths.h to resolve this issue.
Ok, I'm one step to the solution. I can't get around this

error: operands to ?: have different types ‘composite_type {aka double}’ and ‘half’

composite_type g = src == unit ? ueps : src;

? is where it's pointing to the error.


Got around it, but however, this doesn't seem to force src_unitvalue to become 254.

template<class T>
inline T cfGlow(T src, T dst) {
    using namespace Arithmetic;
        typedef typename KoColorSpaceMathsTraits<T>::compositetype composite_type;

    composite_type w = src;
    composite_type eps = epsilon<T>();
    composite_type p = unitValue<T>() - epsilon<T>();
    composite_type g = src == unitValue<T>() ? p : w;
    composite_type z = src == zeroValue<T>() ? eps : g;
    composite_type m = z*z;
    composite_type n = inv(dst);
    composite_type o = m/n;

    if(dst == unitValue<T>()) {
    return unitValue<T>();
    }

    return clamp<T>(o);
}

If I'm reading this right. Let's try this.

  • eps = 1
  • p = 255- eps
  • g = src == 255 ? p : src
  • src = 255
  • g = 255 == 255 ? 254 : src
  • g = 255 == 255 is TRUE
  • g = 254
  • z = 255 == zeroValue<T>() ? eps : g;
  • eps = 1
  • z = 255 == 0 is FALSE
  • z = g = 254

So therefore, it should be 254 used. If it worked, then this bug would been resolved.


Apparently, I tested unitValue<T>()-epsilon<T>()+src*0+dst*0 in another blending mode to verify that it does indeed become 254, and it does indeed become 254, but however for some reason, the glow blending modes still reads it as 255. I believe now it is confirmed that there is a bug embedded into KoColorSpaceMaths.h or something.

Also, tried cfQuad1 where I put if src==unitValue<T>(), then unitValue<T>()-epsilon<T>() and result dst*0+src. After that put cfQuad1 to replace src in result of Glow. cfQuad1 did indeed replaced 255 with 254. It didn't work. So, that's my final attempt in fixing the bug. It won't work.

Reptorian added a comment.EditedJun 30 2018, 12:21 AM

It turns out I was getting dst, and src mixed up all along. Sorry about that. I think I can continue with the solution. dst is the below layer, and src is the top layer. That doesn't affect many of the blending modes I made. They work as expected.


Ladies, and gentlemen, I am almost close to solving the bug! Now, I have a new theory on solving the bug. I tested inv of src, and dst of paint.net blend mode images to verify the ugly zx colors are gone.

I learned even if you attempted to eliminate unitvalue<T>() on dst, you do get a pretty ugly splash of colors for all area where src = 0. The new solution I have requires float numbers, so therefore I cannot solve it now. Same issue with interpolate. My new theory involves changing_zero src into something like .5, and unitvalue becomes something on the line of 254.5. This should fix the issues.

The main gist is that if float numbers are able to be used on integer images, interpolate would be fixed. I'm not sure if quad blending modes, parallel, and color dodge would be solved right there because epsilon are the lowest you can go with float images, and I believe those values I am making up would just get truncated. What can be done about that?


Actually thought of a theoretical solution involving multiplying src and dst twice so to avoid needing float value. All while avoiding problem numbers.

New formula for glow blending mode.

((2a*2a)/4)/2-2b

where 2a ranges from epsilon to 2*unitvalue and 2b is 0 to 2 times unitvalue subtracted by epsilon. This means it is possible.

The new formula simplifies to a^2/1-b.

I'll do excel test, and if all goes well, the new formula will be used.

rempt added a subscriber: rempt.Jun 30 2018, 8:15 AM

Could you give us a ping when you've posted that fix? I'll check the patch again then.

Reptorian added a comment.EditedJun 30 2018, 6:58 PM

Could you give us a ping when you've posted that fix? I'll check the patch again then.

I don't think there can be a fix to those color splotches when testing with paint.net images, but I find that other blending modes aren't free from those issues. Even with other softwares, I noticed they aren't free from those issues.

I concluded I did everything right from the beginning, and my issue with perfectionism lead me with so much delay. If Photoshop has those issues, then I'm guessing there can be no fixes to certain blend modes under certain circumstances.

The workaround I can see to those issues is to add turn zero to epsilon adjustment mask, and unitvalue to unitvalue - epsilon adjustment mask. For those that use brushes blending mode, I imagine a toggle somewhere would resolve those issues. It's not perfect, but it's the only way.

Reptorian added a comment.EditedJul 9 2018, 9:24 PM

Any reviews yet on those blend modes?

I'm attaching this because I can't get git diff for some reason, and as I have no answer as how to fix that, I'm leaving this .h file here. Here's the fixed version, and there aren't any bugs in here. You get what you expect. I tested with several images, and there does not seem to be any issues.

Update: The updated patch has been pushed into the branch by Dmitry.

rempt commandeered this revision.Aug 20 2018, 8:13 AM
rempt added a reviewer: Reptorian.

If it's pushed, please close the revision.

There are two different branch, the branch I'm referring to is reptorian/blend-modes branch. But, yes this can be closed as there is a new differential group.

Reptorian added a comment.EditedAug 29 2018, 11:41 AM

Here's a paste to fix the current reptorian-blending modes branch - https://phabricator.kde.org/P257

  • Changes : Removed duplicate lines, and fixed Penumbra C by fixing Penumbra D. If this was applied to the reptorian blending modes branch, then it is completely ready to test as all issues has been addressed. Now, while I would like to add Autodesk Sketch blending mode and it's possible to recreate Autodesk Sketch Glow/Color Dodge blending mode using 5 different layers with specific blending modes assigned to those layers with the reptorian-blending modes patch mixed with the paste, there isn't a official formula for their special mode (different than every other softwares in formula), so I would not add that mode, so therefore, I have nothing to add or delete after the paste has been applied.

To test that it works, here's a testing file -

  • Color Dodge and Parallel has been changed though at some point in reptorian-blending modes! Color Dodge has been fixed. Parallel is currently buggy when src or dst is at zeroValue, and this patch fixed that, but at the same time, some people use current Krita Parallel because of that behavior. Either there needs to be 2 different varients of Parallel, or the new Parallel is applied seeing as it's less buggy.

Here's the final revision of the patch - https://phabricator.kde.org/D15584

I will definitely document new modes soon.

Some things of note - There are some new modes that are functionally better on linear color space like SuperLight and Flatlight. Logarithmic burn is very smooth for a darkening mode. Modulo are similar to binary in usage except that Modulo can give smoother result, and can be used to manipulate gradients without the need to resort to gmic or adding new filter.

Okay, I added more to that differential, and going to say that I'm done here as there's nothing left except documentation for the new ones I added.

- Documentation to the Blending Mode released.

Also, I made some error to Modulo Shift modes. So, fixed in that differential link.

This needs to be closed.

rempt abandoned this revision.Feb 11 2019, 8:53 AM