经纬志
首页 / three.js / API 文档

Sprite

先看结论

永远正对相机的平面片,常用来做地名标注、图标与光晕。

最后验证 2026-11-03 · three.js 0.160.0 · 更新 2026-10-28 · 引用本文
new THREE.Sprite(material) → Sprite

构造参数

参数默认说明
materialnew SpriteMaterial()必须是 SpriteMaterial 或其子类,普通网格材质无效

属性

属性说明
material材质实例,改颜色与贴图都从这里入手
centerVector2,默认 (0.5, 0.5),即锚点位于片中心
position / scale继承自 Object3D,片的世界尺寸由 scale 决定
isSprite只读标记

方法

方法说明
raycast(raycaster, intersects)按片的外接矩形做命中判断,不检查透明像素
copy(source) / clone()复制属性,几何体共享
lookAt()继承自 Object3D,但对 Sprite 没有实际效果,朝向由渲染器强制决定

SpriteMaterial 的关键参数

参数默认说明
color0xffffff与贴图相乘的底色
mapnull标注内容,通常来自 Canvas 生成的纹理
rotation0片绕自身中心旋转的角度,单位弧度
sizeAttenuationtrue为 false 时尺寸不随距离变化,等效于固定像素大小
transparenttrue默认开启混合,边缘才能透明
depthTesttrue关闭后标注永远画在最前,会失去遮挡关系
fogtrue是否随距离融入雾色

用 Canvas 生成标注

function makeLabel(text) {
  const canvas = document.createElement('canvas');
  canvas.width = 256;
  canvas.height = 64;

  const ctx = canvas.getContext('2d');
  ctx.fillStyle = 'rgba(13, 17, 23, 0.82)';
  ctx.fillRect(0, 0, 256, 64);
  ctx.strokeStyle = '#4f9ef8';
  ctx.lineWidth = 3;
  ctx.strokeRect(1.5, 1.5, 253, 61);

  ctx.fillStyle = '#e6e8ec';
  ctx.font = '600 30px sans-serif';
  ctx.textAlign = 'center';
  ctx.textBaseline = 'middle';
  ctx.fillText(text, 128, 34);

  const texture = new THREE.CanvasTexture(canvas);
  texture.colorSpace = THREE.SRGBColorSpace;

  const sprite = new THREE.Sprite(new THREE.SpriteMaterial({
    map: texture,
    transparent: true,
    depthWrite: false
  }));
  sprite.scale.set(8, 2, 1);   // 8 : 2 与画布 256 : 64 同比例
  return sprite;
}

scale 必须与画布的宽高比一致,否则文字会被拉伸。 画布尺寸取 2 的幂(256、512)并不会影响 WebGL2 下的采样, 但可以省掉部分驱动的缩放开销。

标注不随距离变形

// 远处的标注保持相同的屏幕大小
material.sizeAttenuation = false;
sprite.scale.set(0.08, 0.02, 1);   // 此时数值只表达相对比例

// 让标注始终可见,不被建筑遮挡
material.depthTest = false;
sprite.renderOrder = 10;

sizeAttenuation 为 false 时,scale 不再对应世界单位, 而是与屏幕像素挂钩,具体比例取决于视口高度。 关闭 depthTest 后所有这类标注都会浮在最上层, 密集标注容易互相压盖,需要按层级设置 renderOrder 并做屏幕空间的避让。

与 Points 的分工

每个 Sprite 是一次独立的绘制调用,几百个标注还能接受, 上万个就会拖慢帧率。只需要固定形状的点符号时,用 Points 配合一张纹理更划算;标注确实需要各自的文字内容时, 才考虑把文字预渲染成图集,再用实例化或 Points 的 UV 偏移取用。

Sprite 不受 lookAt 控制。它始终面向相机, 想让标注随地形倾斜、贴在坡面上,应改用带贴图的 Mesh, 并把朝向写入几何体或四元数。

标注只是图形。three.js 不管理名称、层级、避让与符号规则, 这些都属于渲染之外的业务逻辑。

引用本文

经纬志(2026)。《Sprite》。https://www.jingweizhi.com/three/api/sprite.html(访问日期 2026-11-03)。