Case 895

The transparent pixels still had a value

the_transparent_pixels_still_had_a_value.eml - A sprite is drawn with smooth edges by bilinear filtering, and the filter is the engine's own, applied exactly at every edge pixel. What a fully transparent pixel still carries into the filter is computed below.

ok: true — round-trip fixpoint reached (python1 == python2)updated 2026-09-17

EML

eml
# Self-authored for the EML case corpus (no external origin). A sprite is drawn
# with smooth edges by bilinear filtering, and the filter is the engine's own,
# applied exactly at every edge pixel. What a fully transparent pixel still
# carries into the filter is computed below.
#
# The draw is careful. It reads the real sprite pixels, not a proxy; it uses the
# engine's own bilinear filter at every edge; alpha is honoured so transparent
# areas stay transparent; and the intent is exactly 'a smooth, correctly
# coloured edge'.
#
# A transparent pixel is stored with alpha 0 and a colour nobody ever sees -
# black - and straight-alpha filtering averages that black into the edge, so a
# white sprite gets a dark fringe.

255 => opaque_pixel_value
255 => opaque_pixel_alpha
0 => transparent_pixel_value
0 => transparent_pixel_alpha

opaque_pixel_value + transparent_pixel_value => value_sum
int(value_sum / 2) => edge_value_straight_alpha
opaque_pixel_alpha + transparent_pixel_alpha => alpha_sum
int(alpha_sum / 2) => edge_alpha
opaque_pixel_value => edge_value_premultiplied
int(edge_value_straight_alpha * 10000 / opaque_pixel_value) => edge_brightness_share_per_myriad

"opaque sprite pixel             : value " + str(opaque_pixel_value) + ", alpha " + str(opaque_pixel_alpha) ^0
"transparent neighbour           : value " + str(transparent_pixel_value) + ", alpha " + str(transparent_pixel_alpha) ^0
"" ^0
"edge pixel, straight alpha      : value " + str(edge_value_straight_alpha) + ", alpha " + str(edge_alpha) ^0
"edge pixel, premultiplied       : value " + str(edge_value_premultiplied) + ", alpha " + str(edge_alpha) ^0
"edge brightness, straight       : " + str(edge_brightness_share_per_myriad) + " per ten thousand of the sprite" ^0
"" ^0

# ---- what the draw verified ----

"the edge filter" ^0
"  reads : the real sprite pixels" ^0
"  filter : the engine's own bilinear, at every edge pixel" ^0
"  alpha : honoured, transparent areas stay transparent" ^0
"  intent : a smooth, correctly coloured edge" ^0
"  edge pixels skipped : 0" ^0
"  verdict : EVERY EDGE PIXEL IS THE MEAN OF ITS NEIGHBOURS" ^0
"" ^0
"  applying the engine's filter exactly at every edge pixel" ^0
"  is the part done right here, and it is why the alpha ramp" ^0
"  is smooth and the transparent area really is transparent" ^0
"" ^0

# ---- what a transparent pixel carries ----

"the stored transparent pixel" ^0
"  alpha : 0, so it is never drawn on its own" ^0
"  value : 0, black, which nobody sees while alpha is 0" ^0
"  what straight-alpha filtering does : averages values and" ^0
"    alphas separately" ^0
"  so the edge value : mean of 255 and 0, " + str(edge_value_straight_alpha) + " - half-black" ^0
"  at alpha " + str(edge_alpha) + " : a visible, dark, half-transparent fringe" ^0
"" ^0

# ---- what the viewer sees ----

"the sprite on screen" ^0
"  intended : a white sprite fading smoothly to nothing" ^0
"  rendered : a white sprite with a grey rim" ^0
"  is the filter wrong : no; it is the mean it was asked for" ^0
"  is a transparent pixel colourless : no; it has a value," ^0
"    and the filter reads it" ^0
"" ^0

# ---- null control ----

# The same sprite in premultiplied alpha (value times alpha stored), so a
# transparent pixel contributes nothing to the mean.
127 => nc_edge_value_straight
255 => nc_edge_value_premultiplied
0 => nc_dark_fringe_pixels_premultiplied

