GLSL着色器:混合,原始特定行为和丢弃顶点

时间:2012-06-27 16:57:07

标签: opengl glsl shader primitive-types blending

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

我的问题,在一般意义上 - 详见下文 - 如下:

  1. 着色器是否允许您进行自定义混合,以帮助消除使用GL_BLEND时发现的z次序透明度问题?
  2. 有没有办法让着色器知道在没有“手动”传递某种旗帜的情况下绘制了什么类型的图元?
  3. 着色器是否有办法“忽略”或“丢弃”顶点(特别是在绘制点时)?
  4. 背景:我的应用程序绘制与正投影中的线相关的点(顶点在投影中具有不同的深度)。我最近才开始在项目中使用着色器(试图摆脱弃用的概念)。据我所知,标准混合有alpha测试和深度测试的排序问题:基本上,如果首先绘制更高z级别的“半透明”像素(因此在较低的z级别与已经绘制到该像素的任何颜色混合),然后在该像素处绘制不透明物体,但是在较低的z水平,深度测试防止改变已经为“较高”z水平绘制的像素,从而导致混合问题。要解决此问题,您需要先绘制不透明的项目,然后按升序z顺序绘制半透明项目。我的直觉是着色器不会提供一种(有效的)方式来改变这种行为 - 我错了吗?

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

1 个答案:

答案 0 :(得分:7)

  

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

排序。如果您可以访问GL 4.x级硬件(Radeon HD 5xxx或更高版本,或GeForce 4xx或更高版本),则可以执行与订单无关的透明度。早期的版本有深度剥皮等技术,但它们非常昂贵。

GL 4.x级版本基本上使用了一系列透明样本的“链接列表”,您可以通过全屏模式将其解析为最终的样本颜色。它当然不是 free ,但它没有其他OIT方法那么昂贵。对你的案子来说多贵是不确定的;它与您拥有的重叠像素数成正比。

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

  

有没有办法让着色器知道在没有“手动”传递某种标志的情况下绘制了什么类型的图元?

没有

  

着色器是否有办法“忽略”或“丢弃”顶点(特别是绘制点时)?

一般情况下不行,但积分是。几何着色器可以有条件地发射顶点,从而允许您出于任意原因丢弃任何顶点。

可以丢弃非点基元中的顶点,但它也会影响该基元的解释。点的简单原因是因为顶点一个图元,而三角形中的顶点不是整个图元。您可以丢弃行,但丢弃行中的顶点是......值不确定。

话虽如此,你对为什么要这样做的解释是值得怀疑的。您希望更新顶点数据,其基本上是一个布尔值,表示“与我一起做”或不做。这意味着,每一帧,你必须修改你的数据,以说明应该呈现哪些点,哪些不应该。

最简单,最有效的方法是简单地不用它们渲染。也就是说,排列您的数据,以便GPU上唯一的东西是您想要渲染的点。因此,根本不需要做任何特别的事情。如果您要不断更新顶点数据,那么您已经被迫处理streaming vertex data。所以你也可以通过一种使渲染效率更高的方式来传输它。