You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 02:15:38