MCPInstall

babylonjs-engine

Comprehensive skill for Babylon.js 3D web rendering engine. Use this skill when building real-time 3D experiences, browser-based games, interactive visualizations, or immersive web applications. Triggers on tasks involving Babylon.js, 3D scenes, WebGL/WebGPU rendering, entity-component systems, physics simulations, PBR materials, shadow mapping, or 3D model loading. Alternative to Three.js with built-in editor integration and game engine features.

Installs
2.5K
Last 24h
+16
Trending rank
#6735
Security
Not audited

Install

Works with every agent the skills CLI supports.

npx skills add https://github.com/freshtechbro/claudedesignskills --skill babylonjs-engine
  1. 01

    Install

    Run the command in your project. The CLI asks which agents to install for.

  2. 02

    Describe the task

    Ask your agent for something this skill covers. It loads babylonjs-engine automatically when relevant.

  3. 03

    Review the result

    The agent follows the SKILL.md steps, scripts and references bundled with the skill.

SKILL.md

The instructions your agent reads when the skill is triggered.

Babylon.js Engine Skill

Related Skills

  • threejs-webgl: Alternative 3D engine
  • react-three-fiber: React integration for 3D
  • gsap-scrolltrigger: Animation library
  • motion-framer: UI animations

Core Concepts

1. Engine and Scene Initialization

Basic Setup

// Get canvas element
const canvas = document.getElementById('renderCanvas');

// Create engine
const engine = new BABYLON.Engine(canvas, true, {
  preserveDrawingBuffer: true,
  stencil: true
});

// Create scene
const scene = new BABYLON.Scene(engine);

// Render loop
engine.runRenderLoop(() => {
  scene.render();
});

// Handle resize
window.addEventListener('resize', () => {
  engine.resize();
});

ES6/TypeScript Setup

import { Engine } from '@babylonjs/core/Engines/engine';
import { Scene } from '@babylonjs/core/scene';
import { FreeCamera } from '@babylonjs/core/Cameras/freeCamera';
import { Vector3 } from '@babylonjs/core/Maths/math.vector';
import { HemisphericLight } from '@babylonjs/core/Lights/hemisphericLight';
import { CreateSphere } from '@babylonjs/core/Meshes/Builders/sphereBuilder';

const canvas = document.getElementById('renderCanvas') as HTMLCanvasElement;
const engine = new Engine(canvas);
const scene = new Scene(engine);

// Camera setup
const camera = new FreeCamera('camera1', new Vector3(0, 5, -10), scene);
camera.setTarget(Vector3.Zero());
camera.attachControl(canvas, true);

// Lighting
const light = new HemisphericLight('light1', new Vector3(0, 1, 0), scene);
light.intensity = 0.7;

// Create mesh
const sphere = CreateSphere('sphere1', { segments: 16, diameter: 2 }, scene);
sphere.position.y = 2;

// Render
engine.runRenderLoop(() => {
  scene.render();
});

Scene Configuration Options

const scene = new BABYLON.Scene(engine, {
  // Optimize for large mesh counts
  useGeometryUniqueIdsMap: true,
  useMaterialMeshMap: true,
  useClonedMeshMap: true
});

2. Camera Systems

Free Camera (FPS-style)

const camera = new BABYLON.FreeCamera('camera1', new BABYLON.Vector3(0, 5, -10), scene);
camera.setTarget(BABYLON.Vector3.Zero());
camera.attachControl(canvas, true);

// Movement settings
camera.speed = 0.5;
camera.angularSensibility = 2000;
camera.keysUp = [87]; // W
camera.keysDown = [83]; // S
camera.keysLeft = [65]; // A
camera.keysRight = [68]; // D

Arc Rotate Camera (Orbit)

const camera = new BABYLON.ArcRotateCamera(
  'camera',
  -Math.PI / 2,        // alpha (horizontal rotation)
  Math.PI / 2.5,       // beta (vertical rotation)
  15,                  // radius (distance)
  new BABYLON.Vector3(0, 0, 0), // target
  scene
);
camera.attachControl(canvas, true);

// Constraints
camera.lowerRadiusLimit = 5;
camera.upperRadiusLimit = 50;
camera.lowerBetaLimit = 0.1;
camera.upperBetaLimit = Math.PI / 2;

Universal Camera (Advanced)

const camera = new BABYLON.UniversalCamera('camera', new BABYLON.Vector3(0, 5, -10), scene);
camera.setTarget(BABYLON.Vector3.Zero());
camera.attachControl(canvas, true);

// Collision detection
camera.checkCollisions = true;
camera.applyGravity = true;
camera.ellipsoid = new BABYLON.Vector3(1, 1, 1);

3. Lighting Systems

Hemispheric Light (Ambient)

const light = new BABYLON.HemisphericLight('light1', new BABYLON.Vector3(0, 1, 0), scene);
light.intensity = 0.7;
light.diffuse = new BABYLON.Color3(1, 1, 1);
light.specular = new BABYLON.Color3(1, 1, 1);
light.groundColor = new BABYLON.Color3(0, 0, 0);

Directional Light (Sun-like)

const light = new BABYLON.DirectionalLight('dirLight', new BABYLON.Vector3(-1, -2, -1), scene);
light.position = new BABYLON.Vector3(20, 40, 20);
light.intensity = 0.5;

