Use premultiplied alpha for emoji rendering (#37370)

This improves emoji rendering on windows removing artifacts at the edges
by using premultiplied alpha. A bit more context can be found in #37167

Release Notes:

- N/A
This commit is contained in:
localcc
2025-09-02 13:59:27 +00:00
committed by GitHub
parent 47ad1b2143
commit 60b95d9253
2 changed files with 18 additions and 3 deletions
@@ -39,5 +39,6 @@ cbuffer GlyphLayerTextureParams : register(b0) {
float4 emoji_rasterization_fragment(PixelInput input): SV_Target {
float sample = t_layer.Sample(s_layer, input.texcoord.xy).r;
float alpha_corrected = apply_contrast_and_gamma_correction(sample, run_color.rgb, grayscale_enhanced_contrast, gamma_ratios);
return float4(run_color.rgb, alpha_corrected * run_color.a);
float alpha = alpha_corrected * run_color.a;
return float4(run_color.rgb * alpha, alpha);
}
@@ -112,10 +112,10 @@ impl GPUState {
RenderTarget: [
D3D11_RENDER_TARGET_BLEND_DESC {
BlendEnable: true.into(),
SrcBlend: D3D11_BLEND_SRC_ALPHA,
SrcBlend: D3D11_BLEND_ONE,
DestBlend: D3D11_BLEND_INV_SRC_ALPHA,
BlendOp: D3D11_BLEND_OP_ADD,
SrcBlendAlpha: D3D11_BLEND_SRC_ALPHA,
SrcBlendAlpha: D3D11_BLEND_ONE,
DestBlendAlpha: D3D11_BLEND_INV_SRC_ALPHA,
BlendOpAlpha: D3D11_BLEND_OP_ADD,
RenderTargetWriteMask: D3D11_COLOR_WRITE_ENABLE_ALL.0 as u8,
@@ -1132,6 +1132,20 @@ impl DirectWriteState {
};
}
// Convert from premultiplied to straight alpha
for chunk in rasterized.chunks_exact_mut(4) {
let b = chunk[0] as f32;
let g = chunk[1] as f32;
let r = chunk[2] as f32;
let a = chunk[3] as f32;
if a > 0.0 {
let inv_a = 255.0 / a;
chunk[0] = (b * inv_a).clamp(0.0, 255.0) as u8;
chunk[1] = (g * inv_a).clamp(0.0, 255.0) as u8;
chunk[2] = (r * inv_a).clamp(0.0, 255.0) as u8;
}
}
Ok(rasterized)
}