gl_PointSize,gl_Position,gl_FragCoord之间的关系

时间:2019-01-31 09:13:50

标签: webgl2

示例 vs着色器

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

画布为1x5像素(宽度,高度)

片段着色器使用gl_FragCoord

这5个像素的gl_FragCoord值是什么?

欢呼

1 个答案:

答案 0 :(得分:0)

对于每个像素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像素)

当前正在绘制哪个像素取决于调用gl.drawArraysgl.drawElements时要求GPU执行的操作。

上面的顶点着色器(无输入更改)。假设您将gl.POINTS传递到gl.drawArrays,它将始终尝试在当前视口的中心向要绘制的内容绘制100x100像素的“点”。如果您通过了LINESTRIANGLES或其他任何操作,则不会绘制任何内容,因为着色器始终将gl_Position设置为vec4(0, 0, 0, 1),这将使长度为零的线或三角形大小为零。

对于POINTS,gl_Position从剪辑空间转换为绘图对象(画布或帧缓冲区)的像素空间。根据您将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)。