如何在 OpenGL/GLSL 中对特定颜色进行阈值处理

Posted

技术标签:

【中文标题】如何在 OpenGL/GLSL 中对特定颜色进行阈值处理【英文标题】:How to threshold a specific color in OpenGL/GLSL 【发布时间】:2014-07-20 11:54:35 【问题描述】:

我在 OpenGL 中制作了粒子轨迹效果。

诀窍是在屏幕上画一个半透明的矩形来逐渐淡化上一帧:

    ofSetColor(0,0,0,255*(1.0-persistence));
    ofFill();
    ofRect(0, 0, ofGetScreenWidth(), ofGetScreenHeight());

然后画出粒子(粗略):

    ofEnableBlendMode(OF_BLENDMODE_ADD);    
    ofEnablePointSprites();
    vbo.draw(GL_POINTS, 0, (int)points.size());
    ofDisablePointSprites();

问题是轨迹在纯黑色之前不会褪色,而是保持灰色。

我可以设置深灰色值的阈值,或者逐渐淡化它们,但最好的方法是什么? OpenGL混合功能/操作或着色器?速度是一个主要问题。

【问题讨论】:

您使用的是什么混合模式?如果您使用默认值,则可以尝试乘法或减法混合。 openframeworks.cc/documentation/graphics/… 我想你的意思是当我绘制透明矩形时。你能解释一下为什么你建议使用不同的混合模式吗?它会改变什么?我不记得 blendMode 是如何影响最终片段的。 我怀疑这是舍入错误,例如片段颜色变得像 0.01 一样小,乘以你的淡入淡出(比如 0.9)得到 0.09。但是当它被存储回一个字节时(使用常规的 RGBA8 帧缓冲区),它可能会被四舍五入到 0.01。 (实际值不正确;仅用于说明。)实际上乘法混合无济于事,但减法而不是乘法可能会奏效。 (当然要减去一些非黑色的东西:)) 【参考方案1】:

您需要使用浮点格式分配您的 fbo。

openFrameworks 示例目录中有一个示例显示了浮点格式和非浮点格式之间的区别,这似乎是您的问题 (examples/gl/fboTrailsExample)。

浮点格式分配:

ofFbo rgbaFboFloat;
rgbaFboFloat.allocate(400, 400, GL_RGBA32F_ARB);

然后在更新方法中你可以在rgbaFboFloat.begin();rgbaFboFloat.end();之间绘制fbo

最后,你在 draw 方法中绘制你的 fbo:rgbaFboFLoat.draw(0,0);

【讨论】:

谢谢,我很惭愧,因为我已经遇到并解决了这个问题,但是我没有正确记住解决方案。我所做的是在 main.cpp 中尝试 window.setGlutDisplayString("rgba double samples>=4"); 但没有成功(我虽然它会直接为屏幕创建一个浮动 fbo,但显然它做了一些不同的事情......)另外,当我尝试使用双 FBO 时,我忘记了在绘制 FBO 之前清除屏幕(ofBackground(0,0,0,0))(它做同样的事情,但有轨迹!)。也许你应该在你的回答中提醒一下。 我还想知道如何使用 OpenGL 对颜色进行阈值处理。这可能会更快,因为使用第二个 fbo 的成本很高。我打开了另一个标记为重复的question(但它似乎不是完全重复的)。 也许你可以使用片段着色器 这也需要一个 FBO。我正在考虑使用模板缓冲区的解决方案。

以上是关于如何在 OpenGL/GLSL 中对特定颜色进行阈值处理的主要内容,如果未能解决你的问题,请参考以下文章

更快的全屏渲染(OpenGL/glsl)?

OpenGL 3.+ glsl 兼容性一团糟?

模型,视图和投影矩阵不希望对opengl glsl有效

片段着色器不会在 OpenGL GLSL 中创建像光一样的渐变

带有 Assimp 的 OpenGL (GLSL) 中的骨骼动画

OpenGL / GLSL - 统一块数据值不正确