White outline around alpha in texture paint (when using multiple layers) #69106

Closed
opened 2019-08-24 00:21:24 +02:00 by Syntex · 26 comments

System Information
Operating system: Windows-10-10.0.17134 64 Bits
Graphics card: GeForce GTX 1080/PCIe/SSE2 NVIDIA Corporation 4.5.0 NVIDIA 417.22

Blender Version
Broken: version: 2.81 (sub 3), branch: master, commit date: 2019-08-22 20:40, hash: 1de7717ed7 and 2.8 release
Worked: Never. As far as I can remember this has always been an issue.

Short description of error
When painting with multiple layers in texture paint mode, there is a white outline around the alpha channel. (You have to be in material view to see the 2 layers at the same time)
The first layer is just a solid red color & the second layer's alpha is set to 0 and then I painted on the layer with green color.
The layers are mixed together using the MixRGB node with the second layer's alpha set as the mix factor.
IMPORTANT: the brush falloff needs to be set to the last preset or the issue is not as visible because the change in alpha value is smoother
falloff.PNG
Texture paint layers white outline.PNG
The white outline is not visible if I render the scene in cycles, which makes me think that this is a bug. If it's not a bug, it's most likely a limitation of the "Mix" blend mode.
Rendered view with cycles.PNG

This issue makes the texture paint mode unusable for any serious work that needs more than 1 layer.

Exact steps for others to reproduce the error
Unwrap the default cube U> smart UV project, switch to texture paint workspace, add a base color texture & a second base color texture with alpha set to 0,
switch to material view, go to the shader editor & Mix the 2 base color textures together using the MixRGB node.
The first base color texture goes to the "Color1" input & the second base color texture with alpha goes to the "Color2" input.
Connect the alpha output of the second base color texture to the MixRGB node's alpha input. Then paint on the second base color layer with a hard edged brush (last falloff preset) and you get white outlines around your brush strokes.

Here's a .blend file where i reproduced the issue.
white outline.blend

