最近,根据《OpenGL 编程指南,第 8 版》一书,我使用 OpenGL 实现了一个与顺序无关的透明着色器。 但是我发现有混合错误:
经过一番思考,我意识到错误来自哪里:
首先,物体分为两类:不透明的和透明的。然后我们直接渲染不透明的。接下来,我们将透明的渲染到链表中。最后,链表上的片段与屏幕上的片段混合在一起。
错误发生在最后一步(混合)。假设混合函数是
blend(src, dst)
。我目前的解决方案是做
opaque_color = blend(..., blend(opaque_frag_2, blend(opaque_frag_1, blend(opaque_frag_0, clear_color_opaque))))
,然后做
transparent_color = blend(..., blend(transparent_frag_2, blend(transparent_frag_1, blend(transparent_frag_0, clear_color_transparent))))
.
最后,我将透明物体颜色与不透明物体颜色混合
final_color = blend(transparent_color, opaque_color)
。
这是不正确的,因为 blend
函数不满足关联属性。因此,天空的颜色会渗入树叶(如红圈所示)。
目前,我已经找到了避免这种情况的方法。即首先将不透明对象渲染到帧缓冲区中,并使用帧缓冲区的颜色作为背景颜色来混合链表中的片段。但是,这需要打开一个额外的帧缓冲区。我的问题是:除了分配一个framebuffer(比如修改blending函数)还有其他方法吗?