Skip to content

精灵模型 Sprite

精灵模型Sprite

创建精灵模型

  1. 创建精灵模型材质

    js
    // 创建精灵材质对象SpriteMaterial
    const spriteMaterial = new THREE.SpriteMaterial({
      color: 0x00ffff, //设置颜色
    });
  2. 创建精灵模型

    • 创建精灵模型对象不需要创建几何体对象 Geometry
    • 精灵模型 Sprite 默认是一个矩形形状,默认长宽都是 1,默认在坐标原点位置
    js
    // 创建精灵模型对象,不需要几何体geometry参数
    const sprite = new THREE.Sprite(spriteMaterial);
    const mesh = new THREE.Mesh(geometry, material);

属性

  • 位置.position
js
sprite.position.set(0, 50, 0);
  • 缩放.scale
js
// 控制精灵大小
console.log("sprite.scale", sprite.scale);
sprite.scale.set(50, 25, 1); //只需要设置x、y两个分量就可以
  • SpriteMaterial旋转.rotation
js
const spriteMaterial = new THREE.SpriteMaterial({
  rotation: Math.PI / 4, //旋转精灵对象45度,弧度值
});

对比矩形平面

js
// 尺寸相同的Sprite和矩形平面Mesh
const sprite = new THREE.Sprite(spriteMaterial);
sprite.scale.set(50, 25, 1);
const geometry = new THREE.PlaneGeometry(50, 25);
const mesh = new THREE.Mesh(geometry, material);

尺寸大小没区别, 区别在于旋转三维场景时, Sprite矩形平面会始终平行于屏幕,而矩形平面 Mesh 的角度会跟着旋转

精灵模型标注场景(贴图)

设置颜色贴图

js
const texture = new THREE.TextureLoader().load("./光点.png");
const spriteMaterial = new THREE.SpriteMaterial({
  map: texture, //设置精灵纹理贴图
});

属性.transparent

SpriteMaterial.transparent默认是 true

js
const spriteMaterial = new THREE.SpriteMaterial({
  transparent: true, //SpriteMaterial默认是true
});

.color.map 混合

js
const spriteMaterial = new THREE.SpriteMaterial({
  color: 0x00ffff, //设置颜色
  map: texture, //设置精灵纹理贴图
});

Sprite标注三维场景

创建一个标注, 实际开发常见中给建筑或者机器创建地标和标识信息

  1. 创建一个长方几何体

    js
    const geometry = new THREE.BoxGeometry(25, 100, 50);
    geometry.translate(0, 50, 0);
    // mesh顶部中心添加标注,顶部中心坐标是(0,100,0)
    const mesh = new THREE.Mesh(geometry, material);
  2. 创建Sprite并添加到长方体顶部中心

    js
    sprite.scale.set(10, 10, 1);
    sprite.position.set(0, 100 + 10 / 2, 0); //设置位置,要考虑sprite尺寸影响

模拟下雪、下雨

1. 为Sprite添加透明雨滴贴图

js
const texture = new THREE.TextureLoader().load("./雨滴.png");
const spriteMaterial = new THREE.SpriteMaterial({
  map: texture,
});
const sprite = new THREE.Sprite(spriteMaterial);

2. 在 3D 空间随机分布

js
const group = new THREE.Group();
for (let i = 0; i < 16000; i++) {
  // 精灵模型共享材质
  const sprite = new THREE.Sprite(spriteMaterial);
  group.add(sprite);
  sprite.scale.set(1, 1, 1);
  // 设置精灵模型位置,在长方体空间上上随机分布
  const x = 1000 * (Math.random() - 0.5);
  const y = 600 * Math.random();
  const z = 1000 * (Math.random() - 0.5);
  sprite.position.set(x, y, z);
}

3. 周期性改变雨滴 Sprite 位置

js
function loop() {
  // loop()每次执行都会更新雨滴的位置,进而产生动画效果
  group.children.forEach((sprite) => {
    // 雨滴的y坐标每次减1
    sprite.position.y -= 1;
    if (sprite.position.y < 0) {
      // 如果雨滴落到地面,重置y,从新下落
      sprite.position.y = 600;
    }
  });
  requestAnimationFrame(loop);
}
loop();

4. 根据时间计算 Sprite 位置

js
const clock = new THREE.Clock();
function loop() {
  // loop()两次执行时间间隔
  const t = clock.getDelta();
  group.children.forEach((sprite) => {
    // 雨滴的y坐标每次减t*60
    sprite.position.y -= t * 60;
    if (sprite.position.y < 0) {
      sprite.position.y = 600;
    }
  });
  requestAnimationFrame(loop);
}
loop();

5. 调整相机镜头

相机镜头附近的雨滴偏大, 调大相机的near可以解决

js
// near调整为 50
const camera = new THREE.PerspectiveCamera(30, width / height, 50, 3000);