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

Three.js Line2调用toJSON()序列化失败问题求助

Three.js v146中Line2调用toJSON报错的解决方案

问题原因

Line2、LineGeometry、LineMaterial属于Three.js examples目录下的扩展组件,并非核心库原生支持序列化的对象。默认的Object3D.toJSON()方法没有适配这类扩展对象的内部结构,在处理缓存提取时会因未定义的属性抛出Cannot convert undefined or null to object错误。

解决方案

方案一:重写扩展组件的toJSON方法

通过扩展原型,为Line2、LineGeometry、LineMaterial添加适配的序列化逻辑,让它们能兼容核心库的toJSON体系:

// 重写Line2的toJSON方法,继承Object3D的基础序列化并补充自定义逻辑
Line2.prototype.toJSON = function(meta) {
  const data = THREE.Object3D.prototype.toJSON.call(this, meta);
  
  // 处理LineGeometry的序列化引用
  if (this.geometry) {
    data.geometry = this.geometry.toJSON(meta).uuid;
  }
  
  // 处理LineMaterial的序列化引用
  if (this.material) {
    data.material = this.material.toJSON(meta).uuid;
  }
  
  return data;
};

// 为LineGeometry添加toJSON方法,继承BufferGeometry的序列化
LineGeometry.prototype.toJSON = function(meta) {
  const data = THREE.BufferGeometry.prototype.toJSON.call(this, meta);
  data.type = 'LineGeometry'; // 指定类型,反序列化时需要识别
  return data;
};

// 为LineMaterial添加toJSON方法,继承Material的序列化并补充特有属性
LineMaterial.prototype.toJSON = function(meta) {
  const data = THREE.Material.prototype.toJSON.call(this, meta);
  data.type = 'LineMaterial';
  // 补充LineMaterial特有的配置项
  data.linewidth = this.linewidth;
  data.worldUnits = this.worldUnits;
  data.dashed = this.dashed;
  data.alphaToCoverage = this.alphaToCoverage;
  return data;
};

方案二:手动构建自定义序列化对象

如果不想修改原型,可以直接提取Line2的关键参数,构建自定义的可序列化对象:

function serializeLine2(lineObj) {
  return {
    type: 'Line2',
    uuid: lineObj.uuid,
    // 基础变换属性
    position: {
      x: lineObj.position.x,
      y: lineObj.position.y,
      z: lineObj.position.z
    },
    rotation: {
      x: lineObj.rotation.x,
      y: lineObj.rotation.y,
      z: lineObj.rotation.z
    },
    scale: {
      x: lineObj.scale.x,
      y: lineObj.scale.y,
      z: lineObj.scale.z
    },
    // LineGeometry数据
    geometry: {
      type: 'LineGeometry',
      positions: Array.from(lineObj.geometry.attributes.position.array)
    },
    // LineMaterial配置
    material: {
      type: 'LineMaterial',
      color: lineObj.material.color.getHex(),
      linewidth: lineObj.material.linewidth,
      worldUnits: lineObj.material.worldUnits,
      dashed: lineObj.material.dashed,
      alphaToCoverage: lineObj.material.alphaToCoverage,
      transparent: lineObj.material.transparent,
      opacity: lineObj.material.opacity,
      depthWrite: lineObj.material.depthWrite,
      depthTest: lineObj.material.depthTest
    }
  };
}

// 使用示例
const serializedData = serializeLine2(line);
const jsonStr = JSON.stringify(serializedData);

关于是否是BUG/缺失功能

这属于Line2这类扩展组件的功能缺失。Three.js核心的toJSON序列化体系仅针对内置核心对象做了完整适配,examples中的扩展组件通常没有默认实现序列化支持。如果需要官方层面的支持,可以在Three.js的GitHub仓库提交issue反馈该需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 11:23:17