【问题标题】:GLSL Shaders: blending, primitive-specific behavior, and discarding a vertexGLSL 着色器:混合、原始特定行为和丢弃顶点
【发布时间】:2012-06-27 16:57:06
【问题描述】:

标准:我正在使用带有着色器 (GLSL) 的 OpenGL,并尝试使用现代技术(例如,尝试远离已弃用的概念)。

我的问题,在一个非常笼统的意义上——更多细节见下文——如下:

  1. 着色器是否允许您进行自定义混合以帮助消除使用 GL_BLEND 时发现的 z 顺序透明度问题?
  2. 有没有办法让着色器知道正在绘制什么类型的图元,而无需“手动”传递某种标志?
  3. 着色器有没有办法“忽略”或“丢弃”顶点(尤其是在绘制点时)?

背景:我的应用程序在正交投影中绘制与线相连的点(顶点在投影中具有不同的深度)。我最近才开始在项目中使用着色器(试图摆脱过时的概念)。我了解标准混合在 alpha 测试和深度测试方面存在排序问题:基本上,如果首先绘制较高 z 级别的“半透明”像素(因此与已经在较低 z 级别绘制到该像素的任何颜色混合),然后在该像素处绘制一个不透明对象,但在较低的 z 级别上,深度测试可防止更改已经为“较高”z 级别绘制的像素,从而导致混合问题。为了克服这个问题,您需要先绘制不透明的项目,然后按 z 升序绘制半透明的项目。我的直觉是着色器不会提供一种(有效的)方法来改变这种行为——我错了吗?

此外,为了速度和方便,我将每个顶点的信息(以及几个统一变量)传递给着色器,它们使用这些信息来查找需要特别注意的顶点子集。如果不在应用程序本身中执行一组类似的逻辑(并减慢速度),我无法先验地知道那是什么验证子集。因此,我将所有顶点发送到着色器。但是,当我绘制“点”时,我希望着色器忽略所有不在它确定的子集中的顶点。我想我可以通过将 alpha 设置为零并在 GL 上下文中使用 alpha 函数来获得效果,这将防止绘制任何 alpha 小于 0.01 的东西。但是,是否有更好或更“正确”的 glsl 方式让着色器说“忽略这个顶点”?

【问题讨论】:

  • -1:将几个相当不相关的问题作为一个问题提出。
  • 我明白你的意思,但它们都与我的同一个问题有关。我想在一次通过中将顶点子集的点和线绘制为不透明,然后在第二次通过中仅为其余顶点绘制半透明线。我这样做是为了克服混合问题,因为我不知道更好的方法(我的第一个问题)。我想每次都发送相同的顶点(以及几个变量)并让着色器确定要绘制哪些顶点以及要删除哪些顶点(第三个问题)。最后,事实证明,我只需要着色器在绘制点时丢弃顶点(第二个问题)。
  • 不要强调这一点,但我也注意到,问一个简单的问题通常会导致明显的跟进“但是你为什么要这样做?”当它们都回到相同的整体期望行为时,我不想尝试跨多个线程跟踪这些类型的问题。

标签: opengl glsl shader primitive-types blending


【解决方案1】:

着色器是否允许您进行自定义混合以帮助消除使用 GL_BLEND 时发现的 z 顺序透明度问题?

有点。如果您可以访问 GL 4.x 级硬件(Radeon HD 5xxx 或更高版本,或者 GeForce 4xx 或更高版本),那么您可以执行与订单无关的透明度。早期版本有深度剥离等技术,但价格相当昂贵。

GL 4.x 级版本本质上使用了一系列透明样本的“链接列表”,您可以通过全屏处理将其解析为最终样本颜色。当然,它不是免费,但它不像其他 OIT 方法那样昂贵。你的案子会有多贵是不确定的;它与您有多少重叠像素成正比。

你仍然必须先绘制不透明的东西,然后你必须使用特殊的着色器代码来绘制透明的东西。

有没有办法让着色器知道正在绘制什么类型的图元而无需“手动”传递某种标志?

没有。

着色器有没有办法“忽略”或“丢弃”顶点(尤其是在绘制点时)?

一般不会,但可以。几何着色器可以有条件地发射顶点,因此允许您出于任意原因丢弃任何顶点。

在非点图元中丢弃一个顶点是可能的,但它也会影响该图元的解释。点之所以简单是因为顶点一个图元,而三角形中的一个顶点不是一个完整的图元。您可以丢弃线条,但丢弃线条的顶点是......价值可疑。

话虽如此,您对为什么要这样做的解释值得怀疑。您想使用本质上是一个布尔值来更新顶点数据,该值表示“与我一起做事”或不做。这意味着,每一帧,你都必须修改你的数据来说明哪些点应该被渲染,哪些不应该。

最简单和最有效的方法是简单地不使用它们进行渲染。也就是说,排列您的数据,以便 GPU 上唯一的东西是您想要渲染的点。因此,根本不需要做任何特别的事情。如果您要不断更新您的顶点数据,那么您已经注定要与streaming vertex data 打交道。因此,您不妨以一种提高渲染效率的方式对其进行流式传输。

【讨论】:

  • 感谢您的回复!在你关于我为什么要丢弃分数的最后几段中,恐怕我没有提供足够的细节。我不会在每一帧中更新顶点数据。但是,我确实更新了两个与(永不改变的)顶点数据进行比较的统一变量以做出逻辑选择(例如,仅在 t = 59.345 和 t = 120.214 之间绘制顶点)。我必须要么使用 CPU 周期(并渲染顶点数据的子集)来做到这一点,要么将数据传递给着色器并让它完成工作。也许后者是一个较差的选择,但我已经看到使用它提高了性能。
  • @FTL:你应该把这些细节放在你的问题中。在任何情况下,您如何看到执行您要求如何做的事情(剔除顶点)的性能提高?你之前是如何在着色器中剔除它们的?
  • 正如我的问题中所述,我将 alpha 设置为零并告诉 GL 忽略 alpha
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-11
相关资源
最近更新 更多