【问题标题】:Pass texture with float values to shader将具有浮点值的纹理传递给着色器
【发布时间】:2017-12-27 15:51:37
【问题描述】:

我正在使用 QT QML 3D 中的 C++ 开发应用程序。我需要将数十个浮点值(或浮点数的向量)传递给片段着色器。这些值是灯光的位置和颜色,所以我需要的值范围大于 0.0 到 1.0。但是,不支持将浮点数或整数数组传递给 QML 中的着色器。我的想法是将浮点数保存到纹理中,将纹理传递给着色器并从中获取值。

我尝试过这样的事情:

float array [4] = {100.5, 60.05, 63.013, 0.0};
uchar data [sizeof array * sizeof(float)];
memcpy(data, &array, sizeof array * sizeof(float));
QImage img(data, 4, 1, QImage::Format_ARGB32);

并将此 QImage 作为 sampler2D 传递给片段着色器。但是有没有像 memcpy 这样的方法从 GLSL 中的纹理中获取值? texelFetch 方法只返回 vec4,浮点数范围为 0.0 到 1.0。那么如何从着色器中的纹理中获取原始值? 我更喜欢使用 sampler2D 类型,但是在 GLSL 中是否还有其他类型支持直接内存访问?

【问题讨论】:

  • 这并不能解决我的问题。创建具有正确浮点值的 QImage 没有任何问题。我在着色器(在 GLSL 中)中访问这些值时遇到问题。

标签: c++ qt opengl qml glsl


【解决方案1】:

纹理访问函数do直接从纹理中读取。问题是Format_ARGB32 不是 32 位每个通道每像素 32 位。从this documentation page 看来,QImage 不能 创建浮点图像似乎很清楚;它只处理标准化格式。 QImage 本身似乎是一个用于处理 GUI 问题的类,而不是用于加载 OpenGL 图像。

您将不得不放弃 Qt 图像快捷方式并直接使用 OpenGL。

【讨论】:

  • 当我像上面那样创建 QImage 时,值保存在那里,但不是按像素组织的。所以这就是为什么我需要一些像 GLSL 中的 memcpy 这样的函数,它不会访问每个像素或纹素的纹理,而只是将字节复制到任何数组。有这样的功能吗?
  • @david:按像素组织的。只是 Qt 将这些像素解释为每通道 8 位的归一化整数,而不是每通道 32 位的浮点数。 OpenGL 可以完全满足您的需求;只需正确地使用它
【解决方案2】:

这将从浮点数组创建一个浮点纹理。

glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, width, height, 0, GL_RED, GL_FLOAT, &array);

您可以像这样从片段着色器访问浮点值:

uniform sampler2D float_texture;

...

float float_texel = float( texture2D(float_texture, tex_coords.xy) );

“OpenGL 浮动纹理”是一个有据可查的主题。 What exactly is a floating point texture?

【讨论】:

  • 您好,您能否就如何访问片段着色器中的值 展开您的回答?对我来说,这似乎适用于我在这里描述的问题:stackoverflow.com/questions/45301962/…
  • 当我使用 glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, width, height, 0, GL_RED, GL_FLOAT, &array);我必须像这样将创建的纹理传递给着色器: GLuint texture_sampler_loc = glGetUniformLocation(shaderprogram, "texture"); glUniform1f(texture_sampler_loc, 1);但是在 QML 中我无法获得指向着色器程序的指针。或者有没有其他方法可以将纹理传递给着色器?
猜你喜欢
  • 2018-08-29
  • 1970-01-01
  • 2014-06-25
  • 1970-01-01
  • 2016-12-20
  • 1970-01-01
  • 2015-11-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多