> For the complete documentation index, see [llms.txt](https://docs.decentraland.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.decentraland.org/creator/content-creator-zh/chang-jing-sdk7/3d-nei-rong-ji-chu/lights.md).

# 灯光

了解如何在场景中使用灯光

光源是 3D 图形的基础组成部分。它们用于照亮场景并营造深度与真实感，还可用于创建不同的氛围与情绪。

默认情况下，场景由一个单一的平行光照亮。这是一种沿特定方向照射的光，用于模拟太阳或月亮。请参见 [天空盒控制](/creator/content-creator-zh/chang-jing-sdk7/jiao-hu-xing/skybox-control.md) 以获取更多信息。

在你的场景中，每个地块最多可以添加 1 个光源。

支持两种类型的光源：

* 点光源：从某个特定点向四面八方照射的光。
* 聚光灯：沿特定方向照射、只覆盖圆锥形区域的光。

{% hint style="warning" %}
**📔 注意**：嵌入在 `.glb` 或 `.gltf` 文件中的光源会被 Decentraland 忽略。如果你的 3D 模型导出时包含了灯光，它们不会照亮场景中的任何东西。唯一有效的光源来自具有 `LightSource` 组件的实体。如果你想让灯具模型发光，请给同一个实体添加一个 `LightSource` ，或者添加到一个位于灯泡位置的子实体上。
{% endhint %}

{% hint style="info" %}
**💡 提示**：Creator Hub 资源目录中有现成的 **聚光灯** 和 **点光源** 智能物件，位于 **灯光** 分类下。每个都打包了一个模型、一个已配置的 `LightSource`，以及开启、关闭和切换动作，因此你无需编写任何代码。还有一种装饰性的 **聚光灯** 下的 **装饰**，它只有模型，不会发出任何光。需要真实照明时，请从 **灯光** 分类中选择。
{% endhint %}

## 添加光源

要向场景中添加光源，你需要创建一个光源实体，并为其添加 `LightSource` 组件。

```ts
import { engine, LightSource } from '@dcl/sdk/ecs'

const light = engine.addEntity()

Transform.create(light, {
  position: Vector3.create(10, 3, 10),
})

LightSource.create(light, {
  type: LightSource.Type.Point({})
})
```

{% hint style="warning" %}
**📔 注意**：默认亮度的灯光在正午阳光下几乎看不见，就像现实世界一样。你可以使用 [天空盒控制](/creator/content-creator-zh/chang-jing-sdk7/jiao-hu-xing/skybox-control.md) 来强制天空盒切换到夜晚，或者通过设置 `intensity` 组件的 `LightSource` 组件为更高的值来提高亮度。
{% endhint %}

## 聚光灯

聚光灯是沿特定方向照射、覆盖特定圆锥形区域的光。光的方向由实体的 Transform 组件定义。圆锥的开口由 `innerAngle` 和 `outerAngle` 属性定义。 `LightSource` 组件。

```ts
import { engine, LightSource } from '@dcl/sdk/ecs'

const light = engine.addEntity()

Transform.create(light, {
  position: Vector3.create(10, 3, 10),
  rotation: Quaternion.fromEulerDegrees(-90, 0, 0),
})

LightSource.create(light, {
	type: LightSource.Type.Spot({
      innerAngle: 30,
      outerAngle: 60
    }),
	shadow: true
})
```

该 `innerAngle` 是内圆锥的角度，此处光线亮度为全亮，而 `outerAngle` 是外圆锥的角度，此处光线会逐渐向圆锥边缘淡出。你可以调整这些值来创建不同效果，使灯光更聚焦或更扩散。

## 亮度与颜色

所有光源，无论是点光源还是聚光灯，都有颜色和亮度。颜色由 `color` 组件的 `LightSource` 组件定义，而亮度由 `intensity` 属性定义。

```ts
import { engine, LightSource } from '@dcl/sdk/ecs'

const light = engine.addEntity()

Transform.create(light, {
  position: Vector3.create(10, 3, 10),
})

LightSource.create(light, {
  type: LightSource.Type.Point({}),
  color: Color3.Red(),
  intensity: 10000,
})
```

颜色是一个 `Color3` 对象，如果未指定则默认为白色。你可以将其设置为任何你想要的颜色，这会对场景的氛围产生很大影响。

亮度以坎德拉表示（1 米距离处的流明/平方米，或流明除以 4\*pi）。

默认亮度为 16000，这相当于现实世界中一只普通灯泡的亮度，距离光源约 10 米范围内都能看到。如果你需要让灯光在更远处或白天也可见，可以提高亮度。

灯光可见的距离是亮度值的四次方根（`intensity^0.25`).

