Pixel art anti aliasing #10083
Replies: 6 comments 10 replies
-
Relevant: #9349 |
Beta Was this translation helpful? Give feedback.
-
Likewise relevant: #1856 (comment) |
Beta Was this translation helpful? Give feedback.
-
For what it counts, I'd love to have this in Bevy. |
Beta Was this translation helpful? Give feedback.
-
Unanswered questions are perfectly fine for a PR! Opening a PR would be the best way to make sure your questions don't get accidentally overlooked by the project maintainers. If you don't want it merged yet, just mark as draft. |
Beta Was this translation helpful? Give feedback.
-
Was this ever added? (Pardon this Bevy newbie if there's an obvious place for me to have checked instead of asking...) Also, again pardon newbie Q, I'm bringing images into a 3D world as simple flat meshes and can scale them with the mouse wheel--but it's important to see the pixels when they're large. Seems like this might allow that? Thank you all! (Newbie but already accomplishing a lot with my hacks... ; ) |
Beta Was this translation helpful? Give feedback.
-
To do this for all textures by default in Bevy 0.14 you can simply do:
To do this in Bevy 0.14 without changing every texture in the app by default, you can set it per-texture like so:
The complication here is that this can only be done after the image is loaded, which is done in parallel. The 'handle' you get may not be in a loaded state, hence why we verify the loaded state and return after it isn't ready. Of course, you don't want this system running on every frame so you'll want to use run conditions to ensure that it only runs when needed. I do this using a state enum that is set to |
Beta Was this translation helpful? Give feedback.
-
Objective
Better anti aliasing for upscaled pixel art.
Pixel art often uses nearest-neighbor sampling when upscaling. This works well for 2D environments with an integer scale factor, but otherwise leads to aliasing artifacts.
Solution
I'm proposing an implementation of the solution described in this video: https://youtu.be/d6tp43wZqps
The video explains it well and includes graphics to better illustrate why the process works, but here's a simplified summary if you'd prefer:
Simplified explanation
I've implemented this in my fork here and have a sample project using it here. Because of the following questions, though, I don't think it's ready for a PR quite yet.
Unanswered questions
For the following questions, I'm not sure which approach is best. In the current implementation, I arbitrarily chose to add
pbr_functions::texture_sample
and use a shader definePIXEL_ART_ANTI_ALIASING
. This can be easily changed depending on the discussion.When to check if enabled
To actually implement this strategy within Bevy, all relevant instances of texture sampling must be replaced with this function. I'll call it
pixel_art_texture_sample
. There are a few ways to approach this:texture_sample
) that checks if this feature is enabled. Use this to replace all relevant calls to a built-in texture sample.Pseudocode
pixel_art_texture_sample
.Example
From
pbr.wgsl
:(Most of the builtin texture samples use a mip bias. This can be compensated for as explained here)
How to check if enabled
There are also two approaches for the enabled check itself. We can either add a new shader define, or add a new flag to the standard material's flags.
What is a "relevant texture sample"?
There's also the question of what texture samples should use the new method. Bevy's PBR shaders have many different textures, and any time one of them is sampled, we have to choose whether this new behaviour is necessary.
Obviously, base color texture should use it. Using it for the normal map and emissive textures also seems useful. The metallic/roughness and occlusion textures don't seem particularly likely to be provided with pixel art, but if they were, I think using this technique would produce more consistent results.
There are more texture samples than these in the PBR shaders, though. A grep shows the following files:
I don't really know enough about PBR to judge if these should also use this technique. But, since this technique shouldn't change the overall shape of the texture, perhaps shadows don't need to use it.
Possible issues
Beta Was this translation helpful? Give feedback.
All reactions