# Luzes

As lights são uma parte fundamental dos gráficos 3D. São usadas para iluminar a scene e criar uma sensação de profundidade e realismo, e podem ser usadas para criar diferentes ambientes e atmosferas.

Por padrão, a scene é iluminada com uma única directional light. Esta é uma light que brilha numa direção específica, e é usada para simular o sol ou a lua. Consulta [Controlo do skybox](/creator/content-creator-pt/scenes-sdk7/interatividade/skybox-control.md) para mais informações.

Podes adicionar até 1 light por parcel na tua scene.

Existem dois tipos de lights suportados:

* Point light: Uma light que brilha em todas as direções a partir de um ponto específico.
* Spot light: Uma light que brilha numa direção específica e cobre apenas uma área em forma de cone.

## Adicionar uma light

Para adicionar uma light à tua scene, precisas de criar uma light entity e adicionar o `LightSource` component a ela.

```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" %}
**📔 Nota**: Uma light com o brilho padrão será dificilmente visível com o sol do meio-dia, tal como no mundo real. Podes usar o [Controlo do skybox](/creator/content-creator-pt/scenes-sdk7/interatividade/skybox-control.md) para forçar o skybox para a noite, ou aumentar o brilho ao definir o `intensity` propriedade do `LightSource` component para um valor mais alto.
{% endhint %}

## Spot lights

Spot lights são lights que brilham numa direção específica e cobrem uma área específica em forma de cone. A direção da light é definida pelo component Transform da entity. A abertura do cone é definida pelas propriedades `innerAngle` e `outerAngle` do `LightSource` componente.

```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
})
```

O `innerAngle` é o ângulo do cone interior, onde a light está com brilho total, e o `outerAngle` é o ângulo do cone exterior, onde a light desvanece gradualmente em direção às extremidades do cone. Podes brincar com estes valores para criar efeitos diferentes, para lights mais focadas ou mais difusas.

## Intensity e cor

Todas as lights, tanto point como spot, têm uma cor e uma intensity. A cor é definida pelo `color` propriedade do `LightSource` component, e a intensity é definida pela `intensity` property.

```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,
})
```

A cor é um objeto `Color3` ; se não for especificada, será branca. Podes definir isto para qualquer cor que quiseres, o que pode ter um grande impacto no ambiente da scene.

A intensity é expressa em candelas (lumens/m^2 a 1 m de distância, ou lumens divididos por 4\*pi).

A intensity predefinida é 16000; isto é o brilho de uma lâmpada média no mundo real e pode ser vista até cerca de 10 metros de distância da light source. Se precisares que a light seja visível de mais longe, ou durante o dia, podes aumentar a intensity.

A distância a que a light é visível é a raiz quadrada do valor da intensity.

* Com uma intensity de 100, a light é visível até cerca de 10 metros de distância.
* Com uma intensity de 1000, a light é visível até cerca de 31 metros de distância.
* Com uma intensity de 10000, a light é visível até cerca de 100 metros de distância.

## Sombras

Cada light pode ou não projetar sombras. Por padrão, não projetam, mas podes ativá-las ao definir o `shadow` propriedade do `LightSource` component para `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" %}
**📔 Nota**: As sombras só são suportadas para spot lights. Point lights não suportam sombras. Se houver várias lights na scene, algumas delas podem não estar a projetar sombras; consulta [Otimização de lights](#light-optimization) para mais informações.
{% endhint %}

## Ligar e desligar uma light

O component LightSource tem uma `active` property que pode ser usada para ligar e desligar uma light. Isto é útil se quiseres desligar uma light sem a remover da scene, ou sem definir a `intensity` para 0 e perder a referência de qual era a intensity original.

```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
})

const switch = engine.addEntity()

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

MeshRenderer.setBox(switch, {})

MeshCollider.setBox(switch, {})

pointerEventsSystem.onPointerDown(
	{
		entity: switch,
		opts: {
			button: InputAction.IA_POINTER,
			hoverText: 'Clique',
		},
	},
	function () {
		LightSource.getMutable(light).active = !LightSource.getMutable(light).active
	}
)
```

## Otimização de lights

As light sources podem ter um impacto bastante grande no desempenho da tua scene. Por este motivo, o engine vai otimizar automaticamente a scene, desativando algumas das lights ou as suas sombras, começando pelas que estão mais longe.

O número de active lights permitidas numa scene está limitado a uma por parcel, e para além disso depende das definições de qualidade selecionadas pelo utilizador.

* Baixa qualidade: Máximo de 4 lights (numa scene com parcels suficientes)
* Qualidade média: Máximo de 6 lights (numa scene com parcels suficientes)
* Alta qualidade: Máximo de 10 lights (numa scene com parcels suficientes)

Se houver mais lights do que o permitido, o engine vai desativar automaticamente lights com base na proximidade da light source ao player. À medida que o player se move, o engine vai reativar as lights que estiverem suficientemente perto do player.

Em todos os casos, o engine apenas vai render sombras para até 3 light sources. Se houver mais lights com sombras do que 3, o engine vai desativar automaticamente as sombras das lights restantes que estiverem mais longe.

Além do número máximo de lights permitidas, as sombras também dependem da distância ao player.

* A menos de 10 metros: As sombras são renderizadas como soft shadows (alta qualidade)
* Entre 10 e 20 metros: As sombras são renderizadas como hard shadows (baixa qualidade)
* Entre 20 e 40 metros: As sombras não são renderizadas
* A mais de 40 metros: As light sources não são renderizadas de todo

Também é importante notar que as lights só são renderizadas se o player estiver dentro da scene. Se o player estiver fora da scene, as lights não serão renderizadas.

## Alcance da light

O component lightSource tem uma `range` property que pode ser usada para definir a distância máxima a que a light é visível. Por padrão, o valor da `range` property é -1, o que significa que o alcance da light depende da intensity da light.

* Com uma intensity de 16000, o alcance é de 10 metros.
* Com uma intensity de 160000, o alcance é de 31 metros.
* Com uma intensity de 1600000, o alcance é de 100 metros.

A definição predefinida garante que a curva de atenuação seja suave e pareça natural. Mas, caso queiras limitar o alcance da light, podes definir a `range` property para um número positivo.

```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" %}
**📔 Nota**: Definir a `range` property para um número positivo vai cortar abruptamente a light à distância fornecida. Isto é útil se quiseres criar uma light que só seja visível numa área específica, ou para otimizar o desempenho da tua scene. Definir o `range` para um valor maior do que o que a light consegue realmente alcançar com a sua intensity atual não terá qualquer efeito.
{% endhint %}

## Máscaras de luz

Podes usar uma light mask para produzir alguns efeitos interessantes. Em vez de iluminar toda a área, podes aplicar uma texture para ser usada como filtro que apenas vai iluminar partes da área.

As masks são mais normalmente usadas com spot lights, mas também podem ser usadas com point lights. Abaixo está um exemplo de uma spot light com uma mask aplicada.

```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"})         
})
```

Por exemplo, podes aplicar a imagem abaixo para produzir um efeito divertido em que a light só é visível nas áreas onde a texture é branca. Podes usar isto com lights de qualquer cor e intensity.

![](/files/05d0e858abff2850cf688708fbfdb1cf7bdfffa7)

Com uma imagem a preto e branco, a light está ou a atingir uma área ou não. Também é possível passar uma imagem com cores, e estas cores vão tingir a tua light em cada área; isto pode ser usado para projetar um logótipo ou imagem colorida sobre uma surface.

{% hint style="warning" %}
**📔 Nota**: A imagem usada como mask deve ter uma altura e largura em pixels que sejam uma power of 2 (por exemplo: 1024, 512, 256). Esta feature não funciona para imagens que tenham dimensões diferentes.
{% endhint %}

Ao aplicar uma mask a uma point light, a texture será envolvida como um cubo à volta da light source. Se quiseres evitar ter edges visíveis entre os lados do cubo, certifica-te de que a texture tem continuidade nas edges.

```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"})         
})
```

Por exemplo, a imagem abaixo mostra cada uma das letras em lados diferentes do cubo (Y em cima, -Y em baixo, X à direita, -X à esquerda, Z na frente, -Z atrás).

![](/files/d3a9f9e5e1de4b3c0f63cf69bad76294e79022d3)

{% hint style="info" %}
**💡 Dica**: Combina lights com um [Particle System](/creator/content-creator-pt/scenes-sdk7/essenciais-de-conteudo-3d/particle-system.md) para efeitos visuais mais ricos. Por exemplo, combina um particle system com additive-blend e uma warm point light para criar uma fogueira convincente.
{% endhint %}


---

# Agent Instructions: Querying This Documentation

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

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.decentraland.org/creator/content-creator-pt/scenes-sdk7/essenciais-de-conteudo-3d/lights.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
