Связь между gl_PointSize, gl_Position, gl_FragCoord - PullRequest
0 голосов
/ 31 января 2019

пример vs шейдера

void main() {
  gl_Position = vec4(0, 0, 0, 1);
  gl_PointSize = 100.0;
}

холст 1x5 пикселей (ширина, высота)

фрагментный шейдер использует gl_FragCoord

, каковы будут значения gl_FragCoordдля этих 5 пикселей?

ура

1 Ответ

0 голосов
/ 31 января 2019

Для каждого пикселя gl_FragCoord.xy будет

4.5, 0.5
3.5, 0.5
2.5, 0.5
1.5, 0.5
0.5, 0.5

gl_FragCoord всегда пиксель, который рисуется в данный момент .Ваш фрагментный шейдер будет вызываться 5 раз.Один раз для каждого из 5 пикселей покрывается точка размером 100x100 (она, конечно, обрезается до размера холста, размер которого, как вы сказали, составляет всего 1x5 пикселей)

Какие пиксели в настоящее время прорисовываются, зависит от того, что выпопросил GPU сделать, когда вы вызвали gl.drawArrays или gl.drawElements.

Вершинный шейдер выше, поскольку входы не меняются.Он всегда будет пытаться нарисовать «точку» размером 100x100 пикселей в центре текущего видового экрана к тому, что вы рисуете, предполагая, что вы передали gl.POINTS в gl.drawArrays.Если вы передали LINES или TRIANGLES или что-то еще, маловероятно, чтобы что-то рисовало, поскольку шейдер всегда устанавливает gl_Position в vec4(0, 0, 0, 1), что делает линию нулевой длины или треугольник нулевого размера.

В случае POINTS gl_Position преобразуется из пространства клипа в пространство пикселей объекта, на который вы рисуете (canvas или framebuffer).Это преобразование происходит на основе того, что вы установили gl.viewport в.

, как правило, вы установили gl.viewport в качестве размера холста.в этом случае

const x = 0;
const y = 0;
const width = 1;
const height = 5;
gl.viewport(x, y, width, height);

Преобразование из пространства клипов в пространство пикселей через настройку области просмотра получится с позицией 0,5, 2,5.Исходя из этой позиции пикселя, квадрат будет рассчитан на основе gl_PointSize

 gl_Position = vec4(0, 0, 0, 1);
 gl.viewport(0, 0, 1, 5);

 pixelPosition becomes 0.5, 2.5

 x1 = 0.5 - gl_PointSize / 2;
 y1 = 2.5 - gl_PointSize / 2;
 x2 = 0.5 + gl_PointSize / 2;
 y2 = 2.5 + gl_PointSize / 2;

. Это означает, что «ТОЧКА», которую вы просили нарисовать, идет от

 x1 = -49.5
 y1 = -47.5
 x2 = 50.5
 y2 = 52.5

Этот прямоугольник намного большечем холст 1x5, но он будет обрезан, что приведет к визуализации 5 пикселей холста.Для каждого пикселя в холсте вызывается фрагментный шейдер.gl_FragCoord - это координата пикселя, в данный момент рисуемого.Первый пиксель на холсте (внизу слева) всегда имеет gl_FragCoord.xy (0,5, 0,5).Пиксель один пиксель справа от этого всегда имеет gl_FragCoord.xy (1,5, 0,5).

...