使用两个纹理的力量进行OpenGL后处理

时间:2018-12-28 17:29:40

标签: opengl-es glsl webgl shader

我试图在OpenGL ES中进行一些后期处理,因此为了安全起见,我决定使用两种纹理大小的幂。但是,源图像是矩形的,并不完全适合PoT纹理,因此我将其缩小并绘制到帧缓冲区中(不进行拉伸,稍后再讲),如下图所示: enter image description here

因此,纹理中有一个空白/空白区域,为黑色或我清除过的任何颜色。然后,这成为我使用的源纹理,然后我将其多次乒乓以应用效果。我试图勾勒出我认为将在图片中遇到的问题。基本上,当我使用从相邻像素采样的模糊或光晕之类的着色器时,边缘上的像素将从空白区域采样。如果我使用npot纹理或将其拉伸,CLAMP_TO_EDGE可以避免这种情况,但是我无法解决这种情况。这是我想出的一些想法:

  • 拉伸图像以填充整个纹理:我觉得某些着色器(如边缘检测等)可能会导致最终图像中拉伸轴和未拉伸轴的不平衡。我希望它适用于所有类型的着色器。我在这个假设上错了吗?
  • 尝试通过用源图像的边缘颜色填充空白区域来手动模拟CAMP_TO_EDGE:感觉很麻烦,必须在每个乒乓球步骤中完成。
  • 将纹理坐标固定在片段着色器中(例如,最大水平值为0.7):我认为这在着色器中会很重,尤其是在采样多个坐标时。

那么,有什么办法可以有效地做到这一点,例如将纹理坐标设置为边缘或其他东西?我知道NPoT纹理将使这一过程变得更加容易,但是我想首先探索PoT的选项。而且由于一开始甚至台式机GPU都不对NPoT友好,所以我觉得这必须是已经解决的问题,并且必须存在一些最佳实践。

1 个答案:

答案 0 :(得分:1)

在生成纹理的POT版本时,可以模拟钳位到边缘。

生成POT帧缓冲区时,不仅要渲染帧缓冲区中与原始纹理匹配的部分,还应渲染一些稍微过大的内容(例如,足够的额外像素来覆盖滤镜内核宽度)。如果在原始的NPOT纹理上使用CLAMP_TO_EDGE渲染此图像,则只需将原始纹理的边缘扩展到内核的溢出区域即可。

然后,您可以使用计划的坐标范围正常读取此内容,它应该就像在应用CLAMP_TO_EDGE的情况下读取原始纹理一样正常工作。即使夹具便宜,但我希望它会便宜...