* 当亮度为 625 时，灯光可见范围约 5 米。
* 当亮度为 10000 时，灯光可见范围约 10 米。
* 当亮度为 160000 时，灯光可见范围约 20 米。

## 阴影

每个光源都可以投射阴影，也可以不投射。默认情况下不会，但你可以通过设置 `shadow` 组件的 `LightSource` 字段设为 `true`.

```ts
import { engine, LightSource } from '@dcl/sdk/ecs'

const light = engine.addEntity()

Transform.create(light, {
  position: Vector3.create(10, 3, 10),
  rotation: Quaternion.fromEulerDegrees(-90, 0, 0),
})

LightSource.create(light, {
	type: LightSource.Type.Spot({
      innerAngle: 30,
      outerAngle: 60
    }),
	shadow: true
})
```

{% hint style="warning" %}
**📔 注意**：阴影仅支持聚光灯。点光源不支持阴影。如果场景中有多个光源，其中一些可能不会投射阴影，参见 [光源优化](#light-optimization) 以获取更多信息。
{% endhint %}

## 开启和关闭光源

LightSource 组件具有一个 `active` 属性，可用于开启和关闭光源。如果你想在不从场景中移除它、或不将 `intensity` 设置为 0 且丢失原始亮度值的情况下关闭光源，这会很有用。

```ts
import { engine, LightSource } from '@dcl/sdk/ecs'

const light = engine.addEntity()

Transform.create(light, {
  position: Vector3.create(10, 3, 10),
  rotation: Quaternion.fromEulerDegrees(-90, 0, 0),
})

LightSource.create(light, {
	type: LightSource.Type.Spot({
      innerAngle: 30,
      outerAngle: 60
    }),
	shadow: true,
	active: true
})

const lightSwitch = engine.addEntity()

Transform.create(lightSwitch, {
  position: Vector3.create(8, 1, 10),
})

MeshRenderer.setBox(lightSwitch)

MeshCollider.setBox(lightSwitch)

pointerEventsSystem.onPointerDown(
	{
		entity: lightSwitch,
		opts: {
			button: InputAction.IA_POINTER,
			hoverText: '点击',
		},
	},
	function () {
		const lightSource = LightSource.getMutable(light)
		lightSource.active = !lightSource.active
	}
)
```

## 光源优化

光源可能会对场景性能产生相当大的影响。因此，引擎会自动优化场景，禁用部分光源或其阴影，并优先从距离更远的开始。

场景中允许的活动光源数量上限为每个地块 1 个，而更高的数量取决于用户选择的画质设置。

* 低画质：最多 4 个光源（在地块数量足够的场景中）
* 中画质：最多 6 个光源（在地块数量足够的场景中）
* 高画质：最多 10 个光源（在地块数量足够的场景中）

如果光源数量超过允许值，引擎会根据光源与玩家的距离自动禁用部分光源。随着玩家移动，引擎会重新启用距离玩家足够近的光源。

在任何情况下，引擎最多只会为 3 个光源渲染阴影。如果带阴影的光源超过 3 个，引擎会自动禁用更远的其余光源的阴影。

除了允许的最大光源数量外，阴影还取决于与玩家的距离。具体距离因光源类型和玩家的画质设置而异，但通常规则如下：

* 距离小于 10 米：阴影以柔和阴影形式渲染（高质量）
* 距离在 10 到 20 米之间：阴影以硬阴影形式渲染（低质量）
* 距离超过 20 米：不渲染阴影

光源本身会在更远的距离持续照亮场景：只有当玩家距离超过 160 米（10 个地块）时才会被禁用。这使得光源适用于大型场景，例如现场活动中的舞台照明，因为观众中的大多数人都离光源很远。

还需要注意，只有当玩家站在场景内时，才会渲染光源。如果玩家在场景外，则不会渲染这些光源。

## 光照范围

lightSource 组件具有一个 `range` 属性，可用于设置光源可见的最大距离。默认情况下， `range` 属性的值为 -1，这意味着光照范围取决于光源的亮度。

范围的计算方式是亮度值的四次方根（`intensity^0.25`).

