是否可以在gl_FragColor中写入一堆像素?

时间:2013-07-12 14:45:03

标签: opengl opengl-es

有没有人熟悉某种 OpenGL魔法来摆脱计算片段着色器中的像素串而不是只有1?特别是这个问题对于OpenGL ES来说是个热点,实际上是有意义的缺陷移动平台,并且需要以更准确(在性能意义上)的方式处理它。

有任何结论或想法吗?

P.S。由于GPU架构组织是针对每个纹理单元并行运行的,因此已知着色器。但也许有技术可以将它从一个像素提升到一组像素或实现自己的glTexture组织。在GPU中可以通过这种方式更快地完成大量工作。

2 个答案:

答案 0 :(得分:4)

OpenGL不支持在着色器中写入多个片段,我认为这是有充分理由的。几乎在所有情况下它都会非常慢。正如您所提到的,GPU旨在设置数据并使用着色器并行处理它。我想如果GPU有足够的并行处理器,计算每个片段的时间只与最密集的单个片段一样长(显然在较小规模上使用基于图块的渲染器等)。添加某种条件覆盖会极大地减慢流程并消除管道! GPU几乎被迫放弃并行处理,因为它无法启动新的片段而不确定已经在进行的片段是否会覆盖它。

答案 1 :(得分:3)

首先,您可以计算OpenGL 3及更高版本中单个片段着色器的多个输出。帧缓冲对象可以连接多个RGBA表面(渲染缓冲对象),并使用gl_FragData [n]而不是gl_FragColor为每个表面生成RGBA。参见第5版OpenGL SuperBible的第8章。

但是,只能为每个缓冲区中相同的X,Y像素坐标生成多个输出。这是因为旧样式片段着色器只能生成一个输出,并且无法更改gl_FragCoord。 OpenGL保证在渲染任何基元时,只有一个片段着色器将写入目标帧缓冲区中的任何X,Y像素。

如果片段着色器可以在不同的X,Y坐标系上生成多个像素值,它可能会尝试写入与同一片段着色器的另一次执行相同的目标像素。如果片段着色器可以更改像素X或Y,则相同。这是尝试更新共享内存问题的经典多线程。

解决问题的一种方法是说“如果发生这种情况,结果是不可预测的”,这从程序员的角度来看很糟糕,因为它完全超出了你的控制范围。或片段着色器必须锁定他们正在更新的像素,这将使GPU变得更加复杂和昂贵,并且性能会很糟糕。或者片段着色器将以某种定义的顺序执行(例如,从左上角到右下角)而不是并行执行,这不需要锁定,但性能会更糟糕。