将 uint 属性传递给 GLSL
Posted
技术标签:
【中文标题】将 uint 属性传递给 GLSL【英文标题】:Passing uint attribute to GLSL 【发布时间】:2013-09-20 14:59:38 【问题描述】:我正在尝试将一堆连续的无符号整数作为属性传递给我的 GLSL 着色器。
到目前为止,我想出了
s_number = glGetAttribLocation(shader, "number");
numberData = new GLuint[dotAmount];
for (GLuint i = 0; i < dotAmount; i++)
numberData[i] = i;
glGenBuffers(1, &vertBuf);
glBindBuffer(GL_ARRAY_BUFFER, vertBuf);
glBufferData(
GL_ARRAY_BUFFER,
sizeof(dotAmount),
numberData,
GL_STATIC_DRAW
);
渲染函数是
glUseProgram(shader);
[..]
glEnableVertexAttribArray(s_number);
glBindBuffer(GL_ARRAY_BUFFER, vertBuf);
glVertexAttribPointer(
s_number,
1,
GL_UNSIGNED_INT,
GL_FALSE,
0,
BUFFER_OFFSET(0)
);
glDrawArrays(GL_POINTS, 0, dotAmount);
我尝试像这样在顶点着色器中使用数字:
attribute uint number;
(名称“vertBuf”实际上有点误导,因为它不是我要传递的顶点数据) 我正在使用 OpenGL 3 和着色器版本 1.3。
我想要实现的是,我希望着色器被执行dotAmount
次。定位是在着色器中以数学方式完成的。但我得到的只是一个空白屏幕......
我很确定问题不在于着色器。我想画点,如果我把gl_Position = vec4(0.0, 0.0, 0.0, 0.0);
放在顶点着色器中,我认为它应该画一些东西。
【问题讨论】:
顺便说一句,如果你想要的只是一个从 0 到 dotAmount-1 的序列,你可以读取 gl_VertexID (opengl.org/sdk/docs/manglsl/xhtml/gl_VertexID.xml)。如果您迁移到 GLSL 1.4+,那么您可以使用实例渲染和 gl_InstanceID。 感谢您的提示,非常有用。 【参考方案1】:您使用了错误的 API 调用来指定您的顶点属性指针。
glVertexAttribPointer (...)
用于浮点顶点属性。它很乐意接受整数数据类型的值,但最终该值将转换为浮点数。这就是为什么它有一个参数来控制浮点归一化。启用规范化后,您传递的整数值会使用类型的范围进行调整,以使其适合规范化的浮点范围:[-1.0, 1.0]
(有符号)或[0.0, 1.0]
(无符号);禁用时,整数将被有效地视为已转换为 GLfloat
。
在您的情况下,您不需要上述任何行为。在您的顶点着色器中,您的顶点属性一开始就不是浮点类型,因此让 OpenGL 将您的顶点数组数据转换为浮点数将产生毫无意义的结果。
您需要做的是使用glVertexAttribIPointer (...)
。注意这个函数如何缺少用于标准化的布尔值?它会将您的整数顶点数据完全原封不动地传递给您的顶点着色器,这正是您想要的。
总结:
glVertexAttribPointer (...)
非常适合为浮点顶点属性(即vec<N>
、mat4
、float
)提供数据,并且会为您进行数据类型转换。
glVertexAttribIPointer (...)
专为整数属性而设计(即ivec<N>
、uint
)。
【讨论】:
这对问题无关紧要,但这是一个非常好的信息! 这对我很有帮助! 我只是想花一点时间来表达我对你的爱。这个答案解决了我所有的问题。 非常好的答案,这对我很有帮助【参考方案2】:尝试将片段着色器更改为gl_FragColor = vec4(1,0,0,1);
这将确保输出颜色使片段可见。
另外,你应该有gl_Position = vec4(0, 0, 0, 1);
(原因是gl_Position必须在齐次坐标中,这意味着前三个分量将被第四个除。)
【讨论】:
gl_Position
不设置颜色,而是设置剪辑空间位置。但是,您的点仍然有效,因为 (0.0, 0.0, 0.0, 0.0) 处的剪辑空间点会导致除以零和未定义的 NDC/屏幕坐标。以上是关于将 uint 属性传递给 GLSL的主要内容,如果未能解决你的问题,请参考以下文章