线框着色器 - 使用共享顶点时出现重心坐标问题

时间:2014-07-19 11:23:14

标签: opengl-es indexing webgl

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

这是一张能够更清楚地显示问题的图片。

enter image description here

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

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

我知道我可以使用GL_LINES在线框中绘制我的地形,但我不喜欢这种方法,我希望能更好地控制我的线框(例如,不要让它透明)。

有些人可能会问为什么我使用重心坐标在线框模式下绘制我的地形,这是因为它在这个演示中运行良好:

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

所以这基本上是我要找的两件事:

  • 我是否在绘制地形时失去了很多表现,每个四边形使用6个顶点而不是4个?因为如果没有,那么这将通过不共享顶点来解决我的问题。
  • 是否可以为共享的4个顶点设置唯一的重心坐标以绘制单个四边形?

谢谢!

3 个答案:

答案 0 :(得分:4)

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

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倍。

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

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

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);
    }
}

答案 1 :(得分:1)

我将使用两个三角形的四边形创建我的网格,其中顶点不在相邻的四边形之间共享。 这将导致更大的网格(大约4倍),但由于内存布局中更好的数据局部性,渲染性能最有可能更高效。

enter image description here

答案 2 :(得分:1)

有三个重心坐标(100,010和001)我将表示HTO(数百,数十和1,即使这些显然不是十进制数 - 这个简写是为了方便)。您想以这种模式提交这些:

O H T O H
T O H T O
H T O H T
O H T O H
T O H T O

你可以看到,对于你开始的任何三角形,一旦你为它分配了三个坐标,它的边缘就会“选择”周围三角形的两个坐标,只留下一个三角形剩余顶点的选择。请注意,平铺将根据您分割它们组成的四边形的位置进行镜像(您将总是在具有相同顶点的四边形中的每个三角形的远角处结束,就像第一个TOH-THO中的两个Os一样在左下角的两个中。)

无论是在索引顶点还是三角形条带中,您都必须以与它们所属的顶点相同的顺序提供重心坐标。因此,对于一个高两宽的条带:

verts = [ A B C D E F ];
barycentric = [ T O H O H T ];
indices = [ 0 1 4 0 4 3 1 2 5 1 5 4 ];

这是一个分配坐标的简单算法:

barycentricTiles = [[1,0,0],[0,1,0],[0,0,1]];
// looping where i, j are indexes for each point on your mesh from 0,0 to m,n
barycentric.push(barycentricTiles[ (i+j)%3 ]);

上周我花了一些时间来搞清楚这一点,所以我想我会把它传递出去。对不起,这已经太晚了三年了!