编写每个三角形/面具有纯色的 GLSL 片段着色器的方法

发布于 2024-11-17 23:30:52 字数 266 浏览 1 评论 0 原文

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

我应该如何在 GLSL 中解决这个问题,以便为每个渲染的获得纯色分配?通过平均顶点相邻多边形的颜色来计算和分配“顶点颜色”缓冲区非常简单,但这当然会产生模糊的结果,其中颜色在片段着色器中进行插值。

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

I have vertex and triangle data which contains a color for each triangle (face), not for each vertex. i.e. A single vertex is shared by multiple faces, each face potentially a different color.

How should I approach this problem in GLSL to obtain a solid color assignment for each face being rendered? Calculating and assigning a "vertex color" buffer by averaging the colors of a vertex's neighboring polys is easy enough, but this of course produces a blurry result where the colors are interpolated in the fragment shader.

What I really need shouldn't be interpolated color values at all, I'll have about 40k triangles shaded with approx 15 possible solid colors once this is working as intended.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

可爱咩 2024-11-24 23:30:52

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

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

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

While you maybe could do this in high end GLSL, the right way to do solid shading is to make unique vertices for every triangle. This is a trivial loop. For every vertex, count how many triangles share it. That's how often you have to replicate it. Make sure your loop to do this is O(n). Then just set each vertex color or normal to that of the triangle. Again one straight loop. Do not bother to optimize for shared colors, it is not worth it.

Edit much later, because this is a popular answer:

To do flat per face shading you can interpolate the vertex position in world or view space. Then in the fragment shader compute ddx(dFdx) and ddy(dFdy) of this variable. Take the cross product of those two vectors and normalize it - you got a flat normal! No mesh changes or per vertex data needed at all.

淡紫姑娘! 2024-11-24 23:30:52

OpenGL 没有“per-face”属性。请参阅:

在 OpenGL 3.x 中使用索引顶点数组时,如何指定每个面的颜色?

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

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

OpenGL does not have "per-face" attributes. See:

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

Here are a few possible options I see:

  1. Ditch the index arrays and use separate vertices for each face like starmole suggested
  2. Create an index array for each color used. Use materials instead of vertex colors and change the material after drawing the triangles from the index array for each color.
  3. If the geometry allows it, you can make sure the last vertex specified by the index array has the correct vertex color for the face, and then use GL_FLAT shading, or have the fragment shader only use at the last vertex color.
平安喜乐 2024-11-24 23:30:52

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

In addition to the other answers, you could maybe employ the gl_PrimitiveID variable, that's an input to the fragment shader (don't know since which version) and is incremented implicitly for each triangle. You could then use this to lookup the color (either from a 40k buffer texture of colors or color indices into a 15 color color map, or just some direct computation from the primitive id). But don't ask me about the performance of this approach.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文