Skip to content

Add Photoshop-like brush texturing modes

Deif Lou requested to merge deiflou/krita:deiflou/ps_brush_texture_modes into master

This MR adds new texture blend modes for the brushes. They are not new modes per se, but new ways of applying the strength option to the current ones, similar to how Photoshop does it. Technical information can be found in this task I made when I added the current modes:

When I added the current modes, I made the linked task explaining 2 possible ways of applying the texture. One made it look like Photoshop. That is, depending on the strength value, the final dabs would look more like the un-textured dabs or more like the fully textured dabs (which depend on the actual blend mode being used). This mostly would look like some interpolation between the two states (textured and un-textured).The other option was making the blend modes use the strength in a way that was more similar to how the already present multiply and subtract modes used it. That is, the texture is applied the same at all strength values but the dabs kind of fade away with low strength values. It is worth noting that Photoshop already mixes the two approaches: it uses the first approach for all its blend modes except for "height" and "linear height", for which it uses the second approach. So, after some feedback in KA, the second approach was implemented by popular demand. It seems it gives the more desirable results, at least for Krita users. And that's what was implemented.

Now, the first approach has its use case. The primary one is compatibility with Photoshop brushes. And after two years I noticed some interest on having that kind of texturing, mainly because of that. People like Ramon feel that it is beneficial being able to map Photoshop texturing to Krita. Furthermore I heard this past week that someone has fully "cracked" the abr format and wants to write some tool or something to be able to port Photoshop brushes in the most straightforward manner. That has the potential to benefit a large amount of users and is a good selling point. But for that to be really useful, Krita has to be able to reproduce PS... So that's the main reason I implemented this.

What I did was, instead of adding more blend modes entries to the combo box, I just added a new option in the form of a combo box named "soft texturing" with tooltip "Apply less texture when the strength is lower. Use this option if you want the brush to transition between un-textured and textured". That's the more straightforward way that came to my mind, user wise. The default applies the texture as of now. But if you check that option then the effect is as if the texturing is less applied where there is low strength (showing there the dabs "more un-textured"). The users should think of that not as different modes but as the same texturing mode with that "fade off" to the original un-textured look. I think that's a good compromise between being consistent in Krita-land while providing the PS functionality.

Some of the new formulas may seem a bit odd. I tried to replicate PS as close as possible while adding the less complexity possible. Overall I think there should be no issues performance wise since the operations in the new modes are comparable to those in the old ones.

Still, there are some quirks. Photoshop brush texturing is more limited than Krita's one. It has a list of blend modes but the "height" and "linear height" behave differently from the others. And not only regarding to how they react to the "depth" option, but also to how the pen pressure is mapped to that "depth" option. As I said earlier, for all modes but "height" and "linear height", the depth controls how much the texturing applies, with depth=0% looking as the un-textured dabs and depth=100% looking as fully textured (the blend mode has full effect). For "height" and "linear height", the texture is applied the same for all depth values, but depth=0% means that the dabs "fade away", kind of disappear, and depth=100% means the same full texturing effect as in the other modes, similar to the classic "multiply" and "subtract" in Krita (and all the other current modes, modeled after those). [The quick technical explanation is that in the Krita way and PS "height" and "linear height" the strength/depth influences the dab values (that's what produces the "fade off" effect with low strength values), and in the PS way the depth modifies the texture values]. The other issue is that the pen pressure is mapped differently for "height" and "linear height" and the other modes. For "height" and "linear height" 0% pressure is mapped to 0% depth and 100% pressure to 100% depth. That seems reasonable and it is how Krita also works. But for the other modes 0% pressure is mapped to 100% depth and 100% pressure to 0% depth... The only reason I can think for that is: they don't have mapping curves to allow custom mappings so they had to make an, to me, arbitrary decision, maybe based on the resulting look, so they choose that mapping thinking "the more depth the more coverage" (remember that those modes go from un-textured to textured look, and the un-textured look usually looks as it covered more area). Or they have some mental model where the texture is like a height map whose valleys are to be filled by the dab, so the depth controls how filled those appear. That would explain why the high pressure is mapped to low depth values, which are mapped to low texturing (the un-textured dabs would look as if they cover more areas in principle). A mess if you ask me.

My goal here was being consistent and general. So for the new modes I applied the strength in a way that less strength means less texturing (the dabs look more like the un-textured ones), and more strength means more texturing visible. this maps well to the depth of PS but the pressure curves will have to be reversed [f(0) = 1 and f(1) = 0] to make it behave as in PS. But that's not a problem in Krita due its versatility in that regard. This seems to me way more straightforward, specially user wise.

Overall, I think this is a good compromise between number of user-facing changes (just a new toggle option) and functionality.

A video showcasing the feature:

Formalities Checklist

  • I confirmed this builds.
  • I confirmed Krita ran and the relevant functions work.
  • I tested the relevant unit tests and can confirm they are not broken. (If not possible, don't hesitate to ask for help!)
  • I made sure my commits build individually and have good descriptions as per KDE guidelines.
  • I made sure my code conforms to the standards set in the HACKING file.
  • I can confirm the code is licensed and attributed appropriately, and that unattributed code is mine, as per KDE Licensing Policy.

Reminder: the reviewer is responsible for merging the patch, this is to ensure at the least two people can build the patch. In case a patch breaks the build, both the author and the reviewer should be contacted to fix the build. If this is not possible, the commits shall be reverted, and a notification with the reasoning and any relevant logs shall be sent to the mailing list,

Edited by Deif Lou

Merge request reports