// Shadow setup
const shadowGenerator = new BABYLON.ShadowGenerator(1024, light);
shadowGenerator.useExponentialShadowMap = true;

Point Light (Omni-directional)

const light = new BABYLON.PointLight('pointLight', new BABYLON.Vector3(0, 10, 0), scene);
light.intensity = 0.7;
light.diffuse = new BABYLON.Color3(1, 0, 0);
light.specular = new BABYLON.Color3(0, 1, 0);

// Range and falloff
light.range = 100;
light.radius = 0.1;

Spot Light (Focused)

const light = new BABYLON.SpotLight(
  'spotLight',
  new BABYLON.Vector3(0, 10, 0),      // position
  new BABYLON.Vector3(0, -1, 0),      // direction
  Math.PI / 3,                        // angle
  2,                                  // exponent
  scene
);
light.intensity = 0.8;

Light Optimization (Include Only Specific Meshes)

// Only affect specific meshes
light.includedOnlyMeshes = [mesh1, mesh2, mesh3];

// Or exclude specific meshes
light.excludedMeshes = [mesh4, mesh5];

4. Mesh Creation

Built-in Shapes

// Box
const box = BABYLON.MeshBuilder.CreateBox('box', {
  size: 2,
  width: 2,
  height: 2,
  depth: 2
}, scene);

// Sphere
const sphere = BABYLON.MeshBuilder.CreateSphere('sphere', {
  diameter: 2,
  segments: 32,
  diameterX: 2,
  diameterY: 2,
  diameterZ: 2,
  arc: 1,
  slice: 1
}, scene);

// Cylinder
const cylinder = BABYLON.MeshBuilder.CreateCylinder('cylinder', {
  height: 3,
  diameter: 2,
  tessellation: 24
}, scene);

// Plane
const plane = BABYLON.MeshBuilder.CreatePlane('plane', {
  size: 5,
  width: 5,
  height: 5
}, scene);

// Ground
const ground = BABYLON.MeshBuilder.CreateGround('ground', {
  width: 10,
  height: 10,
  subdivisions: 2
}, scene);

// Ground from heightmap
const ground = BABYLON.MeshBuilder.CreateGroundFromHeightMap('ground', 'heightmap.png', {
  width: 100,
  height: 100,
  subdivisions: 100,
  minHeight: 0,
  maxHeight: 10
}, scene);

// Torus
const torus = BABYLON.MeshBuilder.CreateTorus('torus', {
  diameter: 3,
  thickness: 1,
  tessellation: 16
}, scene);

// TorusKnot
const torusKnot = BABYLON.MeshBuilder.CreateTorusKnot('torusKnot', {
  radius: 2,
  tube: 0.6,
  radialSegments: 64,
  tubularSegments: 8,
  p: 2,
  q: 3
}, scene);

Mesh Transformations

// Position
mesh.position = new BABYLON.Vector3(0, 5, 10);
mesh.position.x = 5;
mesh.position.y = 2;

// Rotation (radians)
mesh.rotation = new BABYLON.Vector3(0, Math.PI / 2, 0);
mesh.rotation.y = Math.PI / 4;

// Scaling
mesh.scaling = new BABYLON.Vector3(2, 2, 2);
mesh.scaling.x = 1.5;

// Look at
mesh.lookAt(new BABYLON.Vector3(0, 0, 0));

// Parent-child relationships
childMesh.parent = parentMesh;

Mesh Properties

// Visibility
mesh.isVisible = true;
mesh.visibility = 0.5; // 0 = invisible, 1 = fully visible

// Picking
mesh.isPickable = true;
mesh.checkCollisions = true;

// Culling
mesh.cullingStrategy = BABYLON.AbstractMesh.CULLINGSTRATEGY_BOUNDINGSPHERE_ONLY;

// Receive shadows
mesh.receiveShadows = true;

5. Materials

Standard Material

const material = new BABYLON.StandardMaterial('material', scene);

// Colors
material.diffuseColor = new BABYLON.Color3(1, 0, 1);
material.specularColor = new BABYLON.Color3(0.5, 0.6, 0.87);
material.emissiveColor = new BABYLON.Color3(0, 0, 0);
material.ambientColor = new BABYLON.Color3(0.23, 0.98, 0.53);

// Textures
material.diffuseTexture = new BABYLON.Texture('diffuse.png', scene);
material.specularTexture = new BABYLON.Texture('specular.png', scene);
material.emissiveTexture = new BABYLON.Texture('emissive.png', scene);
material.ambientTexture = new BABYLON.Texture('ambient.png', scene);
material.bumpTexture = new BABYLON.Texture('normal.png', scene);
material.opacityTexture = new BABYLON.Texture('opacity.png', scene);

// Properties
material.alpha = 0.8;
material.backFaceCulling = true;
material.wireframe = false;
material.specularPower = 64;

// Apply to mesh
mesh.material = material;

PBR Material (Physically Based Rendering)

const pbr = new BABYLON.PBRMaterial('pbr', scene);

// Metallic workflow
pbr.albedoColor = new BABYLON.Color3(1, 1, 1);
pbr.albedoTexture = new BABYLON.Texture('albedo.png', scene);
pbr.metallic = 1.0;
pbr.roughness = 0.5;
pbr.metallicTexture = new BABYLON.Texture('metallic.png', scene);

