Closed Giwayume closed 6 months ago
This is an asset issue and not something three.js can fix. The texture needs to be adjusted so that the RGB values in the transparent sections are not black. I'd recommend asking at the forums for more help on how to deal with this issue:
They aren't, everything that is under partial transparency is fully yellow. Only the fully transparent pixels are black.
This is expected behavior if you're using a drawing brush in something like photoshop, the brush should only affect the color of the pixels underneath it. It won't attempt to change the transparent area of the entire canvas that has nothing to do with where the brush touched.
I don't agree with the assessment that this is something that should be fixed in the asset. But if WebGL has a general issue where it is incorrectly reading values from fully transparent pixels and there is no way to fix that... guess nothing can be done.
They aren't, everything that is under partial transparency is fully yellow. Only the fully transparent pixels are black.
Zooming into the pixels in your image editor is not necessarily representative of what's directly in the saved asset and loaded.
I don't agree with the assessment that this is something that should be fixed in the asset. But if WebGL has a general issue where it is incorrectly reading values from fully transparent pixels and there is no way to fix that... guess nothing can be done.
It isn't a matter of disagreement - this is a common, well understood issue when linearly interpolating transparent assets and generating mip maps. It occurs in all graphics APIs, not just WebGL. The pixels in the transparent area are black so when texture samples are interpolated or mipmaps are generated the RGB channel result is mixed with black.
Zooming into the pixels in your image editor is not necessarily representative of what's directly in the saved asset and loaded.
It is in this case. Easy to verify. If you're talking about what's actually in memory when Photoshop loads an image like this, who knows, maybe they modify the image a bit in memory to kind of expand the colors on the border of an image with full transparency. Seems like an expensive operation to do for every single layer. Or Photoshop just renders zoomed out previews full resolution then scales down? That's also very expensive. Or, don't tell me, Photoshop avoids this artifact by rendering on the CPU...
The pixels in the transparent area are black so when texture samples are interpolated or mipmaps are generated the RGB channel result is mixed with black.
I understand the concept, but at the same time I could provide a linear interpolation algorithm that throws fully transparent pixels out and doesn't have this issue. The fact that the hardware can't do this just means the spec is trying to save on performance and doesn't consider it useful enough to avoid this artifact. No one writing a useful scaling algorithm would try to interpolate invisible pixels!
I don't agree with the assessment that this is something that should be fixed in the asset. But if WebGL has a general issue where it is incorrectly reading values from fully transparent pixels and there is no way to fix that... guess nothing can be done.
To avoid the artifacts you're seeing the top image needs to be all yellow.
For me this was a painful concept to learn back in the 90s 😬
Edit: In Photoshop you have to edit the colors of the image separately from the alpha channel and make sure the colors are not being premultiplied when saving.
Premultiplied alpha is an issue for handling for semi-transparent pixels, it seems this issue is the color blending occurs across fully transparent pixels. All partially transparent pixels are already yellow. I'm working on an image editor, not a video game, so the answer for me isn't as simple as "fix your asset".
If you open the smiley face asset in Photoshop you don't see the black outline when you zoom out. Maybe the answer is they're using the CPU for scaling, either way there is a solution for display that doesn't involve modifying the fully transparent black pixels.
I don't want to do something like write a shader that pulls the nearest color values from alpha > 0 pixels into alpha == 0 pixels that operates on each layer. I've seen how terrible the performance of shaders are that do cross pixel reads like a gaussian blur.
Description
minFilter = LinearMipmapLinearFilter
minFilter = LinearFilter
If a texture with transparency is drawn in front of another object, when mipmaps are in use, an unwanted outline is generated.
Reproduction steps
Code
Live example
https://jsfiddle.net/b14e3ndf/
Screenshots
No response
Version
r149
Device
No response
Browser
No response
OS
No response