设置场景:

我正在渲染一个高度图(巨大的不透明表面),上面带有大量的广告牌(通常是草,花等)。

因此,广告牌应用了几乎透明的颜色图,仅涂了几个像素就产生了草或叶的形状等。请注意,这些形状的边缘使用了一些透明度渐变,使它们看起来更平滑,但是我也尝试了使用基本的二进制颜色/透明纹理。

伪渲染代码如下所示:

map->render();
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
wildGrass->render();
glDisable(GL_BLEND);

wildGrass渲染指令在单个OGL调用中的不同位置渲染多个广告牌的地方。

我遇到的问题与透明性有关,事实上,广告牌即使在透明区域也彼此隐藏。但是,高度图的纯背景正确显示在那些透明零件上。

这是故障:
  • 左侧是在完全透明的像素上丢弃的显式片段着色器。
  • 右边没有丢弃,清楚地显示了广告牌的平面四边形

  • c++ - 如何在透明的大型广告牌渲染中避免距离排序-LMLPHP

    根据我对OGL混合的理解和一些阅读,看来解决方案是控制渲染顺序,从最远的对象开始到最接近的对象,以便最后正确填充颜色缓冲区。

    我非常希望有另一种方法...这里的顺序通常会根据 Angular 而有所不同,这意味着必须对每个帧实时应用。加上这些特定广告牌的性质,将以非常大的数量生产...性能警报!

    有什么建议吗,或者我的混合方法有误吗?

    最佳答案

    不适用于我:

    @httpdigest建议禁用深度缓冲区写入:

    它基本上适用于具有相同纹理(并且可能是特定类型的纹理,例如野草)的广告牌,因为深度不一致在视觉上并不明显-但是引入另一种纹理(例如颜色完全不同的花朵)将立即突出显示这些错误。

    解决方案:

    @ Rabbid76的建议是将非半透明的纹理与多重采样和抗锯齿功能结合使用:我相信这是一种以合理的性能成本实现最佳视觉效果的方法。

    替代解决方案:

    我发现了一种中间解决方案,该解决方案可能是性能最便宜而又以质量为代价的解决方案。我仍然使用具有渐变透明边缘的纹理,但是我没有丢弃完全透明的像素,而是引入了一定程度的公差,例如,丢弃了alpha
    使用这种方法:

  • 我仍然执行深度测试,因此输出是正确的
  • 纹理质量降低/看起来不太平滑-但
  • 相当合理
  • 仍然出现半透明像素上的毛刺-但
  • 几乎不明显
  • 请参见下面的捕获

  • 总结一下:
  • 我的解决方案是一种便宜且简单的近似方法,视觉效果不太平滑
  • 通过将所有广告牌渲染为具有抗锯齿的多重采样纹理解析,并最终在全屏四边形中输出结果,可以获得最佳结果。可能有一些方法可以做到这一点:
  • 要么先渲染 map ,要么在渲染广告牌时使用生成的深度缓冲区
  • 或在多采样纹理
  • 上同时渲染 map 和广告牌
  • 请注意,上述方法都是为了避免对多个广告牌进行基于距离的排序-但这仍然是一个有效的选项,我已经阅读了有关将广告牌位置存储在四叉树中以便快速访问的信息。

  • c++ - 如何在透明的大型广告牌渲染中避免距离排序-LMLPHP

    关于c++ - 如何在透明的大型广告牌渲染中避免距离排序,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58174499/

    10-09 05:27