GLSL有许多预定义的全局变量,例如gl_lightsource。它们是全局的,因为任何着色器都可以访问它们。
如何在GLSL中定义自定义全局变量?
答案 0 :(得分:5)
GLSL中不存在全局变量。 gl_*
变量是硬编码变量(将它们视为自动添加编译时),以从着色器访问管道的非可编程元素。在Core OpenGL 3.0中,大多数都被删除了,包括gl_LightSource
。现在希望用户处理他自己的矩阵和灯光并将它们作为制服发送到着色器。如果您想查看剩余的所有列表,请查看GLSL Reference Pages。
你想要的是制服。如果要在着色器之间同步制服,请存储制服的位置并遍历所有程序,以将制服上传到每个着色器。
答案 1 :(得分:3)
您可以使用统一缓冲区。这是一个教程:http://www.lighthouse3d.com/tutorials/glsl-tutorial/uniform-blocks/
答案 2 :(得分:1)
OpenGL中的全局着色器变量称为"制服"。它们是只读的,可以与glUniformX
个电话绑定。粗略地说,它看起来像这样(这更像是伪代码):
// 1. activate the program
glUseProgram(program)
// 2. get uniform location
foo = glGetUniformLocation(program, "foo")
// 3. bind the value, e.g. a single float
glUniform1f(foo, 42.0)
在着色器中,您需要使用uniform
存储限定符限定变量,例如
uniform float foo;
答案 3 :(得分:0)
持久变量的有用性肯定是有希望的。 OpenGL在gl3中引入了实例化,但实际上在gl4中对其进行了完全建模。该答案的目的是扩展其他答案,并提供有关实例化VBO的信息。
如果您可以访问gl4,则可以使实例化VBO加载的数据(如果是平铺地图)可以在每个绘制(而不是每个顶点)上更改。您可以利用GLSL变量gl_InstanceID
来检测正在进行的绘图调用。
在平铺地图的情况下,您使用一个模型(可能是2个三角形,即4个点,4个texcoords,6个索引来形成一个四边形)来渲染很多图块。您可以使用普通的gl缓冲区功能轻松地在CPU端更新所述VBO的值。 VBO可以保存诸如tileid之类的东西,它可以帮助您计算为指定图块索引该图块的纹理坐标。好处是它会按实例更新。
“在两次抽奖之间保存变量”的典型用例通常归结为需要计数器,而gl_InstanceID
绝对符合要求。除非您需要GPU做一些需要保存回去的事情。
如果要在GPU上进行计算,则UBO是从GLSL着色器获取数据或从GLSL着色器获取数据的一种非常好的方法。正如@Arne建议的那样。但是,可能有某种方法可以使用其他方法来完成您要尝试做的事情,除非您实际使用大量统一变量,否则应避免在一般情况下使用它们。
如果要定义常量变量,则可以使用const关键字。但是,这在着色器之间并不持久。仅在其上定义的着色器。
const float example = 5.0;