【问题标题】:How to keep track of 'highlights' in OpenGL Image Viewer如何在 OpenGL 图像查看器中跟踪“亮点”
【发布时间】:2019-07-15 03:40:03
【问题描述】:

我正在想办法为我的 OpenGL 图像查看器实现“突出显示”功能。这个想法是我希望用户能够点击图像来突出显示一个区域,到目前为止这已经很顺利了。我面临的问题是用户第二次点击时。我想在放置它们的图像上保留两个高光渲染。在第二次点击到达的那一刻,第一个亮点消失了。

这是我当前的片段着色器:

precision mediump float;
uniform vec4 vColor;
varying vec2 v_TexCoordinate;
uniform sampler2D u_Image;
uniform float u_touchX;
uniform float u_touchY;

void main() {

    float radius = 0.1;
    float a = v_TexCoordinate.x - u_touchX;
    float b = v_TexCoordinate.y - u_touchY;
    float d = sqrt(abs(a*a + b*b));

    if(d < radius){
        gl_FragColor = texture2D(u_Image, v_TexCoordinate) + vColor;
    }else{
        gl_FragColor = texture2D(u_Image, v_TexCoordinate);
    }
}

相当简单,我传入图像、突出显示颜色以及用户点击屏幕位置的 x 和 y。如果片段在该点的一定距离内,我会添加高光。到目前为止效果很好。

但很明显,一旦该接触点移动,原来的高光就消失了。

我的目标是让这个功能尽可能多地运行在 GPU 端。

到目前为止,我有一些想法,但我希望比我更聪明的人能告诉我一个更好的方法来做到这一点。

  1. 我最不喜欢的策略是跟踪 CPU 端的 XY 接触点,并在每一帧传递更新的列表。这里明显的缺陷是,触摸列表可以快速获得大量的快速屠宰性能。我希望用户能够根据需要突出显示整个图像,而这种解决方案似乎并不实用。
  2. 在 CPU 上跟踪图像中每个像素的状态。我想我可以通过创建一个位图(或者可能是一个代表每个像素的 2D bool 数组)图像的确切大小并跟踪哪个片段被“突出显示”来做到这一点。然后,将整个数组作为统一传递,并将每个 v_TexCoordinate 与数组中的相应值进行比较。我也不喜欢这个想法(尽管它比 #1 更好),因为它再次需要将大量数据洗牌到 GPU 每一帧。在旧的 Android 设备上,这很容易无法启动。
  3. 我遇到了here 对类似问题的回答。提问者想要操纵纹理数据,答案建议在使用 FBO 的地方使用“渲染到纹理”方法。我有点明白这个想法,但我真的不明白这将如何解决记住以前的“亮点”的问题。也许我很愚蠢,错过了这个答案可以告诉我的一些东西,但是......¯\_(ツ)_/¯

必须有更好的方法,但我目前是空的,我希望有人能指出我正确的方向。

【问题讨论】:

  • 不相关,但您可能应该将距离检查从sqrt( abs( a * a + b * b ) &lt; d 更改为abs( a * a + b * b ) &lt; d * d,因为这样可以提高性能,因为您可以避免使用sqrt。不过,驱动程序可能已经在优化它。如果可以,请避免使用条件语句。

标签: android opengl-es


【解决方案1】:

如果您的高光只是加法,则创建第二个纹理并将高光区域渲染到其中。只需在底层上使用添加剂混合来渲染它。尝试在 GLSL 中创建高亮区域的数据库可能要容易得多。

【讨论】:

  • 我花了几个星期才开始工作,但这个解决方案最终是正确的。谢谢!
猜你喜欢
  • 1970-01-01
  • 2015-08-20
  • 2011-12-14
  • 1970-01-01
  • 2011-04-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-05
  • 1970-01-01
相关资源
最近更新 更多