关于 lighting-environment
面向 Decentraland 场景创作者的照明配置参考,涵盖发光材质与昼夜时间。内容包括场景声明、运行时调整,以及光源和阴影限制。
主要功能
- 01声明点光源与聚光灯
- 02配置阴影和遮光纹理
- 03在运行时切换灯光
- 04设置固定或动态天空时间
- 05组合发光材质与光源
适用场景
- 01为 Decentraland 场景添加灯具照明
- 02制作彩色或定向舞台灯光
- 03构建昼夜循环
- 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