gl_PointSize 是如何工作的

Posted

技术标签:

【中文标题】gl_PointSize 是如何工作的【英文标题】:How does gl_PointSize work 【发布时间】:2015-08-24 22:55:42 【问题描述】:

来自 DX 背景,我试图准确理解 gl_PointSize 和 gl_PointCoord 的工作原理/方式。我在网上和手册页上搜索过,但对它们没有很好的解释。假设我有一个 300x300 的输出缓冲区,我定义了一个具有 90,000 个点的顶点着色器,对应于 300x300 缓冲区中的每个位置(每个维度的增量为 1)。现在在顶点着色器中,如果我将 gl_PointSize 定义为 2,它会调用片段着色器 90,000 次还是 360,000 次?如果是 360,000 次,我可以理解 gl_PointCoord 代表什么。但是如果只有 90,000 次,那是否意味着每个片段输出就代表 4 个像素?在这种情况下, gl_PointCoord 代表什么?不是一直都是 0.5,0.5 而不是真的有用吗??

谢谢

【问题讨论】:

【参考方案1】:

OpenGL 4.5 core profile specification 的第 14.4.1 节“基本点光栅化”声明:

点光栅化为每个帧缓冲区像素生成一个片段 其中心位于以该点 (xw; yw) 为中心的正方形内, 边长等于当前点的大小。

所以在点大小 > 1 的情况下,可能会生成几个片段。每个片段至少调用一次片段着色器。如果我们继续对图片进行多重采样,它会在每个片段中调用一次,因此正确答案是 360,000 次。

请注意,这也忽略了早期深度测试,它可能会或可能不会在您描述的场景中发挥作用,因为它可能会在调用 FS 之前丢弃片段。

来自规范的同一部分:

在栅格化点精灵时产生的所有片段都被分配 相同的关联数据,即对应的顶点的数据 点。但是,片段着色器内置gl_PointCoord 包含点精灵纹理坐标。 s 点精灵 纹理坐标跨点从零变化到一 水平从左到右。如果POINT_SPRITE_COORD_ORIGINLOWER_LEFT,t坐标垂直从零到一变化 自下而上。否则如果点精灵纹理坐标原点 是UPPER_LEFTt 坐标从零垂直变化到一 从上到下。 [...]

所以点坐标确实代表了您期望它代表的内容。请注意,此定义意味着即使点大小为 1 且未使用多重采样,点坐标也不一定总是以 0.5 结束。在这种情况下,为 像素中心 调用片段着色器,但该点可能不完全位于像素中心,因此您将看到您正在采样的 1x1 像素大点的确切位置。

【讨论】:

以上是关于gl_PointSize 是如何工作的的主要内容,如果未能解决你的问题,请参考以下文章

WebGL之点上添加图片(using texture on point)

使用 gl_PointSize 来扩大和缩小点

gl_PointSize 对应世界空间大小

解决 three.js / webGL 中的 gl_PointSize 限制

skopt BayesSearchCV 中的 n_points 是如何工作的?

在 Ruby 中, coerce() 是如何工作的?