**System Information** Operating system: Windows-10-10.0.17134 64 Bits Graphics card: GeForce GTX 1080/PCIe/SSE2 NVIDIA Corporation 4.5.0 NVIDIA 417.22 **Blender Version** Broken: version: 2.81 (sub 3), branch: master, commit date: 2019-08-22 20:40, hash: `1de7717ed7` and 2.8 release Worked: Never. As far as I can remember this has always been an issue. **Short description of error** When painting with multiple layers in texture paint mode, there is a white outline around the alpha channel. (You have to be in material view to see the 2 layers at the same time) The first layer is just a solid red color & the second layer's alpha is set to 0 and then I painted on the layer with green color. The layers are mixed together using the MixRGB node with the second layer's alpha set as the mix factor. ***IMPORTANT: the brush falloff needs to be set to the last preset or the issue is not as visible because the change in alpha value is smoother*** ![falloff.PNG](https://archive.blender.org/developer/F7696108/falloff.PNG) ![Texture paint layers white outline.PNG](https://archive.blender.org/developer/F7695973/Texture_paint_layers_white_outline.PNG) The white outline is not visible if I render the scene in cycles, which makes me think that this is a bug. If it's not a bug, it's most likely a limitation of the "Mix" blend mode. ![Rendered view with cycles.PNG](https://archive.blender.org/developer/F7695978/Rendered_view_with_cycles.PNG) This issue makes the texture paint mode unusable for any serious work that needs more than 1 layer. **Exact steps for others to reproduce the error** Unwrap the default cube U> smart UV project, switch to texture paint workspace, add a base color texture & a second base color texture with alpha set to 0, switch to material view, go to the shader editor & Mix the 2 base color textures together using the MixRGB node. The first base color texture goes to the "Color1" input & the second base color texture with alpha goes to the "Color2" input. Connect the alpha output of the second base color texture to the MixRGB node's alpha input. Then paint on the second base color layer with a hard edged brush (last falloff preset) and you get white outlines around your brush strokes. Here's a .blend file where i reproduced the issue. [white outline.blend](https://archive.blender.org/developer/F7696088/white_outline.blend)
Author

Added subscriber: @Syntex3D

Added subscriber: @Syntex3D

#81474 was marked as duplicate of this issue

#81474 was marked as duplicate of this issue
Member
Added subscribers: @PabloDobarro, @fclem, @Jeroen-Bakker, @lichtwerk
Member

Changed status from 'Needs Triage' to: 'Needs Developer To Reproduce'

Changed status from 'Needs Triage' to: 'Needs Developer To Reproduce'
Member

Hi and thx for the report (sorry for the massive delay in answering here)!

To me this seems to be tied to the mode the Texture Interpolation on the Image Texture node?
If I set this to Closest (instead of Linear) for the Image with alpha, this seems to be displaying just fine...

Please also check b98e6743dc... for Filtering in Texture Slots > Material vs Single Image mode

@PabloDobarro , @fclem, @Jeroen-Bakker: I assume this is to be expected behavior? (or is there something wrong with how this is displayed with Linear interpolation?)

Hi and thx for the report (sorry for the massive delay in answering here)! To me this seems to be tied to the mode the `Texture Interpolation` on the `Image Texture` node? If I set this to `Closest` (instead of `Linear`) for the Image with alpha, this seems to be displaying just fine... Please also check b98e6743dc... for Filtering in `Texture Slots` > `Material` vs `Single Image` mode @PabloDobarro , @fclem, @Jeroen-Bakker: I assume this is to be expected behavior? (or is there something wrong with how this is displayed with `Linear` interpolation?)
Member

Seems to be a render difference between cycles and eevee. Perhaps this could be solved by premultiplying the texture when used in eevee, but that will give other artifacts. Point is that in this case the texture is not setup for linear interpolation, so will leave these borders. IMO current solution is that the user should fix the texture to be usable for linear interpolation.

I would vote to put this as a known issue. EEVEE works as it is designed, but can be improved by new developments.

Seems to be a render difference between cycles and eevee. Perhaps this could be solved by premultiplying the texture when used in eevee, but that will give other artifacts. Point is that in this case the texture is not setup for linear interpolation, so will leave these borders. IMO current solution is that the user should fix the texture to be usable for linear interpolation. I would vote to put this as a known issue. EEVEE works as it is designed, but can be improved by new developments.
Member

In #69106#842793, @Jeroen-Bakker wrote:
IMO current solution is that the user should fix the texture to be usable for linear interpolation.

How would you do this (with this kind of falloff)?

> In #69106#842793, @Jeroen-Bakker wrote: > IMO current solution is that the user should fix the texture to be usable for linear interpolation. How would you do this (with this kind of falloff)?
Author

Thanks for the replies :)
The issue happens when using anything other than the default smooth brush curve, if you increase the hardness even a little bit with a custom curve, you get the white artifacts on the edges.
linear interpolation with smooth brush.PNG
When using "closest" interpolation instead of "linear" on the image texture node, the white outline indeed goes away but so does the smoothing, so that's not an option in this case.
Are the changes mentioned in b98e6743dc in the newest alpha build because I couldn't find them from anywhere? @lichtwerk

How would I "fix the texture to be usable for linear interpolation"? @Jeroen-Bakker

I still haven't found a way to fix this issue so any help would be appreciated

