Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
OpenGL混合模式与着色器混合_Opengl_Shader_Fragment Shader - Fatal编程技术网

OpenGL混合模式与着色器混合

OpenGL混合模式与着色器混合,opengl,shader,fragment-shader,Opengl,Shader,Fragment Shader,我目前正在对OpenGL和着色器进行一些研究,但我似乎无法弄清楚使用glBlendMode混合或在着色器中编写自己的混合模式之间是否有任何根本区别 选择前者或后者的原因是什么?通过选择一个而不是另一个,是否存在性能瓶颈?或者这只是个人喜好的问题?与glBlendFunc的传统混合无法在着色器中复制。混合需要在修改目标帧缓冲区之前对其进行采样,这在当前硬件上是无法做到的 目前,您只能传递一种颜色,并从有限的混合模式选择中选择一种(glBlendFunc/glBlendEquation),在写入帧缓

我目前正在对OpenGL和着色器进行一些研究,但我似乎无法弄清楚使用
glBlendMode
混合或在着色器中编写自己的混合模式之间是否有任何根本区别


选择前者或后者的原因是什么?通过选择一个而不是另一个,是否存在性能瓶颈?或者这只是个人喜好的问题?

与glBlendFunc的传统混合无法在着色器中复制。混合需要在修改目标帧缓冲区之前对其进行采样,这在当前硬件上是无法做到的


目前,您只能传递一种颜色,并从有限的混合模式选择中选择一种(glBlendFunc/glBlendEquation),在写入帧缓冲区之前,GPU的光栅化器将应用该混合模式。

在我知道的三种情况下,可以从着色器中模拟OpenGL混合:

  • 使用Direct3D11或OpenGL等效工具,并将渲染目标绑定为像素着色器中的读写纹理。这可以实现任意复杂的混合操作,但在进行简单混合时不会有高性能,因为您正在绕过GPU的特殊硬件进行简单混合

  • 你有一个奇特的“基于瓷砖的”GPU,其中甚至简单的混合都是由“alpha着色器”完成的。在这种情况下,OpenGL中的简单混合和等效着色器代码之间没有性能差异。但不太可能有这样一个GPU,OpenGL也不会公开这个功能

  • 您避开了整个固定功能硬件光栅化管道,并编写了自己的复杂的“计算着色器”。如果您能够做到这一点,类似“alpha着色器”的东西将成为基于瓷砖的管道的一部分,但要达到这一点需要做大量工作,因此alpha混合将是您最不关心的问题


  • 当着色器在同时渲染到同一纹理时从纹理读取时,结果是未定义的。这就是为什么将“传统”或固定功能与glBlendFunc和glBlendEquation混合使用是有用的

    要使用传统混合方式混合两个图像,请渲染第一个图像,设置混合模式、函数和方程,然后渲染第二个图像。这保证会给出正确的结果,并且通常是实现透明效果的最快方法

    要使用着色器实现相同的效果,需要将第一个图像渲染为辅助纹理,更改着色器,并将第二个图像渲染为实际帧缓冲区,作为片段着色器中的最后一步进行混合。这通常较慢,因为额外的纹理读取开销,并且肯定会为辅助纹理使用更多的GPU内存


    在现代硬件上,这两种技术之间的差异往往很小。

    这实际上可以通过使用纹理屏障功能的gl 3.0扩展来实现:


    基本上,在写入背景后,可以使用TextureBarrierNV()函数确保刷新纹理,然后可以在单个着色器阶段执行读/写操作(确保避免多采样缓冲区,因为实际上只允许一次写入操作)

    1:更不用说,如果多个着色器调用访问同一像素,则必须处理显式同步访问。平铺光栅化的一个很好的方面是,像素之间通常不存在竞争条件。但是,如果你说的是1。那么是的,你是对的:在这种情况下,三角形光栅化连续完成的保证将被违反。这是否意味着着色器不能混合两个纹理并对它们应用混合模式,然后输出一个新纹理?如果人们在网上发布Photoshop混合模式着色器,我会觉得有点奇怪。你能详细说明一下吗?谢谢不,您仍然可以在着色器中混合两个纹理,但这不是混合的作用。混合将当前像素与帧缓冲区混合。您仍然可以通过其他方式(绘制纹理和混合)实现相同的效果@bartclaOk,如果我理解正确:通过
    glBlendFunc
    混合与在着色器中混合纹理完全不同吗?假设我想用“倍增”混合模式混合两张照片。这应该在着色器中完成,而不是使用
    glBlendFunc
    ?您能举一个使用
    glBlendFunc
    的例子吗?对于前两个问题,是的,这是正确的。只需对两种纹理进行采样,然后在着色器中将它们相乘。混合通常更多地用于透明度,例如,如果要绘制着色窗口。它适用于当您想要在已绘制的场景的其余部分上绘制透明的内容时@巴特克拉