To model a scanline, we can first start by modeling a CRT's spot and then model its translation across the screen.
What should we use to model the spot? Something based on a two-dimensional gaussian (
- A gaussian extends to infinity on the
$x$ axis, so we would have to window or truncate it. - Two gaussians overlapping form higher peaks than each one by itself. Imagine two scanlines next to each other. Near the peaks of the individual gaussians would be slightly taller peaks of their sum. If this was our spot model, we would have to deal with these by rescaling the gaussians or the sums to be within the range of 0 to 1. See
overlap-gaussian.png
for a visual example.
Neither of these problems is insurmountable, but they make the math a bit more annoying. Instead, we can use a raised cosine:
When two adjacent raised cosines are added together, the sum will never be above the peaks as long as they are at least half of their widths apart. I believe I got this idea from crt-lottes-fast, although that shader uses a different way of calculating scanlines. See overlap-cosine.png
for a visual example.
We can generalize this to two dimensions:
Compare the images below: spot_gaussian.png
and spot_cosine.png
. The cosine spot is slightly squared off in comparison but is pretty similar.
The size and intensity of the spot also varies. We can consider
- Have an integral over its bounds equal to
$s$ so that its overall brightness varies linearly. - Have a width
$\sigma(s)$ that increases as the brightness increases. In other words, the spot should get larger as its intensity increases.
We can satisfy both of these constraints:
Now, imagine the spot being scanned across the screen horizontally over time. The areas it lights up are integrated by our eyes (helped by the persistence of the phosphor) to look like lines. We can model a scanline with an integral and the addition of a time element:
(Note that the bounds of the spot function are omitted for visual clarity.)
We essentially scan the spot over the screen between time
For
I would like to measure an actual CRT to check how accurate to reality this width function is, but my JVC is currently relegated to the garage.
So now with all of this together, our scanline integral is clearly not practical to solve analytically. That's fine, because we don't actually have an analytic representation of
For any given point on the screen, we can estimate its value by adding the estimates from the two nearest scanlines. As long as
Note that if we had instead projected our spot to two dimensions as