这节开始我们来做一个有意思的 3D 场景:
一尊大佛坐在中央,地下一圈圈转动的金色花纹,空中飘舞着金色的经文,然后背景音乐是念经的声音,旁边有个木鱼可以敲,然后敲的时候会有功德 +1 的粒子效果

这个佛光很明显就是粒子效果,很适合作为粒子的实战。
我们来写一下:
npx create-vite online-buddha

创建项目,进入项目,安装依赖:
pnpm install
pnpm install --save three
pnpm install --save-dev @types/three
改下 src/main.js
import './style.css';
import * as THREE from 'three';
import {
OrbitControls
} from 'three/addons/controls/OrbitControls.js';
import mesh from './mesh.js';
const scene = new THREE.Scene();
scene.add(mesh);
const light = new THREE.DirectionalLight(0xffffff);
light.position.set(500, 300, 600);
scene.add(light);
const light2 = new THREE.AmbientLight();
scene.add(light2);
const axesHelper = new THREE.AxesHelper(1000);
scene.add(axesHelper);
const width = window.innerWidth;
const height = window.innerHeight;
const camera = new THREE.PerspectiveCamera(60, width / height, 1, 10000);
camera.position.set(0, 500, 500);
camera.lookAt(0, 0, 0);
const renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(width, height)
function render() {
renderer.render(scene, camera);
requestAnimationFrame(render);
}
render();
document.body.append(renderer.domElement);
const controls = new OrbitControls(camera, renderer.domElement);
创建 Scene、Light、Camera、Renderer
改下 style.css
body {
margin: 0;
}
然后创建 mesh.js
import * as THREE from 'three';
const geometry = new THREE.BoxGeometry(100, 100, 100);
const material = new THREE.MeshPhongMaterial({
color: 'orange'
})
const mesh = new THREE.Mesh(geometry, material);
export default mesh;
先画个立方体
跑一下:
npm run dev


然后我们去找个佛祖的模型:
https://sketchfab.com/3d-models/buddha-ae0f992ba88842649d4655ba650c15d2


下载这个 4M 的精简模型就行。
放到 public 目录:

加载下:
import * as THREE from 'three';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
const loader = new GLTFLoader();
const buddha = new THREE.Group();
export const loadPromise = loader.loadAsync("./buddha.glb");
loadPromise.then(gltf => {
buddha.add(gltf.scene);
console.log(gltf);
gltf.scene.scale.setScalar(50);
const box = new THREE.BoxHelper(gltf.scene);
buddha.add(box);
})
export default buddha;
放大 50 倍,加一个包围盒
看下效果:

让它绕 y 轴旋转 180 度,给它一个 name:

buddha.rotateY(Math.PI);
buddha.name = 'buddha';
然后相机焦点调到佛祖中央的位置:

loadPromise.then(() => {
const box3 = new THREE.Box3();
box3.expandByObject(mesh);
const center = box3.getCenter(new THREE.Vector3());
camera.lookAt(center.x, center.y, center.z);
controls.target.set(center.x, center.y, center.z);
})
用包围盒拿到佛祖的中央位置,注意这里要等模型加载完。
把相机焦点和 OrbitControls 的焦点移到佛祖中央位置。
试一下:

现在整个 3D 场景的中心点就是佛祖中央了。
我们给佛祖调成金色:

gltf.scene.traverse(obj => {
if(obj.isMesh) {
console.log(obj.name, obj);
}
})
先打印下所有 mesh:

不用区分那么细了,整体改颜色就行。

obj.material.color.set('gold')

光线强一点:

const light = new THREE.DirectionalLight(0xffffff, 25);
light.position.set(0, 200, 500);
camera.position.set(0, 200, 600);
改下灯光、相机位置。

这样我们的佛祖就准备好了。
案例代码上传了小册仓库
总结
这节开始更在线佛祖项目。
我们从 sketchfab 找了一个模型,用包围盒计算出模型中央位置,把相机焦点放到中央,然后调了一下材质颜色,灯光强度。
现在佛祖就在 3D 场景中央了,并且颜色也是对的。
下节加上佛光效果。