GLSL 全局变量
GLSL 有许多预定义的全局变量,例如 gl_LightSource
。它们是全局的,因为任何着色器都可以访问它们。
如何在 GLSL 中定义自定义全局变量?
GLSL has many global variables that are predefined such as gl_LightSource
. They are global because any shader can access them.
How do I define custom global variables in GLSL?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
GLSL 中不存在全局变量。
gl_*
变量是硬编码变量(将它们视为自动添加的编译时),用于从着色器访问管道的不可编程元素。在 Core OpenGL 3.0 中,其中大部分已被删除,包括gl_LightSource
。现在,用户需要处理自己的矩阵和灯光,并将它们作为制服发送到着色器。如需完整列表,请参阅内置变量 (GLSL) 维基百科。你想要的是制服。如果要在着色器之间同步制服,请存储制服的位置并迭代所有程序以将制服上传到每个着色器。
Global variables don't exist in GLSL. The
gl_*
variables are hardcoded variables (think of them as automatically added compile-time) to access non-programmable elements of the pipeline from a shader. In Core OpenGL 3.0 most of them were removed, includinggl_LightSource
. The user is now expected to handle his own matrices and lights and send them to the shaders as uniforms. For a complete list, see the Built-in Variable (GLSL) wiki.What you want are uniforms. If you want to synchronize uniforms between shaders, store the location of the uniform and iterate through all your programs to upload the uniform to each shader.
您可以使用统一缓冲区。这是一个教程: http://www.lighthouse3d.com/tutorials/glsl -教程/统一块/
You can use uniform buffers. Here is a tutorial: http://www.lighthouse3d.com/tutorials/glsl-tutorial/uniform-blocks/
OpenGL 中的全局着色器变量称为“uniform”。它们是只读的,可以与
glUniformX
调用。粗略地说,它看起来像这样(这更像是伪代码):
在着色器中,您需要使用
uniform
存储限定符来限定变量,例如Global shader variables in OpenGL are called "uniforms". They're read-only and can be bound with
glUniformX
calls. Roughly, it looks like this (this is more of a pseudocode):Within the shaders, you need to qualify the variable with
uniform
storage qualifier, e.g.持久变量的实用性绝对是值得追求的。 OpenGL 在 gl3 中引入了实例化,但实际上是在 gl4 中完全建模的。此答案的目的是扩展其他答案并提供有关实例 VBO 的信息。
如果您有权访问 gl4,则可以保留一个实例化的 VBO,其中加载的数据可以在每次绘制(而不是每个顶点)时更改(如果它用于平铺地图等内容)。您可以利用 GLSL 变量
gl_InstanceID
来检测您正在进行哪个绘制调用。对于平铺地图,您可以使用一个模型(可能是 2 个三角形,即 4 个点、4 个纹理坐标、6 个索引来形成一个四边形)来渲染大量平铺。您可以使用普通的 gl 缓冲区函数轻松地在 cpu 端更新所述 VBO 的值。 VBO 可以保存类似于tileid 的内容,它可以帮助您计算索引指定图块的图块表的纹理坐标。好处是它会根据实例进行更新。
“在绘制之间保存变量”的典型用例通常归结为需要一个计数器,而
gl_InstanceID
绝对符合要求。除非您需要 GPU 执行需要保存的操作。如果您想要在 GPU 上进行计算,UBO 是一种从 GLSL 着色器获取数据或从 GLSL 着色器获取数据的好方法。正如@Arne 所建议的。但是,可能有某种方法使用其他方法来完成您想要做的事情,并且在一般使用中应该避免它们,除非您实际上使用了很多统一变量。
如果您尝试定义常量变量,可以使用 const 关键字。但是,这在着色器之间不会持续存在。仅定义它的着色器。
The usefulness of persistent variables is definitely something to aspire. OpenGL introduced instancing as part of the gl3, but was actually fully modeled in gl4. This answer's intent is to expand on the other answers as well as inform about instanced VBOs.
If you have access to gl4, you can keep an instanced VBO loaded with data that can change per draw (as opposed to per vertex) if its for something such as a tiled map. You can utilize the GLSL variable
gl_InstanceID
to detect which draw call you are on.In the case of a tiled map, you use one model (probably 2 triangles aka 4 points, 4 texcoords, 6 indices to form a quad) to render a lot of tiles. You can update the values of said VBO easily cpu-side using normal gl buffer functions. The VBO can hold something like the tileid, which helps you calculate the texture coordinates indexing the tilesheet for the specified tile. The benefit is it updates per instance.
The typical use case of 'saving variables between draws' usually comes down to needing a counter, and
gl_InstanceID
definitely fits the bill. That is unless you need the GPU to do something that needs to be saved back.If what you are after is calculating on the GPU, UBOs are a very nice way to get data to and from the GLSL shader. As @Arne suggested. However, there may be some way using other means to do what you are trying to do and they should be avoided in general use unless you actually use a lot of uniform variables.
If you are trying to define a constant variable, you can use the const keyword. However, this doesn't persist between shaders. Only the shader it is defined on.