Appearance
Sampling & moiré
A regular scanline pattern can turn into broad, uneven bands on the output grid. Its formula may be perfectly repeatable; sampling at another spacing makes fine repetition appear much slower.
This history follows our work on Beamline's generated CRT structure: the beam profile, scanlines and Studio material masks. Game-grid detection and source-pixel recovery are different problems.
The pattern and the pixels
Imagine a bright beam repeating once per logical row. With N output pixels per row, that repetition has a fundamental frequency of 1/N cycles per output pixel. A narrow, shaped beam also contains harmonics: components repeating two, three or more times per row. Representing the fundamental does not necessarily represent the whole beam shape.
For a uniformly sampled, band-limited signal, frequencies must lie below half the sample rate to retain their information without aliasing. That boundary is Nyquist. At exactly two samples per sinusoidal period, the result is already phase-sensitive: a sine can put every sample on a zero crossing.
Frequencies above the supported band can appear as lower ones after sampling. That is aliasing. When repetition and the sample grid nearly line up, the apparent difference frequency can be very low: many fine rows become a few broad bands. In two dimensions, rotated or warped patterns can form a moiré weave. Here, “banding” describes spatial brightness bands, not the separate problem of color quantization.
Why moving or resizing changes it
A small change in spacing or phase changes which parts of the beam land on output sample centers. The large-scale artifact can move much farther than the fine structure itself. Curvature makes that relationship vary across one image; reducing the output resolution can make it fail even on a flat raster.
We need to reduce unsupported structure before sampling creates the artifact. A later screenshot blur may hide bands, but it also softens game detail and cannot tell which frequencies were intended.
Curvature made it worse
Flat presentation has a relatively simple relationship between output pixels and CRT rows. Curvature changes that relationship across the screen. A square output pixel covers a warped region in CRT space, so a row pattern that is adequately sampled at one point can become compressed or tilted elsewhere.
The filter needs a local footprint. Warp derivatives approximate it as a parallelogram whose extent and orientation describe the region one output pixel covers.
Four, nine, then sixteen positions
We first tried averaging the completed CRT result as the terminal stage presented it. Four taps gave way to nine, then sixteen:
| Attempt | What it actually sampled | Limitation addressed next |
|---|---|---|
| Four positions | Interior offsets at ±¼ of each warp derivative, averaged equally. | Sparse coverage still left the curved carrier insufficiently filtered. |
| Nine positions | A 3×3 center-and-edge lattice at −½, 0 and +½ derivative offsets, with equal weights. | A regular center/edge pattern could resonate with the periodic CRT structure. |
| Sixteen positions | A 4×4 midpoint lattice at −⅜, −⅛, +⅛ and +⅜ along each derivative. | Denser footprint coverage, but still a finite approximation sampling an already generated pattern. |
The footprint average blended in only where the warp minified the raster; elsewhere the center evaluation stayed unchanged. The counts refer to positions in that average, rather than total texture fetches or rendered frames. The sixteen-point path also evaluates the center separately.
The separate-pass detour
We then tried storing the flat tone result, adding a four-tap curvature prefilter and reading that texture at presentation. A follow-up fixed the mapping between warped source coordinates and output coordinates. The extra passes were later removed, restoring the sixteen-point baseline.
The restored sixteen-point integration still runs when the warp footprint requires it.
Filter the beam, not the screenshot
The lasting correction moved some filtering into the beam calculation. We could soften Beamline's periodic brightness structure for the output footprint before presentation sampled it, while leaving the game's image free of a general blur.
“Beam carrier” means the repeating row profile here. Studio's retired chroma carrier belonged to a different signal stage.
Project a pixel into row phase
Optics constructs the flat CRT signal that the terminal shell will warp. At each signal location, two fixed iterations approximately invert the warp. The local Jacobian then describes how CRT coordinates change as we move across output pixels.
Only the vertical projection is needed for the repeating row beam. Both horizontal and vertical output motion can change CRT row phase under curvature. If one output pixel advances row phase by dx along one axis and dy along the other, the footprint's phase variance is approximated by:
(dx² + dy²) / 12
The factor 1/12 is the variance of a uniform unit-width interval. This gives a local, first-order estimate of the footprint, rather than an exact integral of the nonlinear warp.
Broaden with an energy correction
The beam calculation uses Gaussian-shaped lobes whose widths and strengths depend on image values. The correction locally treats each lobe's parameters as fixed and broadens it according to the projected variance. A reciprocal square-root factor lowers its peak as it widens, preserving that locally frozen lobe's integrated energy.
This moment-matched Gaussian approximation attenuates fine row structure gradually, without a sharp frequency cutoff. The local energy correction applies to the broadened lobe; neighboring-row reconstruction, clipping, color-dependent behavior and later stages still shape the final image.
With no curvature or overscan, this contribution is zero. At generous flat scales, the original beam formula stays unchanged. Curved presentation adds filtering for its extra compression; low scales add another contribution.
Current filtering stages
Both the beam prefilter and sixteen-point terminal integration remain. One filters the structure being generated; the other averages the completed result through the presentation footprint. Together they reduce sampling artifacts in Beamline's generated structure.
The 4× → 3× → 2× problem
Curvature was not the only source of unstable row structure. A flat CRT raster can undersample its own beam when too few output pixels cover each logical row. Changing the warp cannot repair that earlier sampling boundary.
Here, × counts output samples per selected logical row: treated content height divided by logical height. The ratio can be fractional. It describes the treatment's scale, independently of desktop zoom or the game's original source resolution.
The first low-scale fix stopped too late
Virtual Raster explains how Beamline manufactures the synthetic image and derives its treatment scale. Higher virtual heights leave fewer output samples per logical row at a fixed output size.
Our first correction broadened the beam below three samples per row, adding normalized Gaussian variance to the curvature contribution. It kept the old path at 3× and above. This helped as the fundamental approached Nyquist at 2×, but missed the unsupported second and higher harmonics at 3×.
A once-per-row fundamental at 3× has a frequency of ⅓ cycle per output pixel, below the ½-cycle limit. Its second harmonic is ⅔ cycle per pixel, above it. Preserving the full narrow beam because its fundamental fits does not preserve the rest of its shape safely.
Current low-scale transition
The replacement uses two continuous transitions in logical phase step:
| Samples per row | Current beam treatment |
|---|---|
| 4× and above | The low-scale correction is inactive; the original beam profile remains. Curvature can still add its own filtering. |
| 4× toward 3× | Blend toward a bounded mean-plus-fundamental representation, reducing unsupported higher harmonics. |
| At 3× | Retain the mean and an attenuated fundamental rather than the original full periodic shape. |
| 3× toward 2× | Fade the remaining fundamental toward a phase-neutral energy mean. |
| 2× and below | Use that mean for the generated row carrier, avoiding strong unresolved row-phase modulation. |
Illustrative frequencies in cycles per logical row. At 4×, Nyquist is 2 cycles/row. The original profile keeps its appearance there even though some shaped-beam harmonics may still exceed that limit.
Four midpoint phases within a row period estimate the canonical beam's mean and first harmonic. They sample phase, unlike the four spatial taps of the earlier curvature experiment. This finite estimate approximates the continuous Fourier coefficients. Gaussian footprint attenuation reduces the retained fundamental, then the mean transition removes its phase dependence by 2×.
The mean applies to the generated carrier at the local reconstructed image value. Game imagery and other stages still vary, so rows retain different colors and some visible bands may remain.
Studio adds another periodic structure
Multiplying a beam by a periodic material mask creates sum and difference frequencies, often called sidebands. Even a representable beam component can mix with a mask into unwanted structure. The August low-scale correction therefore also faded Studio's then-current masks toward their period means.
That mask implementation was superseded. Studio now derives material pitch from logical spacing, integrates coverage over an output-pixel footprint, and fades modulation from four samples per mask period to its mean at two. Mask periods differ from logical rows. Core omits these masks; Scanlines, masks and sampling explains their treatment.
September's Studio change removed chroma-carrier modulation/demodulation from Y/I/Q transport while keeping the row beam and its low-scale filter. The carrier that shouldn't have been there follows that investigation. LCD uses another approach, covered in When the output cannot resolve the panel.