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

循环更新数组项属性后值未保留的问题排查与解决

问题:批量更新Shader透明度后渲染异常

问题场景

在同一个循环中更新ref.shader的透明度并调用渲染方法时,所有多边形能正确应用对应alpha值渲染:

for (let i = 0; i < this._polyRenderRefs.length; i++) {
    let ref = this._polyRenderRefs[i];
    let poly = this._polygons[ref.polygonIndex];

    let alpha = 1.0 - (poly.position.z - this._zDepthMin) / (this._zDepthMax - this._zDepthMin);
    ref.shader.edgeColor.setAlpha(alpha);
    ref.shader.faceColor.setAlpha(alpha);

    this._polyRender.drawSingle(context, poly, ref);
}

但将渲染逻辑移到独立的后续循环后,所有多边形的透明度都被最后一次计算的alpha值覆盖,渲染结果不符合预期:

for (let i = 0; i < this._polyRenderRefs.length; i++) {
    let ref = this._polyRenderRefs[i];
    let poly = this._polygons[ref.polygonIndex];

    let alpha = 1.0 - (poly.position.z - this._zDepthMin) / (this._zDepthMax - this._zDepthMin);
    ref.shader.edgeColor.setAlpha(alpha);
    ref.shader.faceColor.setAlpha(alpha);

    // this._polyRender.drawSingle(context, poly, ref);
}

for (let i = 0; i < this._polyRenderRefs.length; i++) {
    let ref = this._polyRenderRefs[i];
    let poly = this._polygons[ref.polygonIndex];

    this._polyRender.drawSingle(context, poly, ref);
}

直接操作数组项而非使用变量引用,结果一致。

排查过程

  • alpha计算验证:用固定值替代poly.position.z计算alpha时,透明度能在循环外正常保留;position是gl-matrix的vec3类型,通过Vertex类的getter访问。
  • 引用关系排查:发现所有数组项的ref.shader.edgeColor.alpha和ref.shader.faceColor.alpha都指向同一个内存引用,导致最后一次计算的值覆盖了所有项的设置。
  • 对象引用验证:在PolygonRenderReference中新增测试变量可独立更新,但CanvasShader中的测试变量会被统一覆盖,说明所有PolygonRenderReference实例共用了同一个CanvasShader对象。

解决方案

创建PolyRenderRefs数组时,未为每个PolygonRenderReference实例创建独立的CanvasShader对象,而是复用了同一个实例,导致更新alpha时所有实例的shader都被修改。为每个PolygonRenderReference实例创建单独的CanvasShader对象即可解决该问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 13:35:19