我正在研究在 WebGL 中绘制地形。问题是我只使用 4 个顶点通过使用索引共享顶点来绘制单个四边形。因此,我无法为每个顶点上传唯一的重心坐标,因为它是共享的。
这是更清楚地显示问题的图片。
没有可用于问号的重心坐标。 (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/
所以这基本上是我正在寻找的两件事:
谢谢!
如果您不需要在线框中绘制每个四边形的对角线,并且只需绘制每个四边形的边缘就可以了,那么这会变得简单得多。如果您操作的是四边形而不是三角形,则无需担心重心坐标。使用 2 个坐标代替 3 个重心坐标来表示网格内的相对位置:
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);
}
}
有三个重心坐标(100、010 和 001),我将表示 HTO(代表百位、十位和个位,即使这些显然不是十进制数字 - 这种简写是为了方便)。您想以这种模式提交这些:
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 ]);
上周我花了一些时间来解决这个问题,所以我想我会把它传递下去。抱歉晚了三年!
我将使用两个三角形的四边形创建网格,其中相邻四边形之间不共享顶点。 这将导致更大的网格(大约 4 倍),但由于内存布局中更好的数据局部性,渲染性能很可能会更有效。
这个问题你解决了吗?怎么解决的?