Проблемы с уф при использовании полупиксельных переводов - PullRequest
1 голос
/ 24 мая 2019

Я рендеринг 2 треугольников, чтобы сделать квадрат, используя один вызов отрисовки с GL_TRIANGLE_STRIP.

Я вычисляю положение и уф в шейдере с:

vec2 uv = vec2(gl_VertexID >> 1, gl_VertexID & 1);
vec2 position = uv * 333.0f;
float offset = 150.0f;
mat4 model = mat4(1.0f);
model[3][1] = offset;
gl_Position = projection * model * position;

проекция является регулярнойортографическая проекция, соответствующая размеру экрана.

В фрагментном шейдере я хочу нарисовать каждую первую строку пикселей синим цветом, а каждую вторую линию пикселей красным цветом.

int v = int(uv.y * 333.0f);
if (v % 2 == 0) {
    color = vec4(1.0f, 0.0f, 0.0f, 1.0f);
} else {
    color = vec4(0.0f, 0.0f, 1.0f, 1.0f);
}

Это работает нормальнооднако, если я использую смещение, которое даст мне субпиксельный перевод:

offset = 150.5f;

2 треугольника не получат соответствующие значения uv, как показано на этом рисунке:

2 neighboring triangles get different uv

Что я делаю не так?

1 Ответ

2 голосов
/ 24 мая 2019

Атрибут интерполяции выполняется только с конечной точностью.Это означает, что из-за ошибок округления даже разница в 1 ulp (единица-последнее место, т.е. наименее значащая цифра) может привести к тому, что результат будет округлен в другом направлении.Поскольку порядок операций в модуле аппаратной интерполяции может отличаться между двумя треугольниками, значения до округления могут немного отличаться.OpenGL не предоставляет никаких гарантий по этому поводу.Например, вы можете получить 1.499999 в верхнем треугольнике и 1.50000 в нижнем треугольнике.Следовательно, если вы добавите смещение 0.5, тогда 1.99999 будет округлено до 1.00000, а 2.000000 будет округлено до 2.00000.

Если для вас важны идеальные результаты, то я предлагаюВы вычисляете uv координаты вручную из gl_FragCoord.xy.В случае выровненного по оси прямоугольника, как в вашем примере, это просто сделать.

...