// Or specular workflow
pbr.albedoTexture = new BABYLON.Texture('albedo.png', scene);
pbr.reflectivityTexture = new BABYLON.Texture('reflectivity.png', scene);

// Environment
pbr.environmentTexture = BABYLON.CubeTexture.CreateFromPrefilteredData('environment.dds', scene);

// Other maps
pbr.bumpTexture = new BABYLON.Texture('normal.png', scene);
pbr.ambientTexture = new BABYLON.Texture('ao.png', scene);
pbr.emissiveTexture = new BABYLON.Texture('emissive.png', scene);

mesh.material = pbr;

Multi-Materials

const multiMat = new BABYLON.MultiMaterial('multiMat', scene);
multiMat.subMaterials.push(material1);
multiMat.subMaterials.push(material2);
multiMat.subMaterials.push(material3);

mesh.material = multiMat;
mesh.subMeshes = [];
mesh.subMeshes.push(new BABYLON.SubMesh(0, 0, verticesCount, 0, indicesCount1, mesh));
mesh.subMeshes.push(new BABYLON.SubMesh(1, 0, verticesCount, indicesCount1, indicesCount2, mesh));

6. Model Loading

GLTF/GLB Import

// Append to scene
BABYLON.SceneLoader.Append('path/to/', 'model.gltf', scene, function(scene) {
  console.log('Model loaded');
});

// Import mesh
BABYLON.SceneLoader.ImportMesh('', 'path/to/', 'model.gltf', scene, function(meshes) {
  const mesh = meshes[0];
  mesh.position.y = 5;
});

// Async version
const result = await BABYLON.SceneLoader.ImportMeshAsync(
  null,  // all meshes
  'https://assets.babylonjs.com/meshes/',
  'village.glb',
  scene
);
console.log('Loaded meshes:', result.meshes);

// Load from binary
const result = await BABYLON.SceneLoader.AppendAsync(
  '',
  'data:' + arrayBuffer,
  scene
);

Asset Manager (Batch Loading)

const assetsManager = new BABYLON.AssetsManager(scene);

// Add mesh task
const meshTask = assetsManager.addMeshTask('model', '', 'path/to/', 'model.gltf');
meshTask.onSuccess = function(task) {
  task.loadedMeshes[0].position = new BABYLON.Vector3(0, 0, 0);
};

// Add texture task
const textureTask = assetsManager.addTextureTask('texture', 'texture.png');
textureTask.onSuccess = function(task) {
  material.diffuseTexture = task.texture;
};

// Load all
assetsManager.onFinish = function(tasks) {
  console.log('All assets loaded');
  engine.runRenderLoop(() => scene.render());
};

assetsManager.load();

7. Physics Engine

Havok Physics Setup

// Import Havok
import HavokPhysics from '@babylonjs/havok';

// Initialize
const havokInstance = await HavokPhysics();
const havokPlugin = new BABYLON.HavokPlugin(true, havokInstance);

// Enable physics
scene.enablePhysics(new BABYLON.Vector3(0, -9.8, 0), havokPlugin);

// Create physics aggregate for mesh
const sphereAggregate = new BABYLON.PhysicsAggregate(
  sphere,
  BABYLON.PhysicsShapeType.SPHERE,
  { mass: 1, restitution: 0.75 },
  scene
);

// Ground (static)
const groundAggregate = new BABYLON.PhysicsAggregate(
  ground,
  BABYLON.PhysicsShapeType.BOX,
  { mass: 0 }, // mass 0 = static
  scene
);

Physics Shapes

// Available shapes
BABYLON.PhysicsShapeType.SPHERE
BABYLON.PhysicsShapeType.BOX
BABYLON.PhysicsShapeType.CAPSULE
BABYLON.PhysicsShapeType.CYLINDER
BABYLON.PhysicsShapeType.CONVEX_HULL
BABYLON.PhysicsShapeType.MESH
BABYLON.PhysicsShapeType.HEIGHTFIELD

Physics Body Control

// Get body
const body = aggregate.body;

// Apply force
body.applyForce(
  new BABYLON.Vector3(0, 10, 0),    // force
  new BABYLON.Vector3(0, 0, 0)      // point of application
);

// Apply impulse
body.applyImpulse(
  new BABYLON.Vector3(0, 5, 0),
  new BABYLON.Vector3(0, 0, 0)
);

// Set velocity
body.setLinearVelocity(new BABYLON.Vector3(0, 5, 0));
body.setAngularVelocity(new BABYLON.Vector3(0, 1, 0));

// Properties
body.setMassProperties({ mass: 2 });
body.setCollisionCallbackEnabled(true);

8. Animations

Direct Animation

// Animate property
BABYLON.Animation.CreateAndStartAnimation(
  'anim',
  mesh,
  'position.y',
  30,                    // FPS
  120,                   // total frames
  mesh.position.y,       // from
  10,                    // to
  BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE
);

Animation Class

const animation = new BABYLON.Animation(
  'myAnimation',
  'position.x',
  30,
  BABYLON.Animation.ANIMATIONTYPE_FLOAT,
  BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE
);

// Keyframes
const keys = [
  { frame: 0, value: 0 },
  { frame: 30, value: 10 },
  { frame: 60, value: 0 }
];
animation.setKeys(keys);

// Attach to mesh
mesh.animations.push(animation);

// Start
scene.beginAnimation(mesh, 0, 60, true);

