WebGL中三角间预计算变换矩阵失效问题排查求助
问题原因与修复方案
核心矛盾:矩阵存储/乘法逻辑不匹配
你用transformation-matrix生成的是行主序的2D变换矩阵,而WebGL的mat3默认采用列主序存储,且GLSL里矩阵和向量的乘法规则和Canvas 2D完全相反,直接复用矩阵必然出错。
具体问题拆解
矩阵构造与解析不兼容
transformation-matrix输出的{a,b,c,d,e,f}对应行主序矩阵结构:[ a c e ] [ b d f ] [ 0 0 1 ]你构造的数组
[a, b, 0, c, d, 0, e, f, 1]是按行平铺的,但WebGL的uniformMatrix3fv默认会按列主序解析数据,相当于强行颠倒了矩阵的行和列,变换自然不对。坐标空间重复转换
你先把三角形的[0,1]坐标转成了WebGL的NDC([-1,1])坐标还翻转了y轴,然后又用针对原始[0,1]空间计算的矩阵去变换,等于做了两次空间转换,结果肯定偏离预期。
三种修复方法
方法1:修改着色器的乘法顺序
把顶点向量作为行向量右乘矩阵,匹配transformation-matrix的行主序逻辑:
void main() { // 行向量右乘矩阵,和Canvas 2D变换逻辑一致 vec3 transformedCoords = vec3(a_position,1.0) * u_matrix; gl_Position = vec4(transformedCoords.xy, 0.0, 1.0); v_texcoord = a_texcoord; }
矩阵构造代码保持原样即可。
方法2:转置矩阵适配列主序
如果想保留着色器里矩阵左乘列向量的逻辑,把行主序矩阵转成列主序再传入:
let { a, b, c, d, e, f } = this.matrices[idx][j]; // 转置后按列主序排列数组 let matrix = [a, c, e, b, d, f, 0, 0, 1]; gl.uniformMatrix3fv(glAttrs.uniforms.matrix, false, matrix);
方法3:取消提前坐标转换
直接用原始[0,1]坐标作为顶点数据,在着色器里先应用变换,再转成NDC空间:
- 修改顶点数据代码:
let positions = [ pnts[0][0], pnts[0][1], pnts[1][0], pnts[1][1], pnts[2][0], pnts[2][1], ];
- 修改顶点着色器:
void main() { // 先应用变换矩阵 vec3 transformed = u_matrix * vec3(a_position, 1.0); // 把[0,1]坐标转成WebGL的NDC空间,同时翻转y轴 vec2 ndc = vec2(transformed.x * 2.0 - 1.0, -transformed.y * 2.0 + 1.0); gl_Position = vec4(ndc, 0.0, 1.0); v_texcoord = a_texcoord; }
这种方式最贴合transformation-matrix的原始设计,不容易搞混空间转换。
验证建议
先测试单位矩阵是否正常显示,如果正常,说明矩阵的存储/乘法顺序就是问题根源;如果还是不对,检查矩阵计算时的源/目标三角形坐标空间是否和WebGL的输入匹配。
内容的提问来源于stack exchange,提问作者hobberwickey
相关产品推荐
相关产品推荐

