在两个单独的着色器程序之间共享混合和Z缓冲区?

野蛮人

我有2个着色器程序-一个用于渲染带有纹理的精灵,第二个用于渲染多边形。我已经启用了混合和Z缓冲区,如下所示:

GLES20.glEnable(GLES20.GL_BLEND);
GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE_MINUS_SRC_ALPHA);

GLES20.glEnable( GLES20.GL_DEPTH_TEST );
GLES20.glDepthFunc( GLES20.GL_LEQUAL );
GLES20.glDepthMask( true ); 
GLES20.glDepthRangef(0,  maxZDepth); //maxZDepth = 100f;

我的渲染包括2个渲染调用(glDrawElements):一个用于精灵,一个紧随其后用于具有足够着色器程序的多边形...将对象数据(顶点等)发送到着色器的顺序是从对象的最低位开始排序的Z值最高,我还必须将这样的指令添加到我的精灵的着色器中:

if(gl_FragColor.a == 0.0)
    discard;

现在,混合和Z缓冲区可以正常工作,但一次只能在一个着色器的范围内。由第一个着色器绘制的对象的混合似乎与第二个着色器无关……这是一个示例:

在此处输入图片说明

此处的精灵比其下方的棕色多边形具有更高的Z值,这就是为什么它在多边形上绘制但混合失败的原因,并且您可以看到精灵周围显示的灰色背景(由glClearColor创建)...

有人知道这个问题有好的解决方案吗?我考虑过将2个着色器程序合并为一个,然后我希望可以解决这个问题只有1个渲染调用,但我宁愿为精灵和多边形保留2个单独的着色器程序...

汤米

根据简短的评论讨论,问题是:

深度缓冲区每个像素仅保留一个深度。部分透明的像素组合了来自不同深度的两种颜色。但是只能分配一个深度。最后就是较近像素的深度。

在理想的世界中,如果您绘制的东西远且不透明,则绘制的东西远近且透明,然后在中间的物体又不透明,则最终输出将是介于中间的物体和接近的物体的混合。实际发生的是透明的事物将其深度设置为深度缓冲区。当您在物体之间绘制物体时,将不会输出任何像素,因为它比深度缓冲区中最近的物体更远。因此,您最终会把遥远的事物与临近的事物混合在一起,好像从未画过中间的事物一样。

有很多解决方案,取决于您要达到的严格精度,多少几何(至少部分是透明的)和多少时间。

首先,如果您有任何绝对不透明的几何图形,则可以首先以最有效的顺序绘制所有几何图形。

最明显的解决方案是对透明几何图形进行排序并从背面渲染。那很棒,除了不能仅通过回到最前面就可以正确绘制所有几何图形(例如参见相互重叠),而且在最幼稚的实现中,GL状态更改最终可能会变得非常昂贵,而不是用一个着色器绘制50,000个三角形,然后每秒切换并绘制50,000,您就为99,999个开关绘制了三角形,开关,绘制,开关,绘制等。

如果可以接受附加透明性,那么您可以按任何旧顺序填充透明材料,而无需写入深度缓冲区。

英伟达(Nvidia)提出的一些东西正在利用多重采样的优势,但可能会稍微提高一点。想象更像是为每个像素组合了8x8或16x16像素样本。在那种情况下,绘制透明度不是通过从帧缓冲区读取,混合并再次写出来实现的,而是如果透明度为50%,则只需在每个单元格中仅写入例如一半的样本。您随机选择一半。当您增加像元大小时,可以提高质量,从而获得与订单无关的透明性。

假设您的多边形始终是不透明的,并且所有子图形都可能是部分透明的,那么,就像我现在正在做的那样,首先绘制多边形,然后以从前到后的顺序绘制子图形。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

在两个单独的着色器程序之间共享混合和Z缓冲区?

来自分类Dev

深度缓冲区不适用于多个着色器程序

来自分类Dev

从片段着色器访问深度缓冲区

来自分类Dev

OpenGL:着色器存储缓冲区映射/绑定

来自分类Dev

无法从Compute着色器读取深度缓冲区

来自分类Dev

着色器存储缓冲区对象:字节序?

来自分类Dev

金属着色器在缓冲区中插入值

