使用drawArraysInstancedANGLE多纹理绘图标时几何形状异常问题
排查WebGL实例化绘制图标异常形状的思路
从你描述的异常形状和提供的代码来看,这个问题大概率出在顶点/纹理坐标顺序、实例化数据匹配,或者着色器变换逻辑上,我给你梳理几个具体的排查方向:
1. 先核对纹理坐标的顶点顺序
你在FillIconTextCoordBuffer里定义的两个三角形坐标数组是:
new Float32Array([ ULiconW, ULiconH, // 左上 LRiconW, LRiconH, // 右下 LRiconW, ULiconH, // 右上 LRiconW, LRiconH, // 右下 ULiconW, ULiconH, // 左上 ULiconW, LRiconH // 左下 ])
这组坐标对应的第一个三角形是「左上→右下→右上」,第二个是「右下→左上→左下」——这个顶点顺序很容易出问题:
- 首先要和你的**顶点位置数组(IconMapVertCoordArr)**的顺序完全匹配:如果顶点位置是按「左上→右上→右下→左下」排列的,纹理坐标顺序不匹配就会导致顶点错位,拉伸成奇怪的形状;
- 你可以打印出异常图标对应的纹理坐标值,看是否存在
data.x/data.width为负数,或者mapW/mapH计算错误的情况(比如图集尺寸传反了)。
2. 检查实例化分组与纹理坐标的对应关系
你在循环StartCountArr时,用索引j来绑定IconMapTexCoordArr[j]:
for (var j = this.StartCountArr.length; j--;) { this.DrawInstances(this.StartCountArr[j].start, this.StartCountArr[j].count, j) }
这里要确认:StartCountArr里的每个分组对应的图标类型,是否和IconMapTexCoordArr[j]的索引完全对应?比如会不会某个分组的实例应该用纹理坐标索引k,但实际用了j,导致纹理坐标和顶点位置错位,画出异常形状。
3. 验证实例化偏移量与顶点属性设置
- 检查
IconCoordBuff里的偏移量数据:有没有某个实例的偏移量出现NaN、极大值或者错误的数值?如果偏移量异常,会把顶点拉到奇怪的位置,形成扭曲的形状; - 确认
vertexAttribDivisorANGLE的设置:你在绘制前设为1,绘制后改回0,这个逻辑是对的,但要确保没有其他地方意外修改了这个属性的 divisor 值。
4. 排查着色器的变换逻辑
你设置了旋转、缩放等uniform变量,这里很容易出现细节错误:
- 旋转角度是否转成弧度了?如果着色器里直接用角度值计算
sin/cos,会导致旋转完全异常,顶点位置被严重扭曲; - 检查片元着色器里的纹理采样逻辑:有没有错误反转了y轴?或者对纹理坐标做了额外的错误变换?
- 可以临时把着色器里的旋转、缩放注释掉,只绘制原始位置的图标,看是否还会出现异常,以此排除变换逻辑的问题。
5. 调试小技巧
- 单实例测试:用
gl.drawArrays代替ext.drawArraysInstancedANGLE,只绘制一个异常图标实例,看是否能复现问题——如果能,说明是单个图标的绘制逻辑问题,不是实例化的问题; - 颜色可视化纹理坐标:在片元着色器里把输出颜色设为纹理坐标的x/y值(比如
gl_FragColor = vec4(texCoord.x, texCoord.y, 0.0, 1.0)),这样可以直观看到每个顶点的纹理坐标是否正确,异常形状的颜色会直接暴露坐标问题; - 临时关闭深度测试:执行
gl.disable(gl.DEPTH_TEST)后再绘制,如果异常消失,说明是背面剔除或者深度顺序的问题——WebGL默认逆时针为正面,如果你的三角形是顺时针顺序,会被自动剔除,导致只显示一半的形状。
内容的提问来源于stack exchange,提问作者H. Akkaya
相关产品推荐
相关产品推荐

