mcpField
L
lighting-environment

lighting-environment

github.com/dcl-regenesislabs开发1738 次安装21 周前更新
代码仓库

关于 lighting-environment

面向 Decentraland 场景创作者的照明配置参考,涵盖发光材质与昼夜时间。内容包括场景声明、运行时调整,以及光源和阴影限制。

主要功能

  1. 01声明点光源与聚光灯
  2. 02配置阴影和遮光纹理
  3. 03在运行时切换灯光
  4. 04设置固定或动态天空时间
  5. 05组合发光材质与光源

适用场景

  1. 01为 Decentraland 场景添加灯具照明
  2. 02制作彩色或定向舞台灯光
  3. 03构建昼夜循环
  4. 04在场景运行时调整灯光

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/dcl-regenesislabs/opendcl --skill lighting-environment

安装后在 Claude Code 中输入/lighting-environment确认已加载。

详细介绍

Decentraland 中的灯光与环境

作者拆分

LightSource 在 main-entities.ts 中受支持——在同一条目中声明灯具模型和灯光。用户可以在编辑器中拖动灯具,灯光也会随之移动。

// main-entities.ts
import type { Scene } from '@dcl/sdk/scene-types'

export const scene = {
  ceiling_lamp: {
    components: {
      Transform: { position: { x: 8, y: 3, z: 8 } },
      GltfContainer: { src: 'models/lamp.glb' },
      LightSource: {
        type: { $case: 'point', point: {} },
        color: { r: 1, g: 1, b: 1 },
        intensity: 16000
      }
    }
  }
} satisfies Scene

对于没有网格的纯装饰灯光,声明一个仅包含 Transform 的实体,并跳过 GltfContainer。运行时切换灯光仍通过 src/index.ts 中的 LightSource.getMutable(getEntityOrNullByName('ceiling_lamp')) 完成。

点光源

从一个位置向所有方向发光:

// main-entities.ts entry
ambient_point: {
  components: {
    Transform: { position: { x: 8, y: 3, z: 8 } },
    LightSource: {
      type: { $case: 'point', point: {} },
      color: { r: 1, g: 1, b: 1 },
      intensity: 16000  // candela — point lights typically need 8000–32000 to be visible
    }
  }
}
彩色点光源
LightSource.create(light, {
  type: LightSource.Type.Point({}),
  color: Color3.create(1, 0.5, 0),  // Warm orange
  intensity: 12000,
  range: 15  // Maximum distance in meters
})

聚光灯

沿一个方向发出锥形光束。光锥的朝向由实体的 Transform 旋转决定。

// main-entities.ts
stage_spot: {
  components: {
    Transform: {
      position: { x: 8, y: 4, z: 8 },
      rotation: { x: -0.7071, y: 0, z: 0, w: 0.7071 }  // pitch -90° (down)
    },
    GltfContainer: { src: 'models/spotlight.glb' },
    LightSource: {
      type: { $case: 'spot', spot: { innerAngle: 25, outerAngle: 45 } },
      color: { r: 1, g: 1, b: 1 },
      intensity: 16000
    }
  }
}
  • innerAngle — 全亮度光锥的角度(度)
  • outerAngle — 外侧渐隐角度(度)
  • 灯光方向跟随实体的前向量(通过 Transform 旋转设置)

阴影

为点光源或聚光灯启用阴影:

LightSource.create(spotlight, {
  type: LightSource.Type.Spot({ innerAngle: 25, outerAngle: 45 }),
  shadow: true,
  intensity: 16000
})

阴影仅适用于聚光灯,不适用于点光源。

阴影遮罩纹理(Gobos)

通过灯光投射图案:

const maskedLight = LightSource.getMutable(spotlight)
maskedLight.shadowMaskTexture = Material.Texture.Common({
  src: 'assets/scene/images/lightmask1.png'
})

切换灯光

// Toggle on/off
const lightData = LightSource.getMutable(light)
lightData.active = !lightData.active

灯光限制

  • 每个地块(16m x 16m)最多有一个活动灯光——需要时,多地块场景可以将灯光布置得彼此靠近。
  • 渲染器会根据画质设置和距离自动剔除灯光。画质范围允许同时显示 4–10 个灯光。
  • 阴影仅适用于聚光灯;同时最多可见约 3 个带阴影的灯光。
  • 强度单位为坎德拉。实际可见范围:点光源约 8000–32000,聚光灯约 10000–24000。低于约 1000 的值通常不可见。
  • 自发光材质不会照亮周围实体——它们只会自身发光。若要同时实现两种效果,请将自发光材质与 LightSource 结合使用。

SkyboxTime(昼夜循环)

