opengl 1D 纹理:用任意浮点值填充

opengl 1D texture: fill with arbitrary float values

本文关键字:填充 任意浮 1D 纹理 opengl      更新时间:2023-10-16

所以,我正在努力处理1D纹理。我试图实现的是将 3 个浮点值作为uniform传递给片段着色器。它们表示光源的颜色,以尝试对n光源重复使用相同的着色器,并将其所有信息(颜色和位置)存储在纹理中。现在,我正在尝试只传递单个光源的颜色来测试内容。所以在片段着色器中,我有这个:

uniform sampler1D lightColor;
...
vec3 lc = vec3(texelFetch(lightColor, 0, 0)); // all zeroes
vec3 lc = vec3(texture(lightColor, 0, 0));    // same

我试图在着色器(一个或另一个)中使用texelFetchtexture调用来实现它,在这两种情况下都无济于事。请注意,如果我像这样对着色器中的值进行硬编码:

vec3 lc = vec3(0.0f, 0.0f, 0.8f);

然后我得到了预期的结果(lc中的非零值),所以我肯定,至少在着色器中,问题可能出在texelFetchtexture调用中。

回到C++,代码(在我的lightManager初始化时执行一次)如下:

GLfloat lightValues[] = { 0.8f, 0.8f, 0.8f };
GLuint lightID; // member, not a local variable.
glGenTextures(1, &lightID);
glBindTexture(GL_TEXTURE_1D, lightID);
glActiveTexture(GL_TEXTURE0 + lightID);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexStorage1D(GL_TEXTURE_1D, 1, GL_RGB32F, 1);
glTexSubImage1D(GL_TEXTURE_1D, 0, 0, 3 * sizeof(GLfloat), GL_RGB, GL_FLOAT, lightValues);
glUniform1i(glGetUniformLocation(shader->program, "light"), lightID);

这里没有什么特别花哨的(虽然绝对是错误的)。在浏览了 OpenGL 文档的表 6.2 后,glTexStorage1D我选择了 1 表示levels(没有 MipMaps),GL_RGB32F用于internalFormat(因为我正在尝试传递 3 个浮点数)。width为 1,因为只有一个值。这应该照顾到分配。

现在,继续用glTexSubImage1D填充缓冲区,为此我选择level0(再次,没有MipMaps),0表示xoffset,宽度为GLfloat大小的三倍,GL_RGB作为格式,GLfloat作为type。最后是实际数据。

关于 c++ 代码的一些事情:我正确地将过滤器设置为GL_NEAREST(所以这不是罪魁祸首),我会说与 sader 的统一位置/连接是正确的(通过glUniform1iglGetUniformLocation)。

所以我的问题来了:

  • 首先,很明显,通过纹理传递灯光信息是否有意义?着色器公然无法做像lights[n]这样的事情,因为n需要在编译时知道,所以纹理自然而然地成为欺骗它的一种方式。
  • 其次,我的假设是否正确,即数据的大小可能是罪魁祸首?我读过关于纹理完整性的文章,但说实话,它相当简短。不过,1 纹素的大小闻起来肯定有鱼腥味。
  • 第三,你觉得还有什么不对劲的地方吗?特别是internalFormatformattype
  • 第四,为什么lc总是用零填充

谢谢!!

编辑:我不想使用多次传递等技术,也不想对传递给着色器的光源数量定义硬限制(使n恒定)。我也读过OpenGL 4.2中的一些功能,我相信,这对我来说也不感兴趣。我只是想用手头的工具学习(但将来可以 100% 保证,一旦我弄清楚了这一点,我会回来询问有关这些主题的问题(:)

好的,和 https://stackoverflow.com/users/1774414/raistmaj 一起想通

了事实证明,widthglTexStorageglTexSubImage数组中的元素数量,因此为 1,无论组件的数量如何。

另外,glActiveTexture必须在glBindTexture之前调用(呃!!!