来自分类Dev

OpenGL-从顶点着色器访问缓冲区中的下3个顶点

来自分类Dev

打开gl计算着色器和帧缓冲区

来自分类Dev

打开gl计算着色器和帧缓冲区

来自分类Dev

不同大小的着色器存储缓冲区内容“转移”到阵列缓冲区

来自分类Dev

两个缓冲区的幂

来自分类Dev

顶点着色器如何访问与另一个shaderprogram属性绑定的顶点缓冲区数据?

来自分类Dev

为什么两个透明png照片的opengl着色器混合功能会变黑?

来自分类Dev

ThreeJS:首次尝试着色器-混合两个纹理

来自分类Dev

混合两个音频缓冲区时的咔嗒声/失真

来自分类Dev

如何使用glVertexAttribPointer将两个单独的数组附加到着色器?

来自分类Dev

我应该如何处理两个仅共享相同着色器的QGLWidget?

来自分类Dev

GLSL着色器:在两个以上的纹理之间插值

来自分类Dev

在 WebGL 着色器中使用 mix() 在两个以上的目标之间进行变形

来自分类Dev

OpenGL计算着色器中的样本深度缓冲区

来自分类Dev

运行OpenGL着色器以修改现有的纹理/帧缓冲区

来自分类Dev

有效清除着色器存储缓冲区

来自分类Dev

我可以从Metal着色器获取缓冲区的大小吗?

来自分类Dev

threejs片段着色器,使用回收的帧缓冲区

来自分类Dev

用于着色器资源视图到深度模板缓冲区资源的哪种格式?

来自分类Dev

OpenGL 3.0:无法在着色器中使用帧缓冲区对象(黑色)

来自分类Dev

OSX +屏幕外渲染+ CoreGL +帧缓冲区+着色器=头痛吗?

来自分类Dev

如何使用动态缓冲区声明定义金属着色器?

Related 相关文章

  1. 1

    在两个单独的着色器程序之间共享混合和Z缓冲区?

  2. 2

    深度缓冲区不适用于多个着色器程序

  3. 3

    从片段着色器访问深度缓冲区

  4. 4

    OpenGL:着色器存储缓冲区映射/绑定

  5. 5

    无法从Compute着色器读取深度缓冲区

  6. 6

    着色器存储缓冲区对象:字节序?

  7. 7

    金属着色器在缓冲区中插入值

  8. 8

    OpenGL-从顶点着色器访问缓冲区中的下3个顶点

  9. 9

    打开gl计算着色器和帧缓冲区

  10. 10

    打开gl计算着色器和帧缓冲区

  11. 11

    不同大小的着色器存储缓冲区内容“转移”到阵列缓冲区

  12. 12

    两个缓冲区的幂

  13. 13

    顶点着色器如何访问与另一个shaderprogram属性绑定的顶点缓冲区数据?

  14. 14

    为什么两个透明png照片的opengl着色器混合功能会变黑?

  15. 15

    ThreeJS:首次尝试着色器-混合两个纹理

  16. 16

    混合两个音频缓冲区时的咔嗒声/失真

  17. 17

    如何使用glVertexAttribPointer将两个单独的数组附加到着色器?

  18. 18

    我应该如何处理两个仅共享相同着色器的QGLWidget?

  19. 19

    GLSL着色器:在两个以上的纹理之间插值

  20. 20

    在 WebGL 着色器中使用 mix() 在两个以上的目标之间进行变形

  21. 21

    OpenGL计算着色器中的样本深度缓冲区

  22. 22

    运行OpenGL着色器以修改现有的纹理/帧缓冲区

  23. 23

    有效清除着色器存储缓冲区

  24. 24

    我可以从Metal着色器获取缓冲区的大小吗?

  25. 25

    threejs片段着色器,使用回收的帧缓冲区

  26. 26

    用于着色器资源视图到深度模板缓冲区资源的哪种格式?

  27. 27

    OpenGL 3.0:无法在着色器中使用帧缓冲区对象(黑色)

  28. 28

    OSX +屏幕外渲染+ CoreGL +帧缓冲区+着色器=头痛吗?

  29. 29

    如何使用动态缓冲区声明定义金属着色器?

热门标签

归档