OpenGL亮度到颜色映射?

Posted

技术标签:

【中文标题】OpenGL亮度到颜色映射?【英文标题】:OpenGL luminance to color mapping? 【发布时间】:2013-06-14 01:53:14 【问题描述】:

我想知道是否有一种方法可以处理 OpenGL 纹理缓冲区,以便通过我选择的某些公式将灰度值缓冲区动态转换为 rgb 值。

我已经有一个类似的函数,它运行良好但输出一个颜色为 3 的向量。

rgb convertToColor(float value);

我对 OpenGL 很陌生,想知道我应该使用哪种着色器以及它应该去哪里。我的程序目前这样循环帧:

program1.bind();
program1.setUniformValue("texture", 0);
program1.enableAttributeArray(vertexAttr1);
program1.enableAttributeArray(vertexTexr1);
program1.setAttributeArray(vertexAttr1, vertices.constData());
program1.setAttributeArray(vertexTexr1, texCoords.constData());
glBindTexture(GL_TEXTURE_2D, textures[0]);
glTexSubImage2D(GL_TEXTURE_2D,0,0,0,widthGL,heightGL, GL_LUMINANCE,GL_UNSIGNED_BYTE, &displayBuff[displayStart]);
glDrawArrays(GL_TRIANGLES, 0, vertices.size());
glBindTexture(GL_TEXTURE_2D,0);
//...

着色器

QGLShader *fshader1 = new QGLShader(QGLShader::Fragment, this);
    const char *fsrc1 =
        "uniform sampler2D texture;\n"
        "varying mediump vec4 texc;\n"
        "void main(void)\n"
        "\n"
        "    gl_FragColor = texture2D(texture, texc.st);\n"
        "\n";

我正在尝试在 matlab 中重新创建类似 imagesc 的效果,如下图所示:

【问题讨论】:

【参考方案1】:

这样的事情会起作用:

    "uniform sampler2D texture;\n"
    "uniform sampler1D mappingTexture;\n"
    "varying mediump vec4 texc;\n"
    "void main(void)\n"
    "\n"
    "    gl_FragColor = texture1D(mappingTexture, texture2D(texture, texc.st).s);\n"
    "\n";

其中映射纹理是将灰度映射到颜色的一维纹理。

当然,您也可以编写基于灰度计算 rgb 颜色的函数,但是(取决于您的硬件)仅进行纹理查找可能会更快。

不清楚如何一次将两个缓冲区绑定到 OpenGL 程序

Binding textures to samplers.

【讨论】:

这是一个很好的答案,但我发现学习曲线非常陡峭。 @Mikhail:尝试阅读所谓的“OpenGL 橙皮书”->“OpenGL 着色语言第 3 版”。这应该可以帮助您更好地理解着色器。 例如,不清楚如何一次将两个缓冲区绑定到 OpenGL 程序。 @Mikhail: opengl.org/wiki/GLSL_Sampler#Binding_textures_to_samplers 。用谷歌搜索不到一分钟就找到了。 我想我们都明白 OpenGL 的学习曲线非常陡峭,而且概念很深奥。【参考方案2】:

看起来您已经加载并设置了一个程序来读取纹理(代码中的 program1)。假设顶点着色器已经设置为传递像素着色器纹理坐标以查找纹理(在下面的程序中这是“texcoord”),您应该能够将像素着色器更改为如下所示:

uniform texture2d texture;   // this is the greyscale texture
varying vec2 texcoord;       // passed from your vertex shader

void main() 
  
    float luminance = tex2D(texture, texcoord).r;     // grab luminance texture
    gl_FragColor = convertToColor(luminance);         // run your function

这会读取亮度纹理并调用将亮度转换为颜色的函数。如果您的函数只返回一个 3 分量 rgb 向量,您可以将最后一行更改为:

gl_FragColor = vec4(convertToColor(luminance), 1.0);

【讨论】:

以上是关于OpenGL亮度到颜色映射?的主要内容,如果未能解决你的问题,请参考以下文章

亮度滤波器opengl中的多彩噪声

如何将元素映射到 OpenGL VBO 中的颜色?

在OpenGL中将纹理映射到VBO的问题

OpenGL学习脚印:伽马校正(Gamma Correction)

OpenGL:渲染到 FBO 时是不是支持纹理组合器功能?

opengl纹理