babylonjs制作闪烁的灯管

更新时间: 2025-08-19 14:13:55

先来看一下效果

可以看到诱导灯可以常亮白色,频闪红色

# 原理

  1. 首先加载诱导灯的模型,然后获取诱导灯的材质
  2. 设置GlowLayer辉光层
  3. 控制诱导灯材质的emissiveColor和emissiveIntensity来控制颜色以及亮度
  4. 如果需要频闪就写动画来控制emissiveIntensity

# 实现

  1. 灯光控制变量与响应式监听 定义了三个档位,一个是常亮白色,一个是闪烁,一个是关闭,具体后面一一实现
// 获取诱导灯模型  
bridgeLight = scene.getMeshById("light");
// 自定义诱导灯材质  
const material = new StandardMaterial(`bridgelight`, scene);  
// 初始灯光设置为关闭状态  
material.emissiveIntensity = 0
material.diffuseColor = new Color3(0.8, 0.8, 0.8); // 基础颜色
bridgeLight.material = material;
const youdaoLightStatus = ref('close') // white | shine | close  

watch(youdaoLightStatus, (status) => {
  switch(status) {
    case 'white':
      toggleBridgeLight('white')
      break;
    case 'shine':
      bridgeLightShine(5)
      break;
    case 'close':
      toggleBridgeLight('close')
      break;
  }
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
  1. 设置辉光层

辉光效果(Glow Effect)是指在3D场景中,发光物体周围产生的柔和光晕效果,就像现实世界中的霓虹灯、车灯或光源在黑暗中产生的朦胧光晕。这种效果能极大增强场景的视觉冲击力和真实感,使发光物体更加突出和引人注目。

辉光效果工作原理

  • 自动关联:GlowLayer会自动识别场景中具有emissiveColor属性的物体
  • 后期处理:在场景正常渲染完成后,对发光物体应用辉光效果
  • 叠加渲染:将辉光效果叠加到原始渲染结果上,形成最终画面
createGlowLayer()

function createGlowLayer() {
  if(!glowLayer) {
    glowLayer = new GlowLayer("glowLayer", scene);

    // 辉光设置
    glowLayer.intensity = 1.4; // 辉光强度
    glowLayer.blurKernelSize = 28; // 模糊程度(8-128,值越大越模糊)
  }
}
1
2
3
4
5
6
7
8
9
10
11
  1. 灯光状态控制
function toggleBridgeLight(type) {
  // 获取灯光的材质对象  
  const material = bridgeLight.material;  
  // 如果有正在运行的动画,先停止  
  if(bridgeLightAnimatable) {
    bridgeLightAnimatable.stop()
  }
  bridgeLightAnimatable = null

  // 根据灯光类型切换灯光状态  
  switch (type) {
    case 'white':  
      // 白色常亮模式  
      material.emissiveColor = new Color3(1, 1, 1);
      material.emissiveIntensity = 5;
      break;
    case 'red':  
      // 红色常量模式  
      material.emissiveColor = new Color3(1, 0, 0);
      material.emissiveIntensity = 5;
      break;
    case 'close': 
      // 关闭模式  
      material.emissiveColor = new Color3(0, 0, 0);
      material.emissiveIntensity = 0;
      break;
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
  1. 灯光闪烁动画实现
function bridgeLightShine(duration) {
  // 获取诱导灯的材质  
  const material = bridgeLight.material;  

  // 设置基础色红色  
  material.emissiveColor = new Color3(1, 0, 0);

  // 创建动画控制emissiveColor  
  const colorAnim = new Animation(
      "emissiveColorAnim",  // 动画名称  
      "emissiveColor",  // 要动画的属性  
      60, // 帧率(每秒60帧)  
      Animation.ANIMATIONTYPE_COLOR3,  // 动画数据类型(Color3)
      Animation.ANIMATIONLOOPMODE_YOYO  // 循环模式:YOYO(来回)  
  );

  // 创建强度动画
  const intensityAnim = new Animation(
      "emissiveIntensityAnim",
      "emissiveIntensity",
      60,
      Animation.ANIMATIONTYPE_FLOAT,  // 动画数据类型(浮点数)  
      Animation.ANIMATIONLOOPMODE_YOYO
  );

  // 设置颜色关键帧
  colorAnim.setKeys([
    { frame: 0, value: new Color3(1, 0, 0) },  // 起始帧红色  
    { frame: duration/2 * 60, value: new Color3(0, 0, 0) }  // 中间帧黑色  
  ]);

  // 设置强度关键帧  
  intensityAnim.setKeys([
    { frame: 0, value: 5 },
    { frame: duration/2 * 60, value: 0 }
  ]);

  // 启动动画
  bridgeLightAnimatable = scene.beginDirectAnimation(
      material,  // 动画目标对象
      [colorAnim, intensityAnim],  // 要应用的动画数组
      0,  // 开始帧
      duration/2 * 60, // 结束帧
      true // 是否循环  
  );
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

# 闪烁动画工作原理

以duration = 5秒为例:

  • 动画创建:
    创建了两个动画:颜色动画(未使用)和强度动画
    循环模式都设为YOYO(来回)

  • 关键帧设置:
    强度动画关键帧:0帧时强度5 → 150帧时强度0(因为duration/2 * 60 = 2.5 * 60 = 150)
    颜色动画关键帧:0帧时红色 → 150帧时黑色

  • 动画执行流程:
    0-150帧(0-2.5秒):强度从5→0(灯光逐渐变暗)
    150-300帧(2.5-5秒):由于YOYO模式,强度从0→5(灯光逐渐变亮)
    300-450帧(5-7.5秒):强度从5→0(再次变暗)
    以此类推,直到动画被停止

  • 与辉光的联动:
    随着emissiveIntensity变化,辉光效果强度也会同步变化
    形成"呼吸灯"效果:亮→暗→亮→暗...循环