我有以下问题:我正在使用包含一组点的opengl绘制2D场景。每个点都是通过 XY 坐标指定的。我想使用标记符号 - 类似于三角形、十字形或四边形之类的东西来呈现点。问题是缩放场景时屏幕上的标记大小应该是恒定的 - 就像使用 GL_POINTS
.因此,每次更改比例时,我都必须重新计算标记坐标,这并不方便 - 我想在获得新的渲染点位置时执行此操作一次。有什么问题吗?
最简单的方法可能是使用符号设置纹理,然后使用点精灵绘制它们。如果您需要有关该方法的帮助,我的回答解释了如何使用点精灵:
在现代 OpenGL 中渲染大型圆形点
我想到的另一种方法是,在应用所有其他转换(包括投影(后,在顶点着色器中应用几何体的缩放。
立即想到的最好的方法是将每个顶点的两个属性传递到顶点着色器中:
- 标记的中心,对于一个标记的所有顶点都是相同的值。
- 与标记中心的相对偏移量。
然后在顶点着色器中,仅将所有常用变换(包括投影变换(应用于中心。然后添加相对偏移量。
勾勒出顶点着色器,它可能看起来像这样:
in vec3 centerPos;
in vec2 relativePos;
uniform mat4 ModelViewProj;
...
void main() {
...
vec4 projCenterPos = ModelViewProj * vec4(centerPos, 1.0);
gl_Position = vec4(
projCenterPos.xy + projCenterPos.w * relativePos,
projCenterPos.zw);
}
由于相对偏移是在投影之后应用的,因此您必须考虑到我们现在具有齐次坐标,其中 x
、 y
和 z
将除以 w
,作为顶点着色器之后固定函数处理的一部分。为了使大小在此透视除法后保持不变,上面的代码将偏移量乘以 w
。
由于relativePos
基本上应用于 NDC(规范化设备坐标(,其中 x 和 y 方向的范围为 [-1.0, 1.0],因此这些值必须相当小。例如,偏移量 0.02 对应于窗口大小的 1%。
如果希望大小调整更加灵活,可以传入另一个比例因子来控制精灵的大小,并在上面的计算中relativePos
乘以因子。然后,您可以将相对位置(例如(保持在 [-1.0, 1.0] 的范围内,然后适当地缩小它们:
...
uniform float spriteSize;
...
gl_Position = vec4(
projCenterPos.xy + spriteSize * projCenterPos.w * relativePos,
projCenterPos.zw);