"null control - premultiply alpha before filtering" ^0
"  edge value, straight alpha : " + str(nc_edge_value_straight) ^0
"  edge value, premultiplied : " + str(nc_edge_value_premultiplied) ^0
"  dark fringe pixels, premultiplied : " + str(nc_dark_fringe_pixels_premultiplied) ^0
"  no pixel and no filter changed; the invisible colour" ^0
"  stopped weighing in the mean" ^0
"" ^0

# ---- the rule ----

"what a straight-alpha bilinear edge guarantees" ^0
"  each edge pixel is the mean of its neighbours' values and" ^0
"    alphas : exactly, the engine's own filter" ^0
"  each edge pixel is the sprite's colour, fading : not" ^0
"    addressed; the transparent neighbour stores black, and" ^0
"    the mean reads it, so the edge is " + str(edge_value_straight_alpha) + " where the sprite is " + str(opaque_pixel_value) ^0
"" ^0

"a pixel that cannot be seen still has a number, and a filter does not know which" ^0
"numbers are invisible; the mean weighs the hidden black as much as the shown" ^0
"white, and the seam between them is where the hidden value surfaces" ^0
"" ^0

"It applies the engine's own bilinear filter at every edge pixel - the alpha ramp" ^0
"is smooth. But the transparent neighbour stores value 0 and straight-alpha" ^0
"filtering averages it in, so the edge is " + str(edge_value_straight_alpha) + " where the sprite is " + str(opaque_pixel_value) + "," ^0
"" + str(edge_brightness_share_per_myriad) + " per ten thousand of its brightness, until alpha is premultiplied." ^0

Python (deterministic transpilation)

python
opaque_pixel_value = 255
opaque_pixel_alpha = 255
transparent_pixel_value = 0
transparent_pixel_alpha = 0
value_sum = opaque_pixel_value + transparent_pixel_value
edge_value_straight_alpha = int(value_sum / 2)
alpha_sum = opaque_pixel_alpha + transparent_pixel_alpha
edge_alpha = int(alpha_sum / 2)
edge_value_premultiplied = opaque_pixel_value
edge_brightness_share_per_myriad = int(edge_value_straight_alpha * 10000 / opaque_pixel_value)
print("opaque sprite pixel             : value " + str(opaque_pixel_value) + ", alpha " + str(opaque_pixel_alpha))
print("transparent neighbour           : value " + str(transparent_pixel_value) + ", alpha " + str(transparent_pixel_alpha))
print("")
print("edge pixel, straight alpha      : value " + str(edge_value_straight_alpha) + ", alpha " + str(edge_alpha))
print("edge pixel, premultiplied       : value " + str(edge_value_premultiplied) + ", alpha " + str(edge_alpha))
print("edge brightness, straight       : " + str(edge_brightness_share_per_myriad) + " per ten thousand of the sprite")
print("")
print("the edge filter")
print("  reads : the real sprite pixels")
print("  filter : the engine's own bilinear, at every edge pixel")
print("  alpha : honoured, transparent areas stay transparent")
print("  intent : a smooth, correctly coloured edge")
print("  edge pixels skipped : 0")
print("  verdict : EVERY EDGE PIXEL IS THE MEAN OF ITS NEIGHBOURS")
print("")
print("  applying the engine's filter exactly at every edge pixel")
print("  is the part done right here, and it is why the alpha ramp")
print("  is smooth and the transparent area really is transparent")
print("")
print("the stored transparent pixel")
print("  alpha : 0, so it is never drawn on its own")
print("  value : 0, black, which nobody sees while alpha is 0")
print("  what straight-alpha filtering does : averages values and")
print("    alphas separately")
print("  so the edge value : mean of 255 and 0, " + str(edge_value_straight_alpha) + " - half-black")
print("  at alpha " + str(edge_alpha) + " : a visible, dark, half-transparent fringe")
print("")
print("the sprite on screen")
print("  intended : a white sprite fading smoothly to nothing")
print("  rendered : a white sprite with a grey rim")
print("  is the filter wrong : no; it is the mean it was asked for")
print("  is a transparent pixel colourless : no; it has a value,")
print("    and the filter reads it")
print("")
nc_edge_value_straight = 127
nc_edge_value_premultiplied = 255
nc_dark_fringe_pixels_premultiplied = 0
print("null control - premultiply alpha before filtering")
print("  edge value, straight alpha : " + str(nc_edge_value_straight))
print("  edge value, premultiplied : " + str(nc_edge_value_premultiplied))
print("  dark fringe pixels, premultiplied : " + str(nc_dark_fringe_pixels_premultiplied))
print("  no pixel and no filter changed; the invisible colour")
print("  stopped weighing in the mean")
print("")
print("what a straight-alpha bilinear edge guarantees")
print("  each edge pixel is the mean of its neighbours' values and")
print("    alphas : exactly, the engine's own filter")
print("  each edge pixel is the sprite's colour, fading : not")
print("    addressed; the transparent neighbour stores black, and")
print("    the mean reads it, so the edge is " + str(edge_value_straight_alpha) + " where the sprite is " + str(opaque_pixel_value))
print("")
print("a pixel that cannot be seen still has a number, and a filter does not know which")
print("numbers are invisible; the mean weighs the hidden black as much as the shown")
print("white, and the seam between them is where the hidden value surfaces")
print("")
print("It applies the engine's own bilinear filter at every edge pixel - the alpha ramp")
print("is smooth. But the transparent neighbour stores value 0 and straight-alpha")
print("filtering averages it in, so the edge is " + str(edge_value_straight_alpha) + " where the sprite is " + str(opaque_pixel_value) + ",")
print("" + str(edge_brightness_share_per_myriad) + " per ten thousand of its brightness, until alpha is premultiplied.")

