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

WebGL中三角间预计算变换矩阵失效问题排查求助

问题原因与修复方案

核心矛盾:矩阵存储/乘法逻辑不匹配

你用transformation-matrix生成的是行主序的2D变换矩阵,而WebGL的mat3默认采用列主序存储,且GLSL里矩阵和向量的乘法规则和Canvas 2D完全相反,直接复用矩阵必然出错。

具体问题拆解

  1. 矩阵构造与解析不兼容
    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默认会按列主序解析数据,相当于强行颠倒了矩阵的行和列,变换自然不对。

  2. 坐标空间重复转换
    你先把三角形的[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空间:

  1. 修改顶点数据代码:
let positions = [
  pnts[0][0], pnts[0][1],
  pnts[1][0], pnts[1][1],
  pnts[2][0], pnts[2][1],
];
  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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 09:59:50