This bug seems to be a quirk in the algorithm. Basically, it's resampling from the left edge of the pixel rather than the center (pixels have a width and height when you're using continuous functions) which causes the shift. Fixing it is non-trivial, so I'm going to put it off for now.