Animation Groups

const animationGroup = new BABYLON.AnimationGroup('group', scene);
animationGroup.addTargetedAnimation(animation1, mesh1);
animationGroup.addTargetedAnimation(animation2, mesh2);

// Control
animationGroup.play();
animationGroup.pause();
animationGroup.stop();
animationGroup.speedRatio = 2.0;

// Events
animationGroup.onAnimationEndObservable.add(() => {
  console.log('Animation complete');
});

Skeleton Animations (from imported models)

// Get skeleton from imported model
const skeleton = result.skeletons[0];

// Get animation ranges
const ranges = skeleton.getAnimationRanges();

// Play animation range
scene.beginAnimation(skeleton, 0, 100, true);

// Or use animation groups
result.animationGroups[0].play();
result.animationGroups[0].setWeightForAllAnimatables(0.5);

Common Patterns

Pattern 1: Scene Setup with Default Environment

const createScene = function() {
  const scene = new BABYLON.Scene(engine);

  // Quick setup
  scene.createDefaultCameraOrLight(true, true, true);
  const env = scene.createDefaultEnvironment({
    createGround: true,
    createSkybox: true,
    skyboxSize: 150,
    groundSize: 50
  });

  // Your meshes
  const sphere = BABYLON.MeshBuilder.CreateSphere('sphere', {diameter: 2}, scene);
  sphere.position.y = 1;

  return scene;
};

Pattern 2: Async Scene Loading

const createScene = async function() {
  const scene = new BABYLON.Scene(engine);

  const camera = new BABYLON.ArcRotateCamera('camera', 0, 0, 10, BABYLON.Vector3.Zero(), scene);
  camera.attachControl(canvas, true);

  const light = new BABYLON.HemisphericLight('light', new BABYLON.Vector3(0, 1, 0), scene);

  // Load model
  const result = await BABYLON.SceneLoader.ImportMeshAsync(
    null,
    'https://assets.babylonjs.com/meshes/',
    'village.glb',
    scene
  );

  // Setup physics
  const havokInstance = await HavokPhysics();
  const havokPlugin = new BABYLON.HavokPlugin(true, havokInstance);
  scene.enablePhysics(new BABYLON.Vector3(0, -9.8, 0), havokPlugin);

  return scene;
};

createScene().then(scene => {
  engine.runRenderLoop(() => scene.render());
});

Pattern 3: Interactive Picking

scene.onPointerDown = function(evt, pickResult) {
  if (pickResult.hit) {
    console.log('Picked mesh:', pickResult.pickedMesh.name);
    console.log('Pick point:', pickResult.pickedPoint);

    // Highlight picked mesh
    pickResult.pickedMesh.material.emissiveColor = new BABYLON.Color3(1, 0, 0);
  }
};

// Or use action manager
mesh.actionManager = new BABYLON.ActionManager(scene);
mesh.actionManager.registerAction(
  new BABYLON.ExecuteCodeAction(
    BABYLON.ActionManager.OnPickTrigger,
    function() {
      console.log('Mesh clicked');
    }
  )
);

Pattern 4: Post-Processing Effects

// Default pipeline
const pipeline = new BABYLON.DefaultRenderingPipeline('pipeline', true, scene, [camera]);
pipeline.samples = 4;
pipeline.fxaaEnabled = true;
pipeline.bloomEnabled = true;
pipeline.bloomThreshold = 0.8;
pipeline.bloomWeight = 0.5;
pipeline.bloomKernel = 64;

// Depth of field
pipeline.depthOfFieldEnabled = true;
pipeline.depthOfFieldBlurLevel = BABYLON.DepthOfFieldEffectBlurLevel.Low;
pipeline.depthOfField.focusDistance = 2000;
pipeline.depthOfField.focalLength = 50;

// Glow layer
const glowLayer = new BABYLON.GlowLayer('glow', scene);
glowLayer.intensity = 0.5;

// Highlight layer
const highlightLayer = new BABYLON.HighlightLayer('highlight', scene);
highlightLayer.addMesh(mesh, BABYLON.Color3.Green());

Pattern 5: GUI (2D UI)

import { AdvancedDynamicTexture, Button, TextBlock, Rectangle } from '@babylonjs/gui';

// Fullscreen UI
const advancedTexture = BABYLON.GUI.AdvancedDynamicTexture.CreateFullscreenUI('UI');

// Button
const button = BABYLON.GUI.Button.CreateSimpleButton('button', 'Click Me');
button.width = '150px';
button.height = '40px';
button.color = 'white';
button.background = 'green';
button.onPointerUpObservable.add(() => {
  console.log('Button clicked');
});
advancedTexture.addControl(button);

// Text
const text = new BABYLON.GUI.TextBlock();
text.text = 'Hello World';
text.color = 'white';
text.fontSize = 24;
advancedTexture.addControl(text);

// 3D mesh UI
const plane = BABYLON.MeshBuilder.CreatePlane('plane', {size: 2}, scene);
const advancedTexture3D = BABYLON.GUI.AdvancedDynamicTexture.CreateForMesh(plane);
const button3D = BABYLON.GUI.Button.CreateSimpleButton('button3D', 'Click Me');
advancedTexture3D.addControl(button3D);

Pattern 6: Shadow Mapping