stdout (executed)

text
opaque sprite pixel             : value 255, alpha 255
transparent neighbour           : value 0, alpha 0

edge pixel, straight alpha      : value 127, alpha 127
edge pixel, premultiplied       : value 255, alpha 127
edge brightness, straight       : 4980 per ten thousand of the sprite

the edge filter
  reads : the real sprite pixels
  filter : the engine's own bilinear, at every edge pixel
  alpha : honoured, transparent areas stay transparent
  intent : a smooth, correctly coloured edge
  edge pixels skipped : 0
  verdict : EVERY EDGE PIXEL IS THE MEAN OF ITS NEIGHBOURS

  applying the engine's filter exactly at every edge pixel
  is the part done right here, and it is why the alpha ramp
  is smooth and the transparent area really is transparent

the stored transparent pixel
  alpha : 0, so it is never drawn on its own
  value : 0, black, which nobody sees while alpha is 0
  what straight-alpha filtering does : averages values and
    alphas separately
  so the edge value : mean of 255 and 0, 127 - half-black
  at alpha 127 : a visible, dark, half-transparent fringe

the sprite on screen
  intended : a white sprite fading smoothly to nothing
  rendered : a white sprite with a grey rim
  is the filter wrong : no; it is the mean it was asked for
  is a transparent pixel colourless : no; it has a value,
    and the filter reads it

null control - premultiply alpha before filtering
  edge value, straight alpha : 127
  edge value, premultiplied : 255
  dark fringe pixels, premultiplied : 0
  no pixel and no filter changed; the invisible colour
  stopped weighing in the mean

what a straight-alpha bilinear edge guarantees
  each edge pixel is the mean of its neighbours' values and
    alphas : exactly, the engine's own filter
  each edge pixel is the sprite's colour, fading : not
    addressed; the transparent neighbour stores black, and
    the mean reads it, so the edge is 127 where the sprite is 255

a pixel that cannot be seen still has a number, and a filter does not know which
numbers are invisible; the mean weighs the hidden black as much as the shown
white, and the seam between them is where the hidden value surfaces

It applies the engine's own bilinear filter at every edge pixel - the alpha ramp
is smooth. But the transparent neighbour stores value 0 and straight-alpha
filtering averages it in, so the edge is 127 where the sprite is 255,
4980 per ten thousand of its brightness, until alpha is premultiplied.

Trace event types

eml:run:starteml:assigneml:outputeml:run:done