其他
需要构建 Babylon.js 实时…
适用于基于 Babylon.js 7.x 开发浏览器端实时 3D 体验、游戏、交互可视化和 WebXR 应用。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 48/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 85/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 54/100 ×0.15
适用场景
需要构建 Babylon.js 实时 3通用
解决思路
- 初始化基础 Engine/Scene:获取 canvas,创建 new BABYLON.Engine(canvas, true, { preserveDrawingBuffer: true, stencil: true });创建 new BABYLON.Scene(engine);用 engine.runRenderLoop(() => { scene.render(); }) 启动渲染;监听 window resize 并调用 engine.resize()。
- 用 ES6/TypeScript 初始化:从 @babylonjs/core 分别 import Engine、Scene、FreeCamera、Vector3、HemisphericLight、CreateSphere;创建 Engine 与 Scene;创建 FreeCamera('camera1', new Vector3(0,5,-10), scene),调用 setTarget(Vector3.Zero()) 和 attachControl(canvas,true);创建 HemisphericLight('light1', new Vector3(0,1,0), scene) 并设置 intensity=0.7;用 CreateSphere('sphere1',{segments:16,diameter:2},scene) 创建球并设置 position.y=2;runRenderLoop 渲染。
- 配置 Scene 以优化大量 mesh:new BABYLON.Scene(engine, { useGeometryUniqueIdsMap: true, useMaterialMeshMap: true, useClonedMeshMap: true })。
- 创建 FreeCamera(FPS 风格):new BABYLON.FreeCamera('camera1', new BABYLON.Vector3(0,5,-10), scene);setTarget(BABYLON.Vector3.Zero());attachControl(canvas,true);设置 speed、angularSensibility,用 keysUp/keysDown/keysLeft/keysRight 绑定 W/S/A/D 键码。
- 创建 ArcRotateCamera(轨道):new BABYLON.ArcRotateCamera('camera', -Math.PI/2, Math.PI/2.5, 15, new BABYLON.Vector3(0,0,0), scene);attachControl(canvas,true);设置 lowerRadiusLimit、upperRadiusLimit、lowerBetaLimit、upperBetaLimit 限制。
- 创建 UniversalCamera(高级):new BABYLON.UniversalCamera('camera', new BABYLON.Vector3(0,5,-10), scene);setTarget(BABYLON.Vector3.Zero());attachControl(canvas,true);设置 checkCollisions=true、applyGravity=true、ellipsoid=new BABYLON.Vector3(1,1,1)。
- HemisphericLight(环境光):new BABYLON.HemisphericLight('light1', new BABYLON.Vector3(0,1,0), scene);设置 intensity、diffuse、specular、groundColor。
- DirectionalLight(太阳光)与阴影:new BABYLON.DirectionalLight('dirLight', new BABYLON.Vector3(-1,-2,-1), scene);设置 position 和 intensity;创建 new BABYLON.ShadowGenerator(1024, light);设置 useExponentialShadowMap=true。
- PointLight(点光):new BABYLON.PointLight('pointLight', new BABYLON.Vector3(0,10,0), scene);设置 intensity、diffuse、specular;设置 range 和 radius。
- SpotLight(聚光):new BABYLON.SpotLight('spotLight', new BABYLON.Vector3(0,10,0), new BABYLON.Vector3(0,-1,0), Math.PI/3, 2, scene);设置 intensity。
- 优化光照影响范围:用 light.includedOnlyMeshes=[mesh1,mesh2,mesh3] 只影响指定 mesh;或用 light.excludedMeshes=[mesh4,mesh5] 排除指定 mesh。
- 创建内置 Box:BABYLON.MeshBuilder.CreateBox('box', { size:2, width:2, height:2, depth:2 }, scene)。
- 创建内置 Sphere:BABYLON.MeshBuilder.CreateSphere('sphere', { diameter:2, segments:32, diameterX:2, diameterY:2, diameterZ:2, arc:1, slice:1 }, scene)。
- 创建内置 Cylinder:BABYLON.MeshBuilder.CreateCylinder('cylinder', { height:3, diameter:2, tessellation:24 }, scene)。
- 创建内置 Plane:BABYLON.MeshBuilder.CreatePlane('plane', { size:5, width:5, height:5 }, scene)。
- 创建内置 Ground:BABYLON.MeshBuilder.CreateGround('ground', { width:10, height:10, subdivisions:2 }, scene)。
- 从高度图创建 Ground:BABYLON.MeshBuilder.CreateGroundFromHeightMap('ground', 'heightmap.png', { width:100, height:100, subdivisions:100, minHeight:0, maxHeight:10 }, scene)。
- 创建内置 Torus:BABYLON.MeshBuilder.CreateTorus('torus', { diameter:3, thickness:1, tessellation:16 }, scene)。
- 创建内置 TorusKnot:BABYLON.MeshBuilder.CreateTorusKnot('torusKnot', { radius:2, tube:0.6, radialSegments:64, tubularSegments:8, p:2, q:3 }, scene)。
- 变换 mesh:设置 mesh.position = new BABYLON.Vector3(0,5,10) 或单独改 x/y;设置 rotation(弧度)或 rotation.y;设置 scaling 或 scaling.x;调用 mesh.lookAt(new BABYLON.Vector3(0,0,0));设置 childMesh.parent = parentMesh。
- 设置 mesh 属性:isVisible;visibility(0 不可见到 1 完全可见);isPickable;checkCollisions;cullingStrategy=BABYLON.AbstractMesh.CULLINGSTRATEGY_BOUNDINGSPHERE_ONLY;receiveShadows=true。
- 创建 StandardMaterial:new BABYLON.StandardMaterial('material', scene);设置 diffuseColor、specularColor、emissiveColor、ambientColor;设置 diffuseTexture/specularTexture/emissiveTexture/ambientTexture/bumpTexture/opacityTexture;设置 alpha、backFaceCulling、wireframe、specularPower;赋给 mesh.material。
- 创建 PBRMaterial:new BABYLON.PBRMaterial('pbr', scene);金属工作流设置 albedoColor、albedoTexture、metallic、roughness、metallicTexture;镜面工作流设置 albedoTexture、reflectivityTexture;设置 environmentTexture=BABYLON.CubeTexture.CreateFromPrefilteredData('environment.dds', scene);设置 bumpTexture、ambientTexture、emissiveTexture;赋给 mesh.material。
- 创建 MultiMaterial:new BABYLON.MultiMaterial('multiMat', scene);multiMat.subMaterials.push(material1/material2/material3);赋给 mesh.material;设置 mesh.subMeshes=[] 并 push 多个 new BABYLON.SubMesh(...)。
- 导入 GLTF/GLB:用 BABYLON.SceneLoader.Append('path/to/', 'model.gltf', scene, callback);用 BABYLON.SceneLoader.ImportMesh('', 'path/to/', 'model.gltf', scene, meshesCallback);用 await BABYLON.SceneLoader.ImportMeshAsync(null, 'https://assets.babylonjs.com/meshes/', 'village.glb', scene);用 await BABYLON.SceneLoader.AppendAsync('', 'data:' + arrayBuffer, scene) 从二进制加载。
- 用 Asset Manager 批量加载:new BABYLON.AssetsManager(scene);addMeshTask('model', '', 'path/to/', 'model.gltf') 并在 onSuccess 中设置 loadedMeshes[0].position;addTextureTask('texture', 'texture.png') 并在 onSuccess 中赋给 material.diffuseTexture;在 onFinish 中启动 engine.runRenderLoop;调用 assetsManager.load()。
- 配置 Havok 物理:import HavokPhysics from '@babylonjs/havok';const havokInstance = await HavokPhysics();const havokPlugin = new BABYLON.HavokPlugin(true, havokInstance);scene.enablePhysics(new BABYLON.Vector3(0,-9.8,0), havokPlugin)。
- 创建物理聚合:用 new BABYLON.PhysicsAggregate(sphere, BABYLON.PhysicsShapeType.SPHERE, { mass:1, restitution:0.75 }, scene);地面用 new BABYLON.PhysicsAggregate(ground, BABYLON.PhysicsShapeType.BOX, { mass:0 }, scene) 作为静态体。
- 选择物理形状:BABYLON.PhysicsShapeType.SPHERE、BOX、CAPSULE、CYLINDER、CONVEX_HULL、MESH、HEIGHTFIELD。
- 控制物理体:const body=aggregate.body;用 body.applyForce(new BABYLON.Vector3(0,10,0), new BABYLON.Vector3(0,0,0));body.applyImpulse(...);body.setLinearVelocity(...);body.setAngularVelocity(...);body.setMassProperties({ mass:2 });body.setCollisionCallbackEnabled(true)。
- 直接创建并启动动画:BABYLON.Animation.CreateAndStartAnimation('anim', mesh, 'position.y', 30, 120, mesh.position.y, 10, BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE)。
- 用 Animation 类:new BABYLON.Animation('myAnimation', 'position.x', 30, BABYLON.Animation.ANIMATIONTYPE_FLOAT, BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE);用 setKeys([{frame:0,value:0},{frame:30,value:10},{frame:60,value:0}]);mesh.animations.push(animation);scene.beginAnimation(mesh,0,60,true)。
- 用 AnimationGroup:new BABYLON.AnimationGroup('group', scene);addTargetedAnimation(animation1, mesh1) 和 addTargetedAnimation(animation2, mesh2);调用 play/pause/stop;设置 speedRatio=2.0;用 onAnimationEndObservable.add(...) 监听结束。
- 播放骨骼动画:从导入结果取 skeleton=result.skeletons[0];用 skeleton.getAnimationRanges() 获取范围;scene.beginAnimation(skeleton,0,100,true);或 result.animationGroups[0].play();result.animationGroups[0].setWeightForAllAnimatables(0.5)。
- 快速搭建默认环境:scene.createDefaultCameraOrLight(true,true,true);scene.createDefaultEnvironment({ createGround:true, createSkybox:true, skyboxSize:150, groundSize:50 });再创建自己的 mesh。
- 异步加载场景:async function createScene 中创建 Scene、ArcRotateCamera、HemisphericLight;await BABYLON.SceneLoader.ImportMeshAsync(null,'https://assets.babylonjs.com/meshes/','village.glb',scene);await HavokPhysics() 并 new BABYLON.HavokPlugin 后 scene.enablePhysics;在 createScene().then(scene => engine.runRenderLoop(...)) 中启动。
- 交互拾取:scene.onPointerDown=function(evt,pickResult){ if(pickResult.hit){ 读取 pickedMesh.name 和 pickedPoint;可改 pickedMesh.material.emissiveColor 高亮 } };或给 mesh.actionManager=new BABYLON.ActionManager(scene),registerAction(new BABYLON.ExecuteCodeAction(BABYLON.ActionManager.OnPickTrigger, function(){...}))。
- 后处理效果:new BABYLON.DefaultRenderingPipeline('pipeline', true, scene, [camera]);设置 samples、fxaaEnabled、bloomEnabled、bloomThreshold、bloomWeight、bloomKernel;设置 depthOfFieldEnabled 和 depthOfFieldBlurLevel、focusDistance、focalLength;用 new BABYLON.GlowLayer('glow', scene) 并设 intensity;用 new BABYLON.HighlightLayer('highlight', scene) 并 addMesh(mesh, BABYLON.Color3.Green())。
- 创建 GUI:import { AdvancedDynamicTexture, Button, TextBlock, Rectangle } from '@babylonjs/gui';用 BABYLON.GUI.AdvancedDynamicTexture.CreateFullscreenUI('UI');用 BABYLON.GUI.Button.CreateSimpleButton('button','Click Me') 设置 width/height/color/background 和 onPointerUpObservable;创建 TextBlock 设置 text/color/fontSize;用 CreateForMesh(plane) 创建 3D mesh UI 并 addControl。
- 阴影映射:创建 DirectionalLight 并设置 position;new BABYLON.ShadowGenerator(1024, light);设置 useExponentialShadowMap=true 和 usePoissonSampling=true;用 shadowGenerator.addShadowCaster(sphere) 和 addShadowCaster(box) 添加投射者;设置 ground.receiveShadows=true。
- 粒子系统:new BABYLON.ParticleSystem('particles',2000,scene);particleTexture=new BABYLON.Texture('particle.png',scene);设置 emitter、minEmitBox、maxEmitBox;设置 color1、color2、colorDead;设置 minSize、maxSize、minLifeTime、maxLifeTime、emitRate;设置 direction1、direction2、gravity;调用 particleSystem.start()。
- React 集成:用 useEffect/useRef;在 useEffect 中创建 BABYLON.Engine(canvasRef.current,true) 和 Scene;创建 ArcRotateCamera、HemisphericLight、Sphere;engine.runRenderLoop(() => scene.render());添加 window resize 监听调用 engine.resize();cleanup 中 removeEventListener、scene.dispose()、engine.dispose();返回 canvas ref 并设置宽高 100%。
- WebXR 集成:在 async createScene 中创建 camera、light、sphere、scene.createDefaultEnvironment();await scene.createDefaultXRExperienceAsync({ floorMeshes:[env.ground], disableTeleportation:false });用 xrHelper.input.onControllerAddedObservable.add(controller => controller.onMotionControllerInitObservable.add(motionController => { const trigger=motionController.getMainComponent(); trigger.onButtonStateChangedObservable.add(() => { if(trigger.pressed) console.log('Trigger pressed'); }); }))。
- Node Material:await BABYLON.NodeMaterial.ParseFromSnippetAsync('#SNIPPET_ID', scene);调用 nodeMaterial.build();赋给 mesh.material;或程序化创建 new BABYLON.NodeMaterial('node',scene),用 new BABYLON.InputBlock('position') 并 setAsAttribute('position'),用 new BABYLON.TransformBlock('worldPos'),nodeMaterial.addOutputNode(worldPos)。
- Mesh 优化:用 BABYLON.Mesh.MergeMeshes([mesh1,mesh2,mesh3], true, true, undefined, false, true) 合并;用 mesh.createInstance('instance1') 创建实例;用 mesh.thinInstanceSetBuffer('matrix', buffer, 16) 创建 thin instances;用 mesh.freezeWorldMatrix() 和 material.freeze() 冻结;用 mesh.simplify([{quality:0.8,distance:10},{quality:0.4,distance:50},{quality:0.2,distance:100}], true, BABYLON.SimplificationType.QUADRATIC) 做 LOD。
- Scene 优化:创建 BABYLON.SceneOptimizerOptions 并 addOptimization(new BABYLON.HardwareScalingOptimization(0,1))、ShadowsOptimization(1)、PostProcessesOptimization(2)、LensFlaresOptimization(3)、ParticlesOptimization(4)、TextureOptimization(5,512)、RenderTargetsOptimization(6)、MergeMeshesOptimization(7);new BABYLON.SceneOptimizer(scene, options).start();用 scene.createOrUpdateSelectionOctree();设置 scene.blockMaterialDirtyMechanism=true;设置 scene.skipPointerMovePicking=true;调用 scene.freezeActiveMeshes()。
- 渲染优化:engine.setHardwareScalingLevel(0.5) 降低分辨率;在 scene.onBeforeRenderObservable.add 中读取 engine.getFps(),低于 30 时 setHardwareScalingLevel(2),高于 55 时 setHardwareScalingLevel(1);设置 scene.useDelayedTextureLoading=true;设置 mesh.cullingStrategy=BABYLON.AbstractMesh.CULLINGSTRATEGY_BOUNDINGSPHERE_ONLY。
- 纹理优化:使用压缩纹理 .dds;用 texture.updateSamplingMode(BABYLON.Texture.TRILINEAR_SAMPLINGMODE);设置 texture.anisotropicFilteringLevel=4;使用 KTX2 纹理 .ktx2。
- 避免内存泄漏:不要只 scene.removeMesh(mesh);创建后不需要的 mesh 调用 mesh.dispose();销毁整个场景用 scene.dispose();销毁引擎用 engine.dispose()。
- 避免过多 draw call:不要循环创建 1000 个独立 Box;改为创建一个 Box 后用 box.createInstance('instance'+i) 创建实例,或合并 mesh。
- 避免阻塞主线程:不要在同步循环中创建 10000 个 Sphere;改为 async 增量创建,每 100 个 await new Promise(resolve => setTimeout(resolve,0)) 让出主线程。
- 避免相机无响应:创建 ArcRotateCamera 等相机后必须调用 camera.attachControl(canvas,true)。
- 正确处理异步操作:不要 ImportMesh 后立即 getMeshByName;改用 await BABYLON.SceneLoader.ImportMeshAsync(...) 后再 getMeshByName,或在 ImportMesh 回调中处理 meshes。
- 正确启用物理:不要直接给 mesh 设旧式 physicsImpostor;先 await HavokPhysics()、new BABYLON.HavokPlugin(true,havokInstance)、scene.enablePhysics(new BABYLON.Vector3(0,-9.8,0), havokPlugin),再用 new BABYLON.PhysicsAggregate(...)。
- 自定义着色器:用 BABYLON.Effect.ShadersStore['customVertexShader'] 和 ['customFragmentShader'] 写入 GLSL;创建 new BABYLON.ShaderMaterial('shader', scene, { vertex:'custom', fragment:'custom' }, { attributes:['position','uv'], uniforms:['worldViewProjection'] })。
- 计算着色器:new BABYLON.ComputeShader('compute', engine, { computeSource: ... }),在 computeSource 中声明 layout (local_size_x=8, local_size_y=8, local_size_z=1) in,使用 gl_GlobalInvocationID 和 outputBuffer 写入。
- 程序化纹理:new BABYLON.NoiseProceduralTexture('noise',256,scene);设置 octaves、persistence、animationSpeedFactor;赋给 material.emissiveTexture。
- 调试:scene.debugLayer.show();scene.forceShowBoundingBoxes=true;material.wireframe=true;setInterval(() => console.log('FPS:', engine.getFps()),1000);new BABYLON.SceneInstrumentation(scene) 并设 captureFrameTime=true,读取 instrumentation.frameTimeCounter.average。
- 查阅资源:官方文档 https://doc.babylonjs.com/、Playground https://playground.babylonjs.com/、Forum https://forum.babylonjs.com/、Examples https://doc.babylonjs.com/examples/、NPM @babylonjs/core。
- 版本注意事项:该做法基于 Babylon.js 7.x;使用最新特性前查阅官方文档。
适用边界 · 注意事项
- 如果只是普通 2D 网页动画或 UI 动效,优先用 gsap-scrolltrigger/motion-framer,而不是 Babylon.js。
- 如果团队已标准化 Three.js 且不需要 Babylon.js 的内置编辑器集成、游戏引擎特性或 WebXR 便利 API,可考虑 threejs-webgl/react-three-fiber。
- 如果运行环境不支持 WebGL/WebGPU,或无法引入 @babylonjs 包与相关资源,则不适合使用这套做法。