const light = new BABYLON.DirectionalLight('light', new BABYLON.Vector3(-1, -2, -1), scene);
light.position = new BABYLON.Vector3(20, 40, 20);

// Create shadow generator
const shadowGenerator = new BABYLON.ShadowGenerator(1024, light);
shadowGenerator.useExponentialShadowMap = true;
shadowGenerator.usePoissonSampling = true;

// Add shadow casters
shadowGenerator.addShadowCaster(sphere);
shadowGenerator.addShadowCaster(box);

// Enable shadow receiving
ground.receiveShadows = true;

Pattern 7: Particle Systems

const particleSystem = new BABYLON.ParticleSystem('particles', 2000, scene);
particleSystem.particleTexture = new BABYLON.Texture('particle.png', scene);

// Emitter
particleSystem.emitter = new BABYLON.Vector3(0, 5, 0);
particleSystem.minEmitBox = new BABYLON.Vector3(-1, 0, 0);
particleSystem.maxEmitBox = new BABYLON.Vector3(1, 0, 0);

// Colors
particleSystem.color1 = new BABYLON.Color4(0.7, 0.8, 1.0, 1.0);
particleSystem.color2 = new BABYLON.Color4(0.2, 0.5, 1.0, 1.0);
particleSystem.colorDead = new BABYLON.Color4(0, 0, 0.2, 0.0);

// Size
particleSystem.minSize = 0.1;
particleSystem.maxSize = 0.5;

// Life time
particleSystem.minLifeTime = 0.3;
particleSystem.maxLifeTime = 1.5;

// Emission rate
particleSystem.emitRate = 1500;

// Direction
particleSystem.direction1 = new BABYLON.Vector3(-1, 8, 1);
particleSystem.direction2 = new BABYLON.Vector3(1, 8, -1);

// Gravity
particleSystem.gravity = new BABYLON.Vector3(0, -9.81, 0);

// Start
particleSystem.start();

Integration Patterns

Pattern 1: React Integration

import { useEffect, useRef } from 'react';
import * as BABYLON from '@babylonjs/core';

function BabylonScene() {
  const canvasRef = useRef(null);
  const engineRef = useRef(null);
  const sceneRef = useRef(null);

  useEffect(() => {
    if (!canvasRef.current) return;

    // Initialize
    const engine = new BABYLON.Engine(canvasRef.current, true);
    engineRef.current = engine;

    const scene = new BABYLON.Scene(engine);
    sceneRef.current = scene;

    // Setup scene
    const camera = new BABYLON.ArcRotateCamera('camera', 0, 0, 10, BABYLON.Vector3.Zero(), scene);
    camera.attachControl(canvasRef.current, true);

    const light = new BABYLON.HemisphericLight('light', new BABYLON.Vector3(0, 1, 0), scene);

    const sphere = BABYLON.MeshBuilder.CreateSphere('sphere', {diameter: 2}, scene);

    // Render loop
    engine.runRenderLoop(() => {
      scene.render();
    });

    // Resize handler
    const handleResize = () => engine.resize();
    window.addEventListener('resize', handleResize);

    // Cleanup
    return () => {
      window.removeEventListener('resize', handleResize);
      scene.dispose();
      engine.dispose();
    };
  }, []);

  return (
    <canvas
      ref={canvasRef}
      style={{ width: '100%', height: '100vh' }}
    />
  );
}

Pattern 2: WebXR (VR/AR)

const createScene = async function() {
  const scene = new BABYLON.Scene(engine);

  const camera = new BABYLON.FreeCamera('camera', new BABYLON.Vector3(0, 5, -10), scene);
  camera.attachControl(canvas, true);

  const light = new BABYLON.HemisphericLight('light', new BABYLON.Vector3(0, 1, 0), scene);

  const sphere = BABYLON.MeshBuilder.CreateSphere('sphere', {diameter: 2}, scene);
  sphere.position.y = 1;

  const env = scene.createDefaultEnvironment();

  // Enable WebXR
  const xrHelper = await scene.createDefaultXRExperienceAsync({
    floorMeshes: [env.ground],
    disableTeleportation: false
  });

  // XR controller input
  xrHelper.input.onControllerAddedObservable.add((controller) => {
    controller.onMotionControllerInitObservable.add((motionController) => {
      const trigger = motionController.getMainComponent();
      trigger.onButtonStateChangedObservable.add(() => {
        if (trigger.pressed) {
          console.log('Trigger pressed');
        }
      });
    });
  });

  return scene;
};

Pattern 3: Node Material (Visual Shader Editor)

// Create from snippet
const nodeMaterial = await BABYLON.NodeMaterial.ParseFromSnippetAsync('#SNIPPET_ID', scene);

// Apply to mesh
nodeMaterial.build();
mesh.material = nodeMaterial;

// Or create programmatically
const nodeMaterial = new BABYLON.NodeMaterial('node', scene);

const positionInput = new BABYLON.InputBlock('position');
positionInput.setAsAttribute('position');

const worldPos = new BABYLON.TransformBlock('worldPos');
nodeMaterial.addOutputNode(worldPos);

Performance Optimization

1. Mesh Optimization

// Merge meshes with same material
const merged = BABYLON.Mesh.MergeMeshes(
  [mesh1, mesh2, mesh3],
  true,  // disposeSource
  true,  // allow32BitsIndices
  undefined,
  false, // multiMultiMaterials
  true   // preserveSerializationHelper
);

