线框着色器 - 使用共享顶点时重心坐标出现问题 [英] Wireframe shader - Issue with Barycentric coordinates when using shared vertices

查看:16
本文介绍了线框着色器 - 使用共享顶点时重心坐标出现问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 WebGL 绘制地形.问题是我只使用 4 个顶点通过使用索引来共享顶点来绘制单个四边形.所以我不能为每个顶点上传唯一的重心坐标,因为它是共享的.

I'm working on drawing a terrain in WebGL. The problem is that I'm only using 4 vertices to draw a single quad by using indices to share vertices. So I can't upload unique baricentric coordinates for each vertex, because it's shared.

这是一张更清楚地显示问题的图片.

Here's a picture that shows the problem more clearly.

没有可用于问号的重心坐标.(0,1,0) 用于左上方,(0,0,1) 用于上方,(1,0,0) 用于左侧.因此,当我使用索引来保存顶点数时,我绝对无法做到这一点.

There's no barycentric coordinate that I can use for the question mark. (0,1,0) is used top left, (0,0,1) is used above and (1,0,0) is used to the left. So there's absolutely no way I can do this when I'm using indices to save vertex count.

使用 4 个顶点而不是 6 个顶点绘制四边形真的可以节省那么多性能吗?如果没有,那么这是解决我的问题的最简单方法.但是我仍然很好奇是否有办法使用共享顶点来做到这一点.

Do I really save that much performance drawing a quad using 4 vertices instead of 6? If not then that's the easiest way to fix my problem. But I'm still curious if there's a way I can do it with shared vertices.

我知道我可以使用 GL_LINES 在线框中绘制地形,但我不喜欢这种方法,我想更好地控制我的线框(例如不使其透明).

I'm aware that I can draw my terrain in wireframe using GL_LINES but I don't like that method, I want to have more control over my wireframe (e.g. not make it transparent).

有些人可能会问我为什么要使用重心坐标线框模式来绘制地形,因为它在这个演示中效果很好:

Some people might ask why I'm using barycentric coordinates to draw my terrain in wireframe mode, it's because it works nicely in this demo:

http://codeflow.org/entries/2012/aug/02/easy-wireframe-display-with-barycentric-coordinates/

所以这基本上是我正在寻找的两件事:

So it's basically two things I'm looking for:

  • 在绘制每个四边形使用 6 个顶点而不是 4 个顶点的地形时,我是否会损失很多性能?因为如果不是,那将通过不共享顶点来解决我的问题.
  • 是否可以为 4 个顶点共享唯一的重心坐标以绘制单个四边形?

谢谢!

推荐答案

如果您不需要在线框中绘制每个四边形的对角线,并且只绘制每个四边形的边缘就可以了,这会变得更简单.如果您在四边形而不是三角形上操作,则无需担心重心坐标.代替 3 个重心坐标,使用 2 个坐标作为网格内的相对位置:

If you don't require to draw the diagonal of each quad in your wireframe, and are fine with only drawing the edges of each quad, this gets much simpler. There's no need to worry about barycentric coordinates if you operate on quads instead of triangles. Instead of the 3 barycentric coordinates, use 2 coordinates for the relative position within the mesh:

0,2----1,2----2,2----3,2----4,2
 |      |      |      |      |
 |      |      |      |      |
 |      |      |      |      |
0,1----1,1----2,1----3,1----4,1
 |      |      |      |      |
 |      |      |      |      |
 |      |      |      |      |
0,0----1,0----2,0----3,0----4,0

这还允许您跨四边形共享顶点,从而将模型中的顶点总数减少大约 4 倍.

This also allows you to share vertices across quads, cutting the total number of vertices in your model by approximately a factor of 4.

然后,您将这些坐标对从顶点着色器提供给片段着色器,就像在您链接的文章中描述的重心坐标一样.

You then feed these coordinate pairs from the vertex shader through to the fragment shader just like it's described for the barycentric coordinates in the article you linked.

在片段着色器中,代码稍微复杂一些,因为它需要在取小数部分后测试接近 0 或接近 1 的值.我没有对此进行测试,但它可能看起来像这样,vQC 相当于文章中的 vBC:

In the fragment shader, the code gets just slightly more complicated, since it needs to test for values being either close to 0 or close to 1, after taking the fractional part. I haven't tested this, but it could look something like this, with vQC being the equivalent of vBC in the article:

varying vec2 vQC;
...
void main() {
    vec2 vRel = fract(vQC);
    if (any(lessThan(vec4(vRel, 1.0 - vRel), vec4(0.02)))) {
        gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
    } else {
        gl_FragColor = vec4(0.5, 0.5, 0.5, 1.0);
    }
}

这篇关于线框着色器 - 使用共享顶点时重心坐标出现问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