'D3D11 Half Pixel distorting objects?

I have had this problem with D3D and OpenGL for years (probably for different reasons!). This happens no matter how I draw it. There is another problem not shown in the gif below, which is the a single pixel of a rectangle not being drawn.

Everything is drawn using triangles in the gif below, the same problem occurs if using lines to draw a rect. I am not sure what code is relevant to this issue, whether is it the shader, viewport, projection matrix, or something else.

The start position of each object is aligned at 0.5 or 0.0, but each line call may not. While I've read that D3D11 fixes this half pixel problem, it seems something is off by half a pixel or should be offset by half a pixel.

Here is my code to draw a line:

void line(float x1, float y1, float x2, float y2) {
            float line_width = 0.5f;

            auto a = Vector2{ x2 - x1, y2 - y1 }.perp().normalize() * line_width;

            put(x1 - a.x, y1 - a.y);
            put(x2 - a.x, y2 - a.y);
            put(x2 + a.x, y2 + a.y);

            put(x1 + a.x, y1 + a.y);
            put(x1 - a.x, y1 - a.y);
            put(x2 + a.x, y2 + a.y);
        }

enter image description here



Solution 1:[1]

When drawing simple 2-D shapes with high contrast, this is a common problem called aliasing (this also crops up in full 3D but is somewhat easier to handle there).

Suppose two nearby green spots have "true" positions of (1.9, 2.9) and (2.1, 3.1). In order to be rendered, they must eventually have integer coordinates (ignoring for now that D3D11 has ways of handling 0.5). If these spots are truncated, then their new positions will be (1.0, 2.0) and (2.0, 3.0). They were originally almost on the same pixel, but now they have been skewed further part!

A lot of work actually goes into old-school 2D games to prevent various artifacts due to this phenomenon. Sprites are constructed to be even factors of the most common screen resolutions, a fixed internal resolution can be used and then cropped and black-barred to render neatly at multiple resolutions and aspect ratios with one-to-one blitting, the entity movement speeds and camera motion are finely tuned to minimize the incidence of a sprite arriving at fractional pixel values, etc.

The easiest way to get a clean circle moving smoothly is to create a bitmap (in Paint or whatever) where every pixel is perfectly laid out, then blit that bitmap and translate it around the screen at even pixel increments, then you will have a perfectly clean animated circle. (Since you're using triangles here, just render the bitmap as a texture onto a quad with a color-key for alpha blending, and use orthographic projection of course).

A fun way to see how big games handle this is to analyze Super Mario World or Mario Maker with classic sprites in slow motion, frame by frame! You'll see how tediously orchestrated everything is. You can actually make Mario Maker-SMW-mode mess up and jitter by moving slowly and then jumping onto a spring. Springs cut your speed in half, which in the right situation can make a lot of things on screen jitter nastily!

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1