OpenGL:将随机位置传递给顶点着色器

Posted

技术标签:

【中文标题】OpenGL:将随机位置传递给顶点着色器【英文标题】:OpenGL: Passing random positions to the Vertex Shader 【发布时间】:2014-08-22 00:16:40 【问题描述】:

我开始学习 OpenGL (3.3+),现在我正在尝试做一个在屏幕上随机绘制 10000 个点的算法。 问题是我不知道在哪里做算法。由于它们是随机的,我不能在 VBO 上声明它们(或者我可以吗?),所以我正在考虑将统一值传递给具有不同位置的顶点着色器(我会做一个循环来改变统一值)。然后我会做 10000 次操作。我还会将随机颜色值传递给着色器。

这是我的想法:

#version 330 core

uniform vec3 random_position;
uniform vec3 random_color;

out vec3 Color;

void main() 
    gl_Position = random_position;
    Color = random_color;

通过这种方式,我会在着色器之外进行计算,然后将它们传递给制服,但我认为更好的方法是在顶点着色器中进行计算。那是对的吗?

【问题讨论】:

嗯,您仍然需要绘制一些东西才能执行顶点着色器。所以我想你总是可以绘制相同的对象(也许只是一个点?)来让 VS 运行,然后使用随机位置。这样做你基本上可以通过统一的 var 更新来交换 VBO 更新。 在主循环中,我会执行 glDrawArrays(GL_POINTS, 0, 1) 之类的操作,并对使用统一变量更新的每个随机位置执行此操作 是的,这可能会起作用,但我怀疑它会比更新 VBO 更快,因为大量的绘制调用和统一的 var 更新...... 如何更新 vbo?抱歉这个菜鸟问题 glBufferSubData 【参考方案1】:

将为您传递到顶点着色器阶段的每个顶点调用顶点着色器。每个电话的制服都是一样的。因此,您不应该将顶点(无论它们是否随机)作为制服传递。如果您有全局变换(即相机旋转、模型矩阵等),它们将进入制服。

您的顶点应作为顶点缓冲区对象传递。只需在您的主机应用程序中随机生成它们并绘制它们。将自动成为着色器的 in 变量。

您可以在每次迭代中更改数组,但是保持大小不变​​可能是个好主意。为此,有时传递一个 4 维的 3D 向量很有用,如果使用顶点,则为 1,否则为 0。这样你就可以简单地检查一个顶点是否应该被绘制。

然后在更新屏幕之前清除GL_COLOR_BUFFER_BIT并绘制数组。

在您的着色器中,只需使用您的 in 变量(即顶点)设置 gl_Position 并将颜色传递给片段着色器 - 它还不会应用于顶点着色器。

在片段着色器中,最后设置的变量将是颜色。因此,只需使用您从顶点着色器传递的变量,例如gl_FragColor.

顺便说一句,如果你把东西画成GL_POINTS,它会产生小方块。有很多技巧可以使它们真正变圆,最容易使用的可能是在片段着色器中使用这个简单的if。但是,您应该将它们配置为点精灵 (glEnable(GL_POINT_SPRITE))。

if(dot(gl_PointCoord - vec2(0.5,0.5), gl_PointCoord - vec2(0.5,0.5)) > 0.25) 
    discard;

我建议您阅读一下片段和顶点着色器的作用、顶点和片段是什么以及它们各自的输入/输出/统一变量代表什么。

由于具有完整顶点缓冲区对象的程序、着色器程序等变得非常庞大,您也可以从glBegin()glEnd() 开始直接绘制顶点。然而,这应该只是一个非常早的起点,以便了解您在哪里绘制什么以及不同的着色器如何影响它。

lighthouse3d 教程 (http://www.lighthouse3d.com/tutorials/) 通常是一个好的开始,尽管它们可能有点过时。 glsl wiki (http://www.opengl.org/wiki/Vertex_Shader) 也是一个很好的参考,它在大多数情况下都是最新的——但它可能有点技术性。 无论您使用的是 C++、Java 还是其他语言 - OpenGL 的概念通常都是相同的,因此几乎所有教程都可以。

【讨论】:

谢谢,我真正的问题是使用制服是否是个好主意。

以上是关于OpenGL:将随机位置传递给顶点着色器的主要内容,如果未能解决你的问题,请参考以下文章

将属性传递给 OpenGL 顶点着色器的行为很奇怪

OpenGL着色器没有将变量从顶点传递到片段着色器

OpenGL:如何将多个纹理传递给具有一个变量的着色器?

顶点纹理获取(在顶点着色器中读取纹理)

如何在 OpenGL ES 2.0 中将视图/模型/投影矩阵传递给我的顶点着色器?

OpenGL重叠顶点属性