// Instances (for repeated meshes)
const instance1 = mesh.createInstance('instance1');
const instance2 = mesh.createInstance('instance2');
instance1.position.x = 5;
instance2.position.x = -5;

// Thin instances (even more efficient)
const buffer = new Float32Array(16 * count); // 16 floats per matrix
mesh.thinInstanceSetBuffer('matrix', buffer, 16);

// Freeze meshes (static meshes)
mesh.freezeWorldMatrix();

// Freeze materials
material.freeze();

// Simplify meshes (LOD)
const simplified = mesh.simplify(
  [
    { quality: 0.8, distance: 10 },
    { quality: 0.4, distance: 50 },
    { quality: 0.2, distance: 100 }
  ],
  true,  // parallelProcessing
  BABYLON.SimplificationType.QUADRATIC
);

2. Scene Optimization

// Scene optimizer
const options = new BABYLON.SceneOptimizerOptions();
options.addOptimization(new BABYLON.HardwareScalingOptimization(0, 1));
options.addOptimization(new BABYLON.ShadowsOptimization(1));
options.addOptimization(new BABYLON.PostProcessesOptimization(2));
options.addOptimization(new BABYLON.LensFlaresOptimization(3));
options.addOptimization(new BABYLON.ParticlesOptimization(4));
options.addOptimization(new BABYLON.TextureOptimization(5, 512));
options.addOptimization(new BABYLON.RenderTargetsOptimization(6));
options.addOptimization(new BABYLON.MergeMeshesOptimization(7));

const optimizer = new BABYLON.SceneOptimizer(scene, options);
optimizer.start();

// Octree (spatial partitioning)
const octree = scene.createOrUpdateSelectionOctree();

// Frustum culling
scene.blockMaterialDirtyMechanism = true;

// Skip pointer move picking
scene.skipPointerMovePicking = true;

// Freeze active meshes
scene.freezeActiveMeshes();

3. Rendering Optimization

// Hardware scaling
engine.setHardwareScalingLevel(0.5); // Render at half resolution

// Adaptive quality
scene.onBeforeRenderObservable.add(() => {
  const fps = engine.getFps();
  if (fps < 30) {
    // Reduce quality
    engine.setHardwareScalingLevel(2);
  } else if (fps > 55) {
    // Increase quality
    engine.setHardwareScalingLevel(1);
  }
});

// Incremental loading
scene.useDelayedTextureLoading = true;

// Culling strategy
mesh.cullingStrategy = BABYLON.AbstractMesh.CULLINGSTRATEGY_BOUNDINGSPHERE_ONLY;

4. Texture Optimization

// Compressed textures
const texture = new BABYLON.Texture('texture.dds', scene);

// Mipmaps
texture.updateSamplingMode(BABYLON.Texture.TRILINEAR_SAMPLINGMODE);

// Anisotropic filtering
texture.anisotropicFilteringLevel = 4;

// KTX2 compression
const texture = new BABYLON.Texture('texture.ktx2', scene);

Common Pitfalls

Pitfall 1: Memory Leaks

Problem: Not disposing resources

// ❌ Bad - memory leak
function createAndRemoveMesh() {
  const mesh = BABYLON.MeshBuilder.CreateBox('box', {}, scene);
  scene.removeMesh(mesh);
}

Solution: Properly dispose

// ✅ Good
function createAndRemoveMesh() {
  const mesh = BABYLON.MeshBuilder.CreateBox('box', {}, scene);
  mesh.dispose();
}

// Dispose entire scene
scene.dispose();

// Dispose engine
engine.dispose();

Pitfall 2: Performance Issues with Too Many Draw Calls

Problem: Each mesh = one draw call

// ❌ Bad - 1000 draw calls
for (let i = 0; i < 1000; i++) {
  const box = BABYLON.MeshBuilder.CreateBox('box' + i, {}, scene);
  box.position.x = i;
}

Solution: Use instances or merge

// ✅ Good - 1 draw call
const box = BABYLON.MeshBuilder.CreateBox('box', {}, scene);
for (let i = 0; i < 1000; i++) {
  const instance = box.createInstance('instance' + i);
  instance.position.x = i;
}

Pitfall 3: Blocking the Main Thread

Problem: Heavy computations blocking render

// ❌ Bad - blocks rendering
function createManyMeshes() {
  for (let i = 0; i < 10000; i++) {
    const mesh = BABYLON.MeshBuilder.CreateSphere('sphere' + i, {}, scene);
  }
}

Solution: Use async/incremental loading

// ✅ Good - incremental
async function createManyMeshes() {
  for (let i = 0; i < 10000; i++) {
    const mesh = BABYLON.MeshBuilder.CreateSphere('sphere' + i, {}, scene);

    if (i % 100 === 0) {
      await new Promise(resolve => setTimeout(resolve, 0));
    }
  }
}

Pitfall 4: Incorrect Camera Controls

Problem: Camera not responding

// ❌ Bad - forgot attachControl
const camera = new BABYLON.ArcRotateCamera('camera', 0, 0, 10, BABYLON.Vector3.Zero(), scene);

Solution: Always attach controls

// ✅ Good
const camera = new BABYLON.ArcRotateCamera('camera', 0, 0, 10, BABYLON.Vector3.Zero(), scene);
camera.attachControl(canvas, true);

