如何在WebGL中绘制字母A和I?gl.TRIANGLE_FAN绘制异常问题
问题原因及解决方案
为什么gl.TRIANGLE_FAN会绘制异常
gl.TRIANGLE_FAN的绘制规则是以第一个顶点为中心点,后续每个顶点都会和前一个顶点、中心点共同组成一个三角形。你的顶点序列是按照gl.LINE_LOOP的线框轮廓顺序定义的(沿着字母A和I的边缘依次排列),这种顺序完全不符合TRIANGLE_FAN的填充逻辑——中心点(0,0)会和后续所有顶点错误连接,导致三角形交叉、重叠,最终出现畸形形状。
正确的解决思路
字母A和I属于包含多个独立填充区域的复杂形状,gl.TRIANGLE_FAN只适合绘制单中心的扇形/圆形类图形,不适合这类由多个多边形组成的文字。你有两种可行方案:
方案1:改用gl.TRIANGLES绘制
将字母拆分成多个独立的三角形,重新组织顶点数据,每个三角形的三个顶点按顺序排列。比如字母A可以拆成左右两个大三角形,加上中间的横杠矩形(拆成两个三角形)。
调整后的顶点示例(仅核心位置,颜色可复用):
vertices = new Float32Array([ // A的左三角形:(0,0), (0,0.7), (0.2,0) 0, 0, 0.0, 1.0, 1.0, 0, 0.7, 0.0, 1.0, 1.0, 0.2, 0, 0.0, 1.0, 1.0, // A的右三角形:(0.2,0), (0,0.7), (0.5,0.7) 0.2, 0, 0.0, 1.0, 1.0, 0, 0.7, 0.0, 1.0, 1.0, 0.5, 0.7, 0.0, 1.0, 1.0, // 中间横杠上半部分:(0.2,0.5), (0.5,0.5), (0.2,0.6) 0.2, 0.5, 0.0, 1.0, 1.0, 0.5, 0.5, 0.0, 1.0, 1.0, 0.2, 0.6, 0.0, 1.0, 1.0, // 中间横杠下半部分:(0.2,0.6), (0.5,0.5), (0.5,0.6) 0.2, 0.6, 0.0, 1.0, 1.0, 0.5, 0.5, 0.0, 1.0, 1.0, 0.5, 0.6, 0.0, 1.0, 1.0, // I的部分(按三角形拆分补充顶点) // ... ]);
然后调用绘制:
gl.drawArrays(gl.TRIANGLES, 0, vertices.length / 5);
方案2:拆分多个TRIANGLE_FAN区域
如果坚持用TRIANGLE_FAN,需要把字母的每个独立填充区域单独作为一个扇形,分别调用gl.drawArrays。比如A的左半部分以(0,0.7)为中心组成扇形,右半部分以(0.5,0.7)为中心,但这种方式对于文字来说不如TRIANGLES直观。
补充说明
线框绘制(gl.LINE_LOOP/gl.LINES)只需要按轮廓顺序排列顶点,但填充绘制(gl.TRIANGLES/gl.TRIANGLE_STRIP/gl.TRIANGLE_FAN)严格依赖顶点的环绕顺序和分组逻辑,必须根据不同图元的规则组织顶点数据。
内容的提问来源于stack exchange,提问作者Mutasem Sawalhi
相关产品推荐
相关产品推荐

