Threejs幼儿园几何体喷泉动画代码
代码:<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>ThreeJS示例:方块体和球体运动</title>
</head>
<body style="margin: 0;">
<!-- threejs 模块导入映射目录结构, 里面不能有其它任何多余的东西 -->
<script type="importmap">
{
"imports": {
"three": "https://esm.sh/three@0.176.0?target=es2022",
"three/addons/": "https://esm.sh/three@0.176.0/addons/"
}
}
</script>
<script type="module">
// 导入 three 相关模块
import * as THREE from 'three'; // 主库
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; // 相机控制库
import { RapierPhysics } from 'three/addons/physics/RapierPhysics.js'; // 物理引擎库
let camera, scene, renderer; // 相机、场景、渲染器变量
let physics, position; // 物理模拟对象实例话对象、位置向量变量
let boxes, spheres; // 方块体、球体变量
init(); // 运行程序主函数
// 主函数 :异步运行
async function init() {
// 引入RapierPhysics库并初始化
physics = await RapierPhysics();
// 用于设置物体位置的向量
position = new THREE.Vector3();
// 初始化场景、相机和渲染器
camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 100);
camera.position.set(- 1, 1.5, 2);
camera.lookAt(0, 0.5, 0);
scene = new THREE.Scene();
scene.background = new THREE.Color(0x666666); // 场景背景色
// 添加光源
const hemiLight = new THREE.HemisphereLight(); // 半球光
scene.add(hemiLight);
const dirLight = new THREE.DirectionalLight(0xffffff, 3); // 方向光
dirLight.position.set(5, 5, 5); // 方向光位置
dirLight.castShadow = true; // 允许产生阴影
dirLight.shadow.camera.zoom = 2; // 阴影缩放
scene.add(dirLight);
// 添加地板
const floor = new THREE.Mesh(
new THREE.BoxGeometry(10, 5, 10),
new THREE.ShadowMaterial({color: 0x444444})
);
floor.position.y = - 2.5;
floor.receiveShadow = true;
floor.userData.physics = {mass: 0}; // 质量为 0
scene.add(floor);
// 初始化材质
const material = new THREE.MeshLambertMaterial();
const matrix = new THREE.Matrix4();
const color = new THREE.Color();
// 初始化盒子实例化网格
const geometryBox = new THREE.BoxGeometry(0.075, 0.075, 0.075);
boxes = new THREE.InstancedMesh(geometryBox, material, 400);
boxes.instanceMatrix.setUsage(THREE.DynamicDrawUsage); // 每帧更新
boxes.castShadow = true;
boxes.receiveShadow = true;
boxes.userData.physics = {mass: 1}; // 质量为 1
scene.add(boxes);
// 随机生成盒子的位置和颜色
for (let i = 0; i < boxes.count; i ++) {
matrix.setPosition( Math.random() - 0.5, Math.random() * 2, Math.random() - 0.5 );
boxes.setMatrixAt(i, matrix);
boxes.setColorAt(i, color.setHex( 0xffffff * Math.random() ));
}
// 初始化球体实例化网格
const geometrySphere = new THREE.IcosahedronGeometry(0.05, 4);
spheres = new THREE.InstancedMesh(geometrySphere, material, 400);
spheres.instanceMatrix.setUsage(THREE.DynamicDrawUsage); // 每帧更新
spheres.castShadow = true;
spheres.receiveShadow = true;
spheres.userData.physics = {mass: 1}; // 质量为 1
scene.add(spheres);
// 随机生成球体的位置和颜色
for (let i = 0; i < spheres.count; i ++ ) {
matrix.setPosition(Math.random() - 0.5, Math.random() * 2, Math.random() - 0.5);
spheres.setMatrixAt(i, matrix);
spheres.setColorAt(i, color.setHex( 0xffffff * Math.random() ));
}
// 将场景添加到物理引擎
physics.addScene(scene);
// 初始化渲染器和性能监控
renderer = new THREE.WebGLRenderer({antialias: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setAnimationLoop(animate); // 循环调用动画函数
renderer.shadowMap.enabled = true;
document.body.appendChild(renderer.domElement );
// 初始化控制器
const controls = new OrbitControls(camera, renderer.domElement);
controls.target.y = 0.5;
controls.update();
// 每隔1/60秒随机改变盒子和球体的位置
setInterval( () => {
let index = Math.floor(Math.random() * boxes.count);
position.set(0, Math.random() + 1, 0);
physics.setMeshPosition(boxes, position, index);
index = Math.floor(Math.random() * spheres.count);
position.set(0, Math.random() + 1, 0);
physics.setMeshPosition(spheres, position, index);
}, 1000 / 60);
}
// 运行动画函数
function animate() {
renderer.render(scene, camera);
}
</script>
</body>
</html>以上代码可以存为本地 .html 文档,然后用浏览器打开。也可以到我网站的 简易编辑器 运行以查看效果。
代码注释凭我个人理解添加,不一定准确,仅供参考。
画布缩小到一定程度,可以看到球体到透明玻璃地板边缘后下落的场景,宇宙也是有尽头的{:4_173:} 我就看看你写的中文字。。{:4_173:} 震撼的演示效果,谢谢老师大佬级分享{:4_191:} 这个好,可以不仅在幼儿园做喷泉了,还能在动物园做{:4_173:} 这个解说真仔细,黑黑辛苦了{:4_187:} 红影 发表于 2025-5-7 22:18
这个解说真仔细,黑黑辛苦了
{:4_190:} 很神奇,这就是老师的代码。{:4_190:} 梦江南 发表于 2025-5-8 09:23
很神奇,这就是老师的代码。
这是 three.js 官方代码,我只是略作修改和注释 马黑黑 发表于 2025-5-7 23:19
谢大咖{:4_187:} 红影 发表于 2025-5-9 17:30
谢大咖
{:4_203:} 马黑黑 发表于 2025-5-9 18:20
{:4_187:} 红影 发表于 2025-5-9 20:45
谢花 马黑黑 发表于 2025-5-9 21:23
谢花
不客气{:4_173:} 红影 发表于 2025-5-9 22:44
不客气
应该的 马黑黑 发表于 2025-5-9 22:50
应该的
应该出了那么多效果,星星、战马、喷泉。。。{:4_173:} 红影 发表于 2025-5-10 10:33
应该出了那么多效果,星星、战马、喷泉。。。
{:4_196:} 马黑黑 发表于 2025-5-10 11:26
{:4_187:} 红影 发表于 2025-5-10 13:40
谢花 马黑黑 发表于 2025-5-10 14:17
谢花
别谢,开着的更好{:4_173:}