* 当亮度为 16000 时，范围约为 11 米。
* 当亮度为 160000 时，范围约为 20 米。
* 当亮度为 1600000 时，范围约为 36 米。

默认设置可确保衰减曲线平滑且看起来自然。不过，如果你想限制光照范围，可以将 `range` 属性设置为一个正数。

```ts
import { engine, LightSource } from '@dcl/sdk/ecs'

const light = engine.addEntity()

Transform.create(light, {
  position: Vector3.create(10, 3, 10),
})

LightSource.create(light, {
  type: LightSource.Type.Point({}),
  intensity: 16000,
  range: 20,
})
```

{% hint style="warning" %}
**📔 注意**：将 `range` 属性设置为正数会在指定距离处突然截断光照。如果你想创建一个只在特定区域可见的光源，或者优化场景性能，这会很有用。将 `range` 设置为一个大于当前亮度实际可达距离的值不会产生任何效果。
{% endhint %}

## 光照遮罩

你可以使用光照遮罩来实现一些有趣的效果。你可以不照亮整个区域，而是应用一张纹理作为过滤器，只照亮区域的部分部分。

遮罩更常与聚光灯一起使用，但也可以用于点光源。下面是一个应用了遮罩的聚光灯示例。

```ts
import { engine, LightSource } from '@dcl/sdk/ecs'

const light = engine.addEntity()

Transform.create(light, {
  position: Vector3.create(10, 3, 10),
})

LightSource.create(light, {
	type: LightSource.Type.Spot({
      innerAngle: 30,
      outerAngle: 60
    }),
	shadow: true,
	shadowMaskTexture: Material.Texture.Common({src: "assets/scene/images/lightmask1.png"})
})
```

例如，你可以应用下面这张图像，来产生一种有趣的效果：只有纹理为白色的区域才会被光照到。你可以将其用于任何颜色和亮度的光源。

![](https://2460066822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-1c5642751dfc0b0047732fbbb86e611b492e392f%2Flightmask1.png?alt=media\&token=18ce6d0f-109b-420f-9402-1cbe85f5d123)

对于黑白图像，光线要么照射到某个区域，要么不照射。也可以传入带颜色的图像，这些颜色会给图像照射到的每个区域染色，这可用于将彩色徽标或图像投射到表面上。

{% hint style="warning" %}
**📔 注意**：用作遮罩的图像，其像素高度和宽度必须是 2 的幂次方（例如：1024、512、256）。此功能不适用于尺寸不同的图像。
{% endhint %}

当将遮罩应用于点光源时，纹理会作为一个立方体包裹在光源周围。如果你想避免立方体各面之间出现可见边缘，请确保纹理在边缘处具有连续性。

```ts
import { engine, LightSource } from '@dcl/sdk/ecs'

const light = engine.addEntity()

Transform.create(light, {
  position: Vector3.create(10, 3, 10),
})

LightSource.create(light, {
	type: LightSource.Type.Point({}),
	shadowMaskTexture: Material.Texture.Common({src: "assets/scene/images/point-light-mask1.png"})
})
```

例如，下面的图像会将每个字母显示在立方体的不同面上（Y 在顶部，-Y 在底部，X 在右侧，-X 在左侧，Z 在前面，-Z 在后面）。

![](https://2460066822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-b68fe34eaab8dbaec996c3dca754e4742076f523%2Fpoint-light-mask1.png?alt=media\&token=d8d5037c-0d0e-4098-a45d-3b944f579b6a)

{% hint style="info" %}
**💡 提示**：将光源与 [粒子系统](/creator/content-creator-zh/chang-jing-sdk7/3d-nei-rong-ji-chu/particle-system.md) 结合，可获得更丰富的视觉效果。例如，将一个加法混合的火焰粒子系统与暖色点光源搭配，就能创建一个逼真的篝火。
{% endhint %}

{% hint style="info" %}
**💡 提示**：如需查看该组件的可运行示例，请参阅 [`0,4-动态光源`](https://github.com/decentraland/sdk7-test-scenes/tree/main/scenes/0,4-dynamic-lights) 测试场景，其中涵盖了 `LightSource.Type.Point` 和 `LightSource.Type.Spot`、运行时通过 `LightSource.getMutable()`进行的更改、阴影以及 `shadowMaskTexture`.
{% endhint %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.decentraland.org/creator/content-creator-zh/chang-jing-sdk7/3d-nei-rong-ji-chu/lights.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
