You need to enable JavaScript to run this app. WebGL使用循环多次绘制出现几何体重叠或变形问题求助
优惠活动
大模型
产品
解决方案
定价
更多

WebGL使用循环多次绘制出现几何体重叠或变形问题求助

排查和解决建议

  • 矩阵累加修改问题
    你在循环内直接修改object.mvMatrix本身,mat4.translate默认会在传入的原矩阵基础上做修改,每一轮循环都会在上一轮平移后的矩阵基础上继续叠加偏移,而不是基于初始的模型视图矩阵计算偏移,导致实例位置越来越偏离预期,最终出现重叠、错位。
    解决方法:每次循环前先拷贝一份初始的object.mvMatrix,在拷贝出来的矩阵上做平移操作,不要直接修改原矩阵:

    App.scene.tree1_.instancedDraws.overrideDrawArraysInstance =  function(object) {
      // 先保存初始矩阵
      const originalMvMatrix = mat4.clone(object.mvMatrix);
      for (var i = 0; i < object.instancedDraws.numberOfInstance; i++) {
        // 每次从初始矩阵开始计算偏移
        mat4.translate(
          object.mvMatrix,
          originalMvMatrix,
          // 这里如果要不同实例位置不同,需要根据i生成对应偏移,所有实例偏移一致会导致重叠
          [0 , 0, 18 * (i+1)]
        );
        world.setMatrixUniforms(object, world.pMatrix, object.mvMatrix);
        // 后续绘制逻辑
      }
      // 循环结束后恢复原矩阵,避免影响外部逻辑
      object.mvMatrix = originalMvMatrix;
    };
    
  • drawArraysInstanced参数使用错误

    1. 第二个参数是顶点数组的起始偏移,你当前传了1,会跳过第一个顶点,导致绘制的几何体顶点顺序不对出现变形,如果你的顶点数据是从0开始的,这里应该填0。
    2. 第四个参数是单次调用绘制的实例数,你现在每次循环传1,相当于完全没有用到实例化绘制的特性,不如直接用普通的drawArrays。如果要发挥实例化绘制的性能优势,可以去掉循环,直接把实例数填为object.instancedDraws.numberOfInstance,同时通过实例化顶点属性传递每个实例的偏移量即可。
    3. 你之前正常绘制用的是drawElements(索引绘制),但这里用的是drawArraysInstanced(无索引的数组绘制),请确认你当前绑定的顶点缓冲适配非索引绘制,如果此时还绑定着索引缓冲,或者顶点数据是专门给索引绘制准备的,会出现顶点读取错误导致变形。
  • 实例偏移量固定问题
    你当前所有循环的偏移量都是固定的[0,0,18],如果没有矩阵重置的逻辑,所有实例会沿着Z轴每次累加18的偏移,即便修复了矩阵问题,所有实例偏移都相同的话也会完全重叠。需要根据循环索引i生成不同的偏移值,比如X轴根据i做水平偏移:[i * 10, 0, 18]。

  • 矩阵栈操作校验
    确认进入overrideDrawArraysInstance方法前,你已经调用了mvPushMatrix保存了初始的object.mvMatrix,避免方法内修改的矩阵泄漏到外部其他绘制逻辑。

内容的提问来源于stack exchange,提问作者Nikola Lukic

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.13 21:42:01