Pitfall 5: Not Handling Async Operations

Problem: Using scene before it's ready

// ❌ Bad
BABYLON.SceneLoader.ImportMesh('', 'path/', 'model.gltf', scene);
const mesh = scene.getMeshByName('meshName'); // null!

Solution: Use callbacks or async/await

// ✅ Good
const result = await BABYLON.SceneLoader.ImportMeshAsync('', 'path/', 'model.gltf', scene);
const mesh = scene.getMeshByName('meshName');

// Or with callback
BABYLON.SceneLoader.ImportMesh('', 'path/', 'model.gltf', scene, function(meshes) {
  const mesh = meshes[0];
});

Pitfall 6: Physics Not Working

Problem: Forgot to enable physics or create aggregates

// ❌ Bad
const sphere = BABYLON.MeshBuilder.CreateSphere('sphere', {}, scene);
sphere.physicsImpostor = new BABYLON.PhysicsImpostor(sphere, BABYLON.PhysicsImpostor.SphereImpostor, {mass: 1}, scene);
// Error: Physics not enabled!

Solution: Enable physics first, use aggregates

// ✅ Good
const havokInstance = await HavokPhysics();
const havokPlugin = new BABYLON.HavokPlugin(true, havokInstance);
scene.enablePhysics(new BABYLON.Vector3(0, -9.8, 0), havokPlugin);

const sphere = BABYLON.MeshBuilder.CreateSphere('sphere', {}, scene);
const aggregate = new BABYLON.PhysicsAggregate(
  sphere,
  BABYLON.PhysicsShapeType.SPHERE,
  {mass: 1},
  scene
);

Advanced Topics

1. Custom Shaders

BABYLON.Effect.ShadersStore['customVertexShader'] = `
  precision highp float;
  attribute vec3 position;
  attribute vec2 uv;
  uniform mat4 worldViewProjection;
  varying vec2 vUV;

  void main(void) {
    gl_Position = worldViewProjection * vec4(position, 1.0);
    vUV = uv;
  }
`;

BABYLON.Effect.ShadersStore['customFragmentShader'] = `
  precision highp float;
  varying vec2 vUV;
  uniform sampler2D textureSampler;

  void main(void) {
    gl_FragColor = texture2D(textureSampler, vUV);
  }
`;

const shaderMaterial = new BABYLON.ShaderMaterial('shader', scene, {
  vertex: 'custom',
  fragment: 'custom'
}, {
  attributes: ['position', 'uv'],
  uniforms: ['worldViewProjection']
});

2. Compute Shaders

const computeShader = new BABYLON.ComputeShader('compute', engine, {
  computeSource: `
    #version 450
    layout (local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
    layout(std430, binding = 0) buffer OutputBuffer { vec4 data[]; } outputBuffer;

    void main() {
      uint index = gl_GlobalInvocationID.x + gl_GlobalInvocationID.y * 8u;
      outputBuffer.data[index] = vec4(1.0, 0.0, 0.0, 1.0);
    }
  `
});

3. Procedural Textures

const noiseTexture = new BABYLON.NoiseProceduralTexture('noise', 256, scene);
noiseTexture.octaves = 4;
noiseTexture.persistence = 0.8;
noiseTexture.animationSpeedFactor = 5;

material.emissiveTexture = noiseTexture;

Debugging

// Show inspector
scene.debugLayer.show();

// Show bounding boxes
scene.forceShowBoundingBoxes = true;

// Show wireframes
material.wireframe = true;

// Log FPS
setInterval(() => {
  console.log('FPS:', engine.getFps());
}, 1000);

// Instrumentation
const instrumentation = new BABYLON.SceneInstrumentation(scene);
instrumentation.captureFrameTime = true;
console.log('Frame time:', instrumentation.frameTimeCounter.average);

Resources

Version Notes

This skill is based on Babylon.js 7.x. For latest features, consult the official documentation.

FAQ

What does the babylonjs-engine skill do?

Comprehensive skill for Babylon.js 3D web rendering engine. Use this skill when building real-time 3D experiences, browser-based games, interactive visualizations, or immersive web applications. Triggers on tasks involving Babylon.js, 3D scenes, WebGL/WebGPU rendering, entity-component systems, physics simulations, PBR materials, shadow mapping, or 3D model loading. Alternative to Three.js with built-in editor integration and game engine features.

How do I install babylonjs-engine?

Run npx skills add https://github.com/freshtechbro/claudedesignskills --skill babylonjs-engine in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/babylonjs-engine/ (personal) or .claude/skills/babylonjs-engine/ (project).

Which AI agents can use babylonjs-engine?

Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.

Is babylonjs-engine safe to install?

No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.

Who maintains babylonjs-engine?

It is published by freshtechbro in freshtechbro/claudedesignskills. It has 2,531 recorded installs.

More from freshtechbro/claudedesignskills

View all →

motion-framer

freshtechbro/claudedesignskills

Modern animation library for React and JavaScript. Create smooth, production-ready animations with motion components, variants, gestures (hover/tap/drag), layout animations, AnimatePresence exit animations, spring physics, and scroll-based effects. Use when building interactive UI components, micro-interactions, page transitions, or complex animation sequences.

threejs-webgl

freshtechbro/claudedesignskills

