mirror of
https://github.com/zed-industries/zed.git
synced 2024-09-20 02:47:34 +03:00
Use 16-bit float to store path windings
Previously, we were using a normalized 8-bit unsigned integer which forced us to represent each increment of the winding number as a fraction of the max value (1 / 255) which we would then add up using additive alpha blending. This had three major drawbacks: - The max winding number could not be greater than 255. - Adding up (1 / 255) several times could result in a loss of precision. - Due to also computing anti-aliasing as a fractional winding number, we had to reduce the max winding number to 32. This was still not good enough because we would multiply a fractional value with `1 / 32`, thus introducing more and more loss of precision. This commit changes the texture type to an `f16` which doesn't require the division by 255 and enables greater precision in the computation of the anti-aliased parts of a curve. Note how this also removes the limitation of 255 windings at most per curve. The tradeoff is paying twice as much memory for storing the texture, but that seems totally valid to achieve rendering accuracy. Note that this kind of texture should be compatible with WebGL2 once we start working on a web version of Zed.
This commit is contained in:
parent
3426d46b69
commit
45d1690f6e
@ -107,7 +107,7 @@ impl Renderer {
|
||||
"path_atlas",
|
||||
"path_atlas_vertex",
|
||||
"path_atlas_fragment",
|
||||
MTLPixelFormat::R8Unorm,
|
||||
MTLPixelFormat::R16Float,
|
||||
);
|
||||
Self {
|
||||
sprite_cache,
|
||||
@ -827,7 +827,7 @@ fn build_path_atlas_texture_descriptor() -> metal::TextureDescriptor {
|
||||
let texture_descriptor = metal::TextureDescriptor::new();
|
||||
texture_descriptor.set_width(2048);
|
||||
texture_descriptor.set_height(2048);
|
||||
texture_descriptor.set_pixel_format(MTLPixelFormat::R8Unorm);
|
||||
texture_descriptor.set_pixel_format(MTLPixelFormat::R16Float);
|
||||
texture_descriptor
|
||||
.set_usage(metal::MTLTextureUsage::RenderTarget | metal::MTLTextureUsage::ShaderRead);
|
||||
texture_descriptor.set_storage_mode(metal::MTLStorageMode::Private);
|
||||
|
@ -205,8 +205,6 @@ vertex SpriteFragmentInput sprite_vertex(
|
||||
};
|
||||
}
|
||||
|
||||
#define MAX_WINDINGS 32.
|
||||
|
||||
fragment float4 sprite_fragment(
|
||||
SpriteFragmentInput input [[stage_in]],
|
||||
texture2d<float> atlas [[ texture(GPUISpriteFragmentInputIndexAtlas) ]]
|
||||
@ -216,7 +214,7 @@ fragment float4 sprite_fragment(
|
||||
float4 sample = atlas.sample(atlas_sampler, input.atlas_position);
|
||||
float mask;
|
||||
if (input.compute_winding) {
|
||||
mask = 1. - abs(1. - fmod(sample.r * MAX_WINDINGS, 2.));
|
||||
mask = 1. - abs(1. - fmod(sample.r, 2.));
|
||||
} else {
|
||||
mask = sample.a;
|
||||
}
|
||||
@ -303,6 +301,6 @@ fragment float4 path_atlas_fragment(
|
||||
);
|
||||
float f = (input.st_position.x * input.st_position.x) - input.st_position.y;
|
||||
float distance = f / length(gradient);
|
||||
float alpha = saturate(0.5 - distance) / MAX_WINDINGS;
|
||||
float alpha = saturate(0.5 - distance);
|
||||
return float4(alpha, 0., 0., 1.);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user