循环更新数组项属性后值未保留的问题排查与解决
问题:批量更新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
相关产品推荐
相关产品推荐