Comprehensive skill for Three.js 3D web development. Use this skill when building interactive 3D scenes, WebGL/WebGPU applications, product configurators, 3D visualizations, or immersive web experiences. Triggers on tasks involving Three.js, 3D rendering, scenes, cameras, meshes, materials, lights, animations, textures, or WebGL/WebGPU rendering.

Media & Creative4.6K installs

react-three-fiber

freshtechbro/claudedesignskills

Build declarative 3D scenes with React Three Fiber (R3F) - a React renderer for Three.js. Use when building interactive 3D experiences in React applications with component-based architecture, state management, and reusable abstractions. Ideal for product configurators, portfolios, games, data visualization, and immersive web experiences.

Frontend & Design3.8K installs

blender-web-pipeline

freshtechbro/claudedesignskills

Blender to web export workflows for 3D models and animations. Use this skill when exporting Blender models to glTF for web, optimizing 3D assets for Three.js or Babylon.js, batch processing models with Python scripts, automating Blender workflows, or creating web-ready 3D pipelines. Triggers on tasks involving Blender glTF export, bpy scripting, 3D asset optimization, model compression, texture baking, or Blender automation. Exports models for threejs-webgl, react-three-fiber, and babylonjs-engine skills.

Media & Creative3.5K installs

web3d-integration-patterns

freshtechbro/claudedesignskills

Meta-skill for combining Three.js, GSAP ScrollTrigger, React Three Fiber, Motion, and React Spring for complex 3D web experiences. Use when building applications that integrate multiple 3D and animation libraries, requiring architecture patterns, state management, and performance optimization across the stack. Triggers on tasks involving library integration, multi-library architectures, scroll-driven 3D experiences, physics-based 3D animations, or complex interactive 3D applications.

Frontend & Design3.2K installs

lottie-animations

freshtechbro/claudedesignskills

After Effects animation rendering for web and React applications. Use this skill when implementing Lottie animations, JSON vector animations, interactive animated icons, micro-interactions, or loading animations. Triggers on tasks involving Lottie, lottie-web, lottie-react, dotLottie, After Effects JSON export, bodymovin, animated SVG alternatives, or designer-created animations. Complements GSAP ScrollTrigger and Framer Motion for scroll-driven and interactive animations.

Frontend & Design2.9K installs

Popular media & creative skills

View category →

hyperframes

heygen-com/hyperframes

Read first to make, edit, animate or render any video with HyperFrames (HTML rendered to video), including launch films, explainers, music videos, charts, maps, vertical clips, title cards, captions and overlays. Holds the render contract, the work loop and what each kind of video needs.

Media & Creative1.2M installs

media-use

heygen-com/hyperframes

Get or make any media for a HyperFrames video - music, sound effects, images, icons, logos, voiceover, avatar and generated video, transcripts, cutouts, colour grades and looks - with HeyGen or free local tools, and mix placed audio. Also for footage that looks dark, flat or dull, or should be stylized or hidden.

Media & Creative1.1M installs

hyperframes-registry

heygen-com/hyperframes

About 450 ready-made HyperFrames blocks and components installed as editable source - transitions, overlays, titles, kinetic type, captions, charts, map overlays, 3D, camera moves. Use it before hand-building any named visual (CRT scanlines, glitch, film grain, a chart); also for hyperframes add and catalog.

Media & Creative1M installs

hyperframes-creative

heygen-com/hyperframes

Non-animation creative direction for HyperFrames videos. Use for design spec (frame.md / design.md) handling, palettes, typography, narration, beat planning, audio-reactive visuals, composition patterns, and brand / style decisions. For atomic motion patterns and scene blueprints, use hyperframes-animation.

Media & Creative916.5K installs

ai-video-generation

101-skills/superpowers

Generate AI videos with Google Veo, Seedance 2.0, HappyHorse, Wan, Grok and 40+ models via inference.sh CLI. Models: Veo 3.1, Veo 3, Seedance 2.0, HappyHorse 1.0, Wan 2.5, Grok Imagine Video, OmniHuman, Fabric, HunyuanVideo. Capabilities: text-to-video, image-to-video, reference-to-video, video editing, lipsync, avatar animation, video upscaling, foley sound. Use for: social media videos, marketing content, explainer videos, product demos, AI avatars. Triggers: video generation, ai video, text to video, image to video, veo, animate image, video from image, ai animation, video generator, generate video, t2v, i2v, ai video maker, create video with ai, runway alternative, pika alternative, sora alternative, kling alternative, seedance, happyhorse

Media & Creative881.5K installs

ai-image-generation

101-skills/superpowers

Generate AI images with GPT-Image-2, FLUX, Gemini, Grok, Seedream, Reve and 50+ models via inference.sh CLI. Models: GPT-Image-2, FLUX Dev LoRA, FLUX.2 Klein LoRA, Gemini 3 Pro Image, Grok Imagine, Seedream 4.5, Reve, ImagineArt. Capabilities: text-to-image, image-to-image, inpainting, LoRA, image editing, upscaling, text rendering. Use for: AI art, product mockups, concept art, social media graphics, marketing visuals, illustrations. Triggers: flux, image generation, ai image, text to image, stable diffusion, generate image, ai art, midjourney alternative, dall-e alternative, text2img, t2i, image generator, ai picture, create image with ai, generative ai, ai illustration, grok image, gemini image, gpt image, openai image, chatgpt image

Media & Creative880.3K installs