GLSL:用缓冲区或纹理替换大的均匀int数组 [英] GLSL: Replace large uniform int array with buffer or texture

查看:299
本文介绍了GLSL:用缓冲区或纹理替换大的均匀int数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

现在我试图传递一个int数组到片段着色器,并通过一个统一的数组:

Right now I am trying to pass an array of ints into the fragment shader, and am doing this through a uniform array:

uniform int myArray[300];

glUniform1iv

不幸的是,大于〜400 的统一数组失败。我理解我可以使用统一的缓冲区,但似乎找不到一个完整的例子传递一个大的1D数组到缓冲区或其他的片段着色器。

Unfortunately, uniform arrays larger than ~400 fail. I understand that I can use a "uniform buffer" instead, but can't seem to a find a full example of passing a large 1D array into a fragment shader with buffers or otherwise.

任何人都可以提供这样的例子?

Could anyone supply such an example?

推荐答案

这应该让你开始使用统一缓冲区对象来存储数组。请注意,GL要求UBO的最小容量为16 KiB,最大容量可以通过 GL_MAX_UNIFORM_BLOCK_SIZE 查询。

This should get you started using a Uniform Buffer Object to store an array. Note that GL requires UBOs to have a minimum capacity of 16 KiB, the maximum capacity can be queried through GL_MAX_UNIFORM_BLOCK_SIZE.

#version 140 // GL 3.1

// Arrays in a UBO must use a constant expression for their size.
const int MY_ARRAY_SIZE = 512;

// The name of the block is used for finding the index location only
layout (std140) uniform myArrayBlock {
  int myArray [MY_ARRAY_SIZE]; // This is the important name (in the shader).
};

void main (void) {
  gl_FragColor = vec4 ((float)myArray [0] * 0.1, vec3 (1.0));
}



OpenGL代码



OpenGL Code

const int MY_ARRAY_SIZE = 512;

GLuint myArrayUBO;
glGenBuffers (1, &myArrayUBO);

// Allocate storage for the UBO
glBindBuffer (GL_UNIFORM_BUFFER, myArrayUBO);
glBufferData (GL_UNIFORM_BUFFER, sizeof (GLint) * MY_ARRAY_SIZE,
              NULL, GL_DYNAMIC_DRAW);

[...]

// When you want to update the data in your UBO, you do it like you would any
//   other buffer object.
glBufferSubData (GL_UNIFORM_BUFFER, ...);

[...]

GLuint myArrayBlockIdx = glGetUniformBlockIndex (GLSLProgramID, "myArrayBlock");

glUniformBlockBinding (GLSLProgramID,     myArrayBlockIdx, 0);
glBindBufferBase      (GL_UNIFORM_BUFFER, 0,               myArrayUBO);

我可能忘记了一些东西,有一个原因我不写教程。

I am probably forgetting something, there is a reason I do not write tutorials. If you have any trouble implementing this, leave a comment.

请注意, 0 用于 glUniformBlockBinding(...) glBindBufferBase(...)为绑定点。当与 std140 布局结合使用时,这意味着您可以在任何GLSL程序中使用此UBO,其中将其一个统一块绑定到该绑定位置( 0 )。当你想在几十个不同的GLSL程序之间共享你的ModelView和Projection矩阵时,这是非常方便的。

Note that the 0 used in glUniformBlockBinding (...) and glBindBufferBase (...) is a global identifier for the binding point. When used in conjunction with the std140 layout, this means that you can use this UBO in any GLSL program where you bind one of its uniform blocks to that binding location (0). This is actually extremely handy when you want to share something like your ModelView and Projection matrices between dozens of different GLSL programs.

这篇关于GLSL:用缓冲区或纹理替换大的均匀int数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