lighting-environment について
Decentraland のシーン制作者向けに、照明や発光マテリアル、時刻の設定方法をまとめたスキルです。シーン内の宣言と実行時の変更に加え、ライトや影の制限も説明します。
主な機能
- 01ポイントライトとスポットライトの宣言
- 02影とマスクテクスチャの設定
- 03実行時のライト切り替え
- 04固定または変動する空の時刻設定
- 05発光マテリアルとライトの併用
活用シーン
- 01Decentraland シーンへの照明器具の追加
- 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
})
影を利用できるのはスポットライトのみで、ポイントライトでは利用できません。
シャドウマスクテクスチャ(ゴボ)
ライトを通してパターンを投影します。
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)あたり有効にできるライトは最大1つです。必要に応じて、複数パーセルのシーンでは近くにライトをまとめて配置できます。
- レンダラーは品質設定と近接度に基づいてライトを自動的にカリングします。品質設定によって、同時に表示できるライトは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 の組み合わせ
1つのエンティティに両方を設定できます。マテリアルによるエミッシブグローと、ライトの放射を組み合わせられます。
// 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 スキルを参照してください。
ベストプラクティス
- パーセルあたりライト1つの上限を守り、シーンのパーセルを考慮してライトの配置を計画します
- 周囲を照らす必要のない装飾的なグローには、エミッシブマテリアルを使います
- リアルな照明器具(ランプ = エミッシブメッシュ + ポイントライト)には、エミッシブマテリアルと LightSource を組み合わせます
- ドラマチックな効果(ステージ照明、懐中電灯)には、影付きスポットライトを使います
- 影の数は少なく抑え(表示は最大約3つ)、影が不要なライトでは
shadowを無効にします - ライトに
rangeを設定して影響範囲を制限し、パフォーマンスを節約します - 雰囲気づくりには
SkyboxTimeを使います。ポイントライトを配置した夜のシーンは、ドラマチックな環境を演出できます