Thanks for the replies :) The issue happens when using anything other than the default smooth brush curve, if you increase the hardness even a little bit with a custom curve, you get the white artifacts on the edges. ![linear interpolation with smooth brush.PNG](https://archive.blender.org/developer/F8264080/linear_interpolation_with_smooth_brush.PNG) When using "closest" interpolation instead of "linear" on the image texture node, the white outline indeed goes away but so does the smoothing, so that's not an option in this case. Are the changes mentioned in b98e6743dc in the newest alpha build because I couldn't find them from anywhere? @lichtwerk How would I "fix the texture to be usable for linear interpolation"? @Jeroen-Bakker I still haven't found a way to fix this issue so any help would be appreciated
Member

Not sure if these help (since you can only set it to Closest), but here they are:

T69106_a.png

T69106_b.png

Not sure if these help (since you can only set it to `Closest`), but here they are: ![T69106_a.png](https://archive.blender.org/developer/F8264125/T69106_a.png) ![T69106_b.png](https://archive.blender.org/developer/F8264128/T69106_b.png)
Author

Oddly that fixes the issue on the tansparent layer but now I'm unable to paint on the green solid color layer because the mode is set to "Single image".

I just created a new transparent texture in the "Single image" mode with linear interpolation & alpha set to 0, and swapped that texture to the second image texture node & painted on it with red color.
single image_new transparent layer_linear interpolation.PNG

Linear interpolation seems to work correctly in single image mode but not in material mode.

This is still not a fix because now I'm unable to paint on the green image texture layer.

Oddly that fixes the issue on the tansparent layer but now I'm unable to paint on the green solid color layer because the mode is set to "Single image". I just created a new transparent texture in the "Single image" mode with linear interpolation & alpha set to 0, and swapped that texture to the second image texture node & painted on it with red color. ![single image_new transparent layer_linear interpolation.PNG](https://archive.blender.org/developer/F8264149/single_image_new_transparent_layer_linear_interpolation.PNG) Linear interpolation seems to work correctly in single image mode but not in material mode. This is still not a fix because now I'm unable to paint on the green image texture layer.
Author

Nevermind, it actually works perfectly if you switch the image in "single image" mode. I was able to paint more green in the green layer.
You can switch layers by pressing the button circled in my screenshot.
it actually works.PNG
This 100% fixes the issue. I wonder why it doesn't work properly in "material" mode though

Thanks for helping :)

Nevermind, it actually works perfectly if you switch the image in "single image" mode. I was able to paint more green in the green layer. You can switch layers by pressing the button circled in my screenshot. ![it actually works.PNG](https://archive.blender.org/developer/F8264157/it_actually_works.PNG) This 100% fixes the issue. I wonder why it doesn't work properly in "material" mode though Thanks for helping :)
Member

The original texture had a strong white color with full transparency. When interpolating this white color appears and was rendered.
So with fixing the texture the fully transparent color could have been changed to remove the undesired color interpolation.

image.png

The original texture had a strong white color with full transparency. When interpolating this white color appears and was rendered. So with fixing the texture the fully transparent color could have been changed to remove the undesired color interpolation. ![image.png](https://archive.blender.org/developer/F8264218/image.png)
Member

In #69106#843320, @Jeroen-Bakker wrote:
So with fixing the texture the fully transparent color could have been changed to remove the undesired color interpolation.

Ah, thx for clarification @jbakker.
So I guess this requires a little paintover with Affect Alpha unchecked:
image.png

> In #69106#843320, @Jeroen-Bakker wrote: > So with fixing the texture the fully transparent color could have been changed to remove the undesired color interpolation. Ah, thx for clarification @jbakker. So I guess this requires a little paintover with Affect Alpha unchecked: ![image.png](https://archive.blender.org/developer/F8264239/image.png)

Added subscriber: @will.brown039

Added subscriber: @will.brown039

Hi I stumbled on this and I thought I'd add something,
If you open the source image in an image editor view, you can set the alpha mode to "Premultiplied", which will automatically multiply the RGB values by the alpha so they blend properly. Then you can paint without the white outlines.
premultiplied_change.png
It's odd that you have to open an image editor view to see the "Alpha" option, since you can change the "Image Source" and "Colour Space" options right on the Texture Node in the shader graph.
premultiplied_result.png
Another thing, it looks like the difference between Cycles and Eevee is because one treats "Straight" as "Independent RGB/Alpha" and the other treats it as "Premultiplied RGB/Alpha". If you set the alpha mode to "Premultiplied" or "Channel Packed", you get the same look in both renderers.

Hi I stumbled on this and I thought I'd add something, If you open the source image in an image editor view, you can set the alpha mode to "Premultiplied", which will automatically multiply the RGB values by the alpha so they blend properly. Then you can paint without the white outlines. ![premultiplied_change.png](https://archive.blender.org/developer/F8288658/premultiplied_change.png) It's odd that you have to open an image editor view to see the "Alpha" option, since you can change the "Image Source" and "Colour Space" options right on the Texture Node in the shader graph. ![premultiplied_result.png](https://archive.blender.org/developer/F8288660/premultiplied_result.png) Another thing, it looks like the difference between Cycles and Eevee is because one treats "Straight" as "Independent RGB/Alpha" and the other treats it as "Premultiplied RGB/Alpha". If you set the alpha mode to "Premultiplied" or "Channel Packed", you get the same look in both renderers.
Member

Added subscribers: @WilliamReynish, @brecht

Added subscribers: @WilliamReynish, @brecht
Member

Thx for digging @will.brown039
Indeed this seems to be the (my) cause of confusion as well (should have thought about this before).

In #69106#842793, @Jeroen-Bakker wrote:
Perhaps this could be solved by premultiplying the texture when used in eevee, but that will give other artifacts.

So we already have the freedom to choose here, it is just not obvious. [@Jeroen-Bakker: not sure which artifacts this causes?]

In #69106#853164, @will.brown039 wrote:
It's odd that you have to open an image editor view to see the "Alpha" option, since you can change the "Image Source" and "Colour Space" options right on the Texture Node in the shader graph.

You can do it in the Node Editor, too, if you go to the sidebar and inspect the properties of that Image Texture Node.
(you have more settings in the sidebar than on the node itself, I think this is to keep nodes more compact...)
image.png

However, since this came up, maybe it makes sense in this case to add it to the node directly @WilliamReynish, @brecht?
(screenshot above is already with the patch below, so you can choose the Alpha directly on the node)
P1223: T69106_snippet



diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index 35c9082b54c..5b35ecd0398 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -734,6 +734,13 @@ static void node_buts_image_user(uiLayout *layout,
   uiItemL(split, IFACE_("Color Space"), ICON_NONE);
   uiItemR(split, &colorspace_settings_ptr, "name", 0, "", ICON_NONE);
 
+  uiLayout *split_alpha = uiLayoutSplit(layout, 0.5f, true);
+  uiItemL(split_alpha, IFACE_("Alpha"), ICON_NONE);
+  uiItemR(split_alpha, imaptr, "alpha_mode", 0, "", ICON_NONE);
+  Image *ima = (Image *)imaptr->data;
+  bool is_data = IMB_colormanagement_space_name_is_data(ima->colorspace_settings.name);
+  uiLayoutSetActive(split_alpha, !is_data);
+
   /* Avoid losing changes image is painted. */
   if (BKE_image_is_dirty(imaptr->data)) {
     uiLayoutSetEnabled(split, false);
Thx for digging @will.brown039 Indeed this seems to be the (my) cause of confusion as well (should have thought about this before). > In #69106#842793, @Jeroen-Bakker wrote: > Perhaps this could be solved by premultiplying the texture when used in eevee, but that will give other artifacts. So we already have the freedom to choose here, it is just not obvious. [@Jeroen-Bakker: not sure which artifacts this causes?] > In #69106#853164, @will.brown039 wrote: > It's odd that you have to open an image editor view to see the "Alpha" option, since you can change the "Image Source" and "Colour Space" options right on the Texture Node in the shader graph. You can do it in the Node Editor, too, if you go to the sidebar and inspect the properties of that Image Texture Node. (you have more settings in the sidebar than on the node itself, I think this is to keep nodes more compact...) ![image.png](https://archive.blender.org/developer/F8289384/image.png) However, since this came up, maybe it makes sense in this case to add it to the node directly @WilliamReynish, @brecht? (screenshot above is already with the patch below, so you can choose the `Alpha` directly on the node) [P1223: T69106_snippet](https://archive.blender.org/developer/P1223.txt) ``` diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 35c9082b54c..5b35ecd0398 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -734,6 +734,13 @@ static void node_buts_image_user(uiLayout *layout, uiItemL(split, IFACE_("Color Space"), ICON_NONE); uiItemR(split, &colorspace_settings_ptr, "name", 0, "", ICON_NONE); + uiLayout *split_alpha = uiLayoutSplit(layout, 0.5f, true); + uiItemL(split_alpha, IFACE_("Alpha"), ICON_NONE); + uiItemR(split_alpha, imaptr, "alpha_mode", 0, "", ICON_NONE); + Image *ima = (Image *)imaptr->data; + bool is_data = IMB_colormanagement_space_name_is_data(ima->colorspace_settings.name); + uiLayoutSetActive(split_alpha, !is_data); + /* Avoid losing changes image is painted. */ if (BKE_image_is_dirty(imaptr->data)) { uiLayoutSetEnabled(split, false); ```

Don't add the alpha setting to the node. For correct behavior it almost never needs to be changed, it will encourage users to use the wrong workaround, which then breaks usage of the image in other renderers or tools.

If you open the source image in an image editor view, you can set the alpha mode to "Premultiplied", which will automatically multiply the RGB values by the alpha so they blend properly.

That is not what the option does. It specifies that the image file on disk contains premultiplied colors, and will then use that information to convert the image to the alpha format expected by Blender.

Don't add the alpha setting to the node. For correct behavior it almost never needs to be changed, it will encourage users to use the wrong workaround, which then breaks usage of the image in other renderers or tools. > If you open the source image in an image editor view, you can set the alpha mode to "Premultiplied", which will automatically multiply the RGB values by the alpha so they blend properly. That is not what the option does. It specifies that the image file on disk contains premultiplied colors, and will then use that information to convert the image to the alpha format expected by Blender.
Member

@brecht: thx for clarification (think I still need some more reading on the subject)

@brecht: thx for clarification (think I still need some more reading on the subject)

@brecht If setting the mode to Premultilpied means that the image data is read as already premultipled, then why does alpha_mode == IMA_ALPHA_PREMUL lead to IMB_colormanagement_imbuf_to_byte_texture() multiplying the RGB by alpha, when it's preparing the texture data in gpu_texture_create_from_ibuf()? If it thinks the data is already premultiplied, isn't that redundant?

Sorry if that's a dumb question, I'm just a bit confused following through the code

@brecht If setting the mode to `Premultilpied` means that the image data is read as already premultipled, then why does `alpha_mode == IMA_ALPHA_PREMUL` lead to `IMB_colormanagement_imbuf_to_byte_texture()` multiplying the RGB by alpha, when it's preparing the texture data in `gpu_texture_create_from_ibuf()`? If it thinks the data is already premultiplied, isn't that redundant? Sorry if that's a dumb question, I'm just a bit confused following through the code

Changed status from 'Needs Developer To Reproduce' to: 'Archived'

Changed status from 'Needs Developer To Reproduce' to: 'Archived'
Brecht Van Lommel self-assigned this 2020-01-21 13:42:46 +01:00

You're right, it does end up premultiplying the colors in that case, I wasn't very clear. However it will also unpremultiply the image when loading from disk, which can break things depending on the tool or image file.

The reason for this issue is fb03f50, and it was an intentional change.

Basically, we made to choice to make Eevee behave the same as most game engines for compatibility, while Cycles does texture interpolation as typically found in production renderers. GPU hardware does not support accurate texture interpolation with good performance. It assumes zero alpha areas are still filled with color. By premultiplying the colors you can make it work for some images, while other images will have problematic dark edges.

You're right, it does end up premultiplying the colors in that case, I wasn't very clear. However it will also unpremultiply the image when loading from disk, which can break things depending on the tool or image file. The reason for this issue is fb03f50, and it was an intentional change. Basically, we made to choice to make Eevee behave the same as most game engines for compatibility, while Cycles does texture interpolation as typically found in production renderers. GPU hardware does not support accurate texture interpolation with good performance. It assumes zero alpha areas are still filled with color. By premultiplying the colors you can make it work for some images, while other images will have problematic dark edges.
Added subscribers: @AdrianoOliveira, @iss, @mano-wii, @Diogo_Valadares

Added subscriber: @Punky

Added subscriber: @Punky

I dont't get it. Is there a solution?
I try to paint landscapes (ala unreal engine) with multiple textures: http://kwyn.net/tex_pic.html and get a similar problem. I tried thousend of different things 😉 and still get this effect:
grafik.png.
Any advice (apart from constant falloff, as smoohting leads to the same effect)?

I dont't get it. Is there a solution? I try to paint landscapes (ala unreal engine) with multiple textures: http://kwyn.net/tex_pic.html and get a similar problem. I tried thousend of different things 😉 and still get this effect: ![grafik.png](https://archive.blender.org/developer/F13452019/grafik.png). Any advice (apart from constant falloff, as smoohting leads to the same effect)?

Please try one of the community support forums:
https://www.blender.org/community/

Please try one of the community support forums: https://www.blender.org/community/
Sign in to join this conversation.
No Label
Interest
Alembic
Interest
Animation & Rigging
Interest
Asset Browser
Interest
Asset Browser Project Overview
Interest
Audio
Interest
Automated Testing
Interest
Blender Asset Bundle
Interest
BlendFile
Interest
Collada
Interest
Compatibility
Interest
Compositing
Interest
Core
Interest
Cycles
Interest
Dependency Graph
Interest
Development Management
Interest
EEVEE
Interest
EEVEE & Viewport
Interest
Freestyle
Interest
Geometry Nodes
Interest
Grease Pencil
Interest
ID Management
Interest
Images & Movies
Interest
Import Export
Interest
Line Art
Interest
Masking
Interest
Metal
Interest
Modeling
Interest
Modifiers
Interest
Motion Tracking
Interest
Nodes & Physics
Interest
OpenGL
Interest
Overlay
Interest
Overrides
Interest
Performance
Interest
Physics
Interest
Pipeline, Assets & IO
Interest
Platforms, Builds & Tests
Interest
Python API
Interest
Render & Cycles
Interest
Render Pipeline
Interest
Sculpt, Paint & Texture
Interest
Text Editor
Interest
Translations
Interest
Triaging
Interest
Undo
Interest
USD
Interest
User Interface
Interest
UV Editing
Interest
VFX & Video
Interest
Video Sequencer
Interest
Virtual Reality
Interest
Vulkan
Interest
Wayland
Interest
Workbench
Interest: X11
Legacy
Blender 2.8 Project
Legacy
Milestone 1: Basic, Local Asset Browser
Legacy
OpenGL Error
Meta
Good First Issue
Meta
Papercut
Meta
Retrospective
Meta
Security
Module
Animation & Rigging
Module
Core
Module
Development Management
Module
EEVEE & Viewport
Module
Grease Pencil
Module
Modeling
Module
Nodes & Physics
Module
Pipeline, Assets & IO
Module
Platforms, Builds & Tests
Module
Python API
Module
Render & Cycles
Module
Sculpt, Paint & Texture
Module
Triaging
Module
User Interface
Module
VFX & Video
Platform
FreeBSD
Platform
Linux
Platform
macOS
Platform
Windows
Priority
High
Priority
Low
Priority
Normal
Priority
Unbreak Now!
Status
Archived
Status
Confirmed
Status
Duplicate
Status
Needs Info from Developers
Status
Needs Information from User
Status
Needs Triage
Status
Resolved
Type
Bug
Type
Design
Type
Known Issue
Type
Patch
Type
Report
Type
To Do
No Milestone
No project
No Assignees
8 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: blender/blender#69106
No description provided.