在 scene.json 中设置固定时间

无需编写代码即可设置固定时刻:

{
  "skyboxConfig": {
    "fixedTime": 36000
  }
}

时间值:0 = 午夜,36000 = 正午,54000 = 黄昏,72000 = 再次午夜。

读取当前世界时间
import { getWorldTime } from '~system/Runtime'

executeTask(async () => {
  const time = await getWorldTime({})
  console.log('Seconds since midnight:', time.seconds)
})
动态更改时间
import { engine, SkyboxTime } from '@dcl/sdk/ecs'

// Set time of day (must target root entity)
SkyboxTime.create(engine.RootEntity, { fixedTime: 36000 })  // Noon

// Change with transition direction (TransitionMode from the generated protobuf)
SkyboxTime.createOrReplace(engine.RootEntity, {
  fixedTime: 54000,  // Dusk
  transitionMode: 1  // TM_BACKWARD
})
昼夜循环系统
let currentTime = 36000
const CYCLE_SPEED = 100  // Time units per second

function dayNightCycle(dt: number) {
  currentTime = (currentTime + CYCLE_SPEED * dt) % 72000
  SkyboxTime.createOrReplace(engine.RootEntity, {
    fixedTime: currentTime
  })
}

engine.addSystem(dayNightCycle)

Realm 信息

检测玩家连接到的 realm(服务):

import { getRealm } from '~system/Runtime'

executeTask(async () => {
  const realm = await getRealm({})
  console.log('Realm:', realm.realmInfo?.realmName)
  console.log('Network:', realm.realmInfo?.networkId)
  console.log('Base URL:', realm.realmInfo?.baseUrl)
})

自发光材质(发光效果)

Material 在 main-entities.ts 中受支持,因此对于无需照亮周围环境的发光效果,可以直接内联声明:

// main-entities.ts
glowing_orb: {
  components: {
    Transform: { position: { x: 8, y: 1, z: 8 } },
    MeshRenderer: { mesh: { $case: 'sphere', sphere: {} } },
    Material: {
      material: {
        $case: 'pbr',
        pbr: {
          albedoColor: { r: 0, g: 0, b: 0, a: 1 },
          emissiveColor: { r: 0, g: 1, b: 0 },
          emissiveIntensity: 2.0
        }
      }
    }
  }
}
组合使用自发光材质与 LightSource

单个实体可以同时包含两者——材质产生自发光效果,同时发出灯光。

// main-entities.ts
bulb: {
  components: {
    Transform: { position: { x: 8, y: 3, z: 8 } },
    GltfContainer: { src: 'models/bulb.glb' },
    Material: {
      material: {
        $case: 'pbr',
        pbr: {
          emissiveColor: { r: 1, g: 0.9, b: 0.7 },
          emissiveIntensity: 1.5
        }
      }
    },
    LightSource: {
      type: { $case: 'point', point: {} },
      color: { r: 1, g: 0.9, b: 0.7 },
      intensity: 12000,
      range: 10
    }
  }
}
阴影类型

控制每个灯光的阴影质量。阴影类型在 Spot() 或 Point() 辅助函数中设置:

import { LightSource, PBLightSource_ShadowType } from '@dcl/sdk/ecs'

// Spot light with soft shadows
LightSource.create(spotEntity, {
  type: LightSource.Type.Spot({
    innerAngle: 25,
    outerAngle: 45,
    shadow: PBLightSource_ShadowType.ST_SOFT
  }),
  shadow: true,
  intensity: 16000
})

可用的阴影类型:

  • PBLightSource_ShadowType.ST_NONE — 无阴影(开销最低)
  • PBLightSource_ShadowType.ST_HARD — 清晰阴影(中等开销)
  • PBLightSource_ShadowType.ST_SOFT — 平滑、模糊的阴影(开销最高)

需要高级材质效果? 请参阅 advanced-rendering 技能,了解金属度、粗糙度、透明度、纹理贴图和纹理模式。

最佳实践

  • 控制在每个地块一个灯光的限额内——围绕场景地块规划灯光布局
  • 对于无需照亮周围环境的装饰性发光效果,请使用自发光材质
  • 将自发光材质与 LightSource 结合使用,打造逼真的灯具(灯具 = 自发光网格 + 点光源)
  • 使用带阴影的聚光灯营造戏剧性效果(舞台灯光、手电筒)
  • 控制阴影数量(最多约 3 个可见)——对于不需要阴影的灯光,请禁用 shadow
  • 为灯光设置 range,以限制影响范围并提升性能
  • 使用 SkyboxTime 营造氛围——夜景中的点光源可打造富有戏剧性的环境

评论

支持 Markdown