首页 / three.js / API 文档
Sprite
先看结论
永远正对相机的平面片,常用来做地名标注、图标与光晕。
new THREE.Sprite(material) → Sprite
构造参数
| 参数 | 默认 | 说明 |
|---|---|---|
material | new SpriteMaterial() | 必须是 SpriteMaterial 或其子类,普通网格材质无效 |
属性
| 属性 | 说明 |
|---|---|
material | 材质实例,改颜色与贴图都从这里入手 |
center | Vector2,默认 (0.5, 0.5),即锚点位于片中心 |
position / scale | 继承自 Object3D,片的世界尺寸由 scale 决定 |
isSprite | 只读标记 |
方法
| 方法 | 说明 |
|---|---|
raycast(raycaster, intersects) | 按片的外接矩形做命中判断,不检查透明像素 |
copy(source) / clone() | 复制属性,几何体共享 |
lookAt() | 继承自 Object3D,但对 Sprite 没有实际效果,朝向由渲染器强制决定 |
SpriteMaterial 的关键参数
| 参数 | 默认 | 说明 |
|---|---|---|
color | 0xffffff | 与贴图相乘的底色 |
map | null | 标注内容,通常来自 Canvas 生成的纹理 |
rotation | 0 | 片绕自身中心旋转的角度,单位弧度 |
sizeAttenuation | true | 为 false 时尺寸不随距离变化,等效于固定像素大小 |
transparent | true | 默认开启混合,边缘才能透明 |
depthTest | true | 关闭后标注永远画在最前,会失去遮挡关系 |
fog | true | 是否随距离融入雾色 |
用 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)。