參考資料
- 精靈模型Sprite
- …
- Sprite模擬下雨、下雪
知識點
注:基于Three.jsv0.155.0
- 精靈模型Sprite
- 精靈模型標注場景(貼圖)
- Sprite模擬下雨、下雪
精靈模型Sprite
Three.js的精靈模型Sprite
和Threejs的網格模型Mesh
一樣都是模型對象,父類都是Object3D
,關于精靈模型對象Sprite
的方法和屬性除了可以查看文檔Sprite,也可以查看父類Object3D
。
Sprite
與矩形平面Mesh
的區別在于,當你旋轉三維場景的時候,如果通過相機控件OrbitControls旋轉測試,你可以發現Sprite
矩形平面會始終平行于Canvas畫布或者說屏幕,而矩形平面Mesh
的姿態角度會跟著旋轉,不一定平行于canvas畫布。
代碼實現
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Three.js</title>
</head><body></body><!-- 具體路徑配置,你根據自己文件目錄設置,我的是課件中源碼形式 --><script type="importmap">{"imports": {"three": "./js/three.module.js","three/addons/": "../three.js/examples/jsm/"}}</script><script type="module">import * as THREE from 'three';import { OrbitControls } from 'three/addons/controls/OrbitControls.js';const width = 800const height = 500// 場景const scene = new THREE.Scene();const texture = new THREE.TextureLoader().load("./img/6.JPG");// 創建精靈材質對象SpriteMaterialconst spriteMaterial = new THREE.SpriteMaterial({// color:0x00ffff,//設置顏色rotation:Math.PI/4,//旋轉精靈對象45度,弧度值map: texture, //設置精靈紋理貼圖transparent:true,//SpriteMaterial默認是true});const geometry = new THREE.BoxGeometry(25, 100, 50);geometry.translate(0, 50, 0);// 材質const material = new THREE.MeshBasicMaterial({color: 0x00ff00,transparent: true,opacity: 0.5});// mesh頂部中心添加標注,頂部中心坐標是(0,100,0)const mesh = new THREE.Mesh(geometry, material);scene.add(mesh);// 創建精靈模型對象,不需要幾何體geometry參數const sprite = new THREE.Sprite(spriteMaterial);// sprite.scale.set(100, 100, 1); //只需要設置x、y兩個分量就可以sprite.scale.set(10, 10, 1);// sprite.position.set(0,50,0);sprite.position.set(0, 100 + 10/2, 0);//設置位置,要考慮sprite尺寸影響scene.add(sprite);console.log(sprite);// 環境光const ambientLight = new THREE.AmbientLight( 0xffffff, 0.2);scene.add( ambientLight );// 坐標系const axes = new THREE.AxesHelper(200);scene.add(axes);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)}scene.add(group);const camera = new THREE.PerspectiveCamera(75, width/height, 0.1, 1000);camera.position.set(200, 200, 200);camera.lookAt(scene.position);// 渲染器const renderer = new THREE.WebGLRenderer();renderer.setSize(width, height);renderer.render(scene, camera);document.body.appendChild(renderer.domElement);const clock = new THREE.Clock();function loop() {// loop()兩次執行時間間隔const t = clock.getDelta();group.children.forEach(sprite => {// 雨滴的y坐標每次減t*60sprite.position.y -= t*60;if (sprite.position.y < 0) {sprite.position.y = 600;}});requestAnimationFrame(loop);renderer.render(scene, camera);}loop();// 控制器const controls = new OrbitControls(camera, renderer.domElement);controls.addEventListener('change', () => {// 因為動畫渲染了,所以這里可以省略// renderer.render(scene, camera);});</script>
</html>