【问题标题】:Approach for writing a GLSL fragment shader with a solid color per triangle/face编写每个三角形/面纯色的 GLSL 片段着色器的方法
【发布时间】:2011-06-30 06:19:49
【问题描述】:

我有顶点和三角形数据,其中包含每个三角形(面)的颜色,而不是每个顶点的颜色。即一个顶点由多个面共享,每个面可能具有不同的颜色。

我应该如何在 GLSL 中解决这个问题,以便为每个正在渲染的 face 分配纯色?通过平均顶点相邻多边形的颜色来计算和分配“顶点颜色”缓冲区很容易,但这当然会在片段着色器中插入颜色时产生模糊结果。

我真正需要的根本不应该是插值颜色值,一旦按预期工作,我将使用大约 15 种可能的纯色着色大约 40k 三角形。

【问题讨论】:

标签: opengl 3d glsl shader


【解决方案1】:

虽然您可能可以在高端 GLSL 中执行此操作,但进行实体着色的正确方法是为每个三角形制作唯一的顶点。这是一个微不足道的循环。对于每个顶点,计算有多少三角形共享它。这就是你必须复制它的频率。确保执行此操作的循环为 O(n)。然后只需将每个顶点颜色或法线设置为三角形的颜色。又是一个直线循环。不要费心优化共享颜色,这是不值得的。

稍后再编辑,因为这是一个流行的答案:

要对每个面进行平整着色,您可以在世界或视图空间中插入顶点位置。然后在片段着色器中计算这个变量的 ddx(dFdx) 和 ddy(dFdy)。取这两个向量的叉积并对其进行归一化 - 你得到一个平坦的法线!根本不需要网格更改或每个顶点数据。

【讨论】:

  • 担心性能,但我想如果它全部在一个几何中,它可能不是问题。将不得不看看它是如何进行的。我没有提到的另一个复杂因素是我希望能够从这种“模式”切换到完全多纹理的混合模式。但我也可以切换网格可见。
  • 这是不久前的事,但这就是我最终需要的。只需复制所有顶点,没有三角形共享相同的顶点索引。
【解决方案2】:

OpenGL 没有“per-face”属性。见:

How can I specify per-face colors when using indexed vertex arrays in OpenGL 3.x?

以下是我看到的一些可能的选项:

  1. 放弃索引数组并像 starmole 建议的那样为每个面使用单独的顶点
  2. 为使用的每种颜色创建一个索引数组。使用材质而不是顶点颜色,并在从索引数组中为每种颜色绘制三角形后更改材质。
  3. 如果几何体允许,您可以确保索引数组指定的最后一个顶点具有正确的面顶点颜色,然后使用 GL_FLAT 着色,或者让片段着色器仅使用最后一个顶点颜色。

【讨论】:

  • 你能详细说明#3吗?特别是在片段着色器中“使用最后一个顶点颜色”的能力 - 我们如何从片段着色器访问片段的顶点?
【解决方案3】:

除了其他答案之外,您还可以使用gl_PrimitiveID 变量,它是片段着色器的输入(不知道从哪个版本开始),并为每个三角形隐式递增。然后,您可以使用它来查找颜色(从 40k 的颜色缓冲区纹理或颜色索引到 15 色颜色图,或者只是从原始 id 进行一些直接计算)。但是不要问我这种方法的性能。

【讨论】:

  • 如果我尝试了这个,你知道这个 ID 变量是否适用于每个网格,或者 ID 是否会随着每个渲染的三角形而增加?我会担心 ID 是否一致,以及其他网格是否会取消计数。
  • @Crusader 对于每个glDraw... 命令(我认为在glDrawMulti... 命令的每个实例中),ID 都设置为零,并且每次绘制原始(三角形)时都会增加,所以是的ID 是一致的,只依赖于当前的glDraw... 命令。
猜你喜欢
  • 1970-01-01
  • 2021-05-02
  • 1970-01-01
  • 2018-01-05
  • 1970-01-01
  • 2017-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多