> 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-pt/scenes-sdk7/fundamentos-de-conteudo-3d/materials.md).

# Materiais

Saiba como adicionar materiais e texturas a entities com formas primitivas.

## Materiais

Materials podem ser aplicados a entities que usam formas primitivas (cube, sphere, plane, etc) adicionando um `Material` component. Este component tem vários campos que permitem configurar as properties do material, adicionar uma texture, etc.

*glTF* models incluem seus próprios materials que são importados implicitamente para uma scene junto com o model. Para modificar ou substituir esses materials, use o `GltfNodeModifiers` component. Veja [Modificar materiais glTF](#modify-gltf-materials) para mais detalhes.

Ao importar um model 3D com seus próprios materials, tenha em mente que nem todos os shaders são suportados pelo engine do Decentraland. Apenas materiais standard e materiais PBR (physically based rendering) são suportados. Veja [considerações sobre modelos 3D externos](https://github.com/decentraland/docs/blob/main/creator/3d-modeling/materials.md) para mais detalhes.

Há diferentes tipos de materials suportados:

* PBR (Physically Based Rendering): O tipo de material mais comum em Decentraland. Ele suporta cores sólidas ou textures, e diferentes properties como metallic, emissive, transparency, etc. Leia mais sobre [PBR](https://en.wikipedia.org/wiki/Physically_based_rendering).
* Basic materials: Eles não respondem a luzes e sombras, o que os torna ideais para exibir imagens de billboard.

## Use o Scene Editor no Creator Hub

A forma mais fácil de dar a um entity um Material é usar o Scene Editor. Você pode adicionar um **Material** component ao seu entity e então configurar todos os campos disponíveis na UI do Scene Editor. Veja [Add Components](/creator/content-creator-pt/scene-editor/construir/components.md#add-components).

## Adicionar um material

O exemplo a seguir cria um material PBR e define alguns de seus campos para lhe dar uma cor vermelha e properties metálicas. Este material é adicionado a um entity que também tem uma box shape, então ele colorirá a box com este material.

```ts
//Criar entity e atribuir shape
const meshEntity = engine.addEntity()
Transform.create(meshEntity, {
	position: Vector3.create(4, 1, 4),
})
MeshRenderer.setBox(meshEntity)

//Criar material e configurar seus fields
Material.setPbrMaterial(meshEntity, {
	albedoColor: Color4.Red(),
	metallic: 0.8,
	roughness: 0.1,
})
```

Para mudar o material de um entity que já tem um `Material` component, execute `Material.setPbrMaterial()` ou qualquer uma das outras helper functions e ela sobrescreverá o material original. Não há necessidade de remover o original `Material` nem de usar a syntax avançada.

```ts
//Criar entity e atribuir shape
const meshEntity = engine.addEntity()
Transform.create(meshEntity, {
	position: Vector3.create(4, 1, 4),
})
MeshRenderer.setBox(meshEntity)

//Criar material e configurar seus fields
Material.setPbrMaterial(meshEntity, {
	albedoColor: Color4.Red(),
})

//Sobrescrever com um novo material component
Material.setPbrMaterial(meshEntity, {
	albedoColor: Color4.Blue(),
})
```

{% hint style="warning" %}
**📔 Observação**: O `Material` component deve ser importado via

> `import { Material } from "@dcl/sdk/ecs"`

Veja [Imports](/creator/content-creator-pt/scenes-sdk7/primeiros-passos/coding-scenes.md#imports) para saber como lidar com isso facilmente.
{% endhint %}

## Cores do material

Dê a um material uma cor sólida. Em um Material PBR, você define o `albedoColor` field. As cores de albedo respondem à luz e podem incluir tons.

Os valores de cor são do tipo `Color4`, composta por *r*, *g* e *b* valores (vermelho, verde e azul). Cada um deles aceita valores entre 0 e 1. Ao definir valores diferentes para eles, você pode compor qualquer cor visível. Para preto, defina todos os três para 0. Para branco, defina todos para 1.

{% hint style="warning" %}
**📔 Observação**: Se você definir qualquer cor em `albedoColor` para um valor maior que *1*, ela aparecerá como *emissive*, com mais intensidade quanto maior for o valor. Portanto, por exemplo, `{r: 15, g: 0, b: 0}` produz um brilho vermelho muito intenso.
{% endhint %}

Veja [tipos de cor](/creator/content-creator-pt/scenes-sdk7/fundamentos-de-conteudo-3d/color-types.md) para mais detalhes sobre como definir cores.

Você também pode editar os seguintes campos em um Material PBR para ajustar com precisão como sua cor é percebida:

* *emissiveColor*: A cor emitida pelo material.
* *reflectivityColor*: Também conhecido como *Specular Color* em outra nomenclatura.

Para criar um material de cor sólida que não seja afetado por luz e sombras no ambiente, crie um basic material em vez de um material PBR.

```ts
Material.setBasicMaterial(myEntity, {
	diffuseColor: Color4.Black(),
})
```

## Usando textures

Defina um arquivo de imagem como uma texture em um material ajustando o `texture` parameter.

```ts
//Criar entity e atribuir shape
const meshEntity = engine.addEntity()
Transform.create(meshEntity, {
	position: Vector3.create(4, 1, 4),
})
MeshRenderer.setBox(meshEntity)

//Criar material e configurar seus fields
Material.setPbrMaterial(meshEntity, {
	texture: Material.Texture.Common({
		src: 'assets/materials/wood.png',
	}),
})
```

No exemplo acima, a imagem do material está localizada em uma `assets/materials` pasta, que está localizada no nível raiz da pasta do projeto da scene.

{% hint style="info" %}
**💡 Dica**: Recomendamos manter seus arquivos de imagem de texture em algum lugar na `/assets` pasta dentro da sua scene.
{% endhint %}

Ao criar uma texture, você também pode passar parâmetros adicionais:

* `filterMode`: Determina como os pixels na texture são esticados ou comprimidos quando renderizados. Isso recebe um valor do `TextureFilterMode` enum. Veja [Escala da Texture](#texture-scaling).
* `wrapMode`: Determina como uma texture é repetida sobre um objeto. Isso recebe um valor do `TextureWrapMode` enum. Veja [Repetição de Texture](#texture-wrapping).

```ts
Material.setPbrMaterial(myEntity, {
	texture: Material.Texture.Common({
		src: 'assets/materials/wood.png',
		filterMode: TextureFilterMode.TFM_BILINEAR,
		wrapMode: TextureWrapMode.TWM_CLAMP,
	}),
})
```

Para criar uma texture que não seja afetada por luz e sombras no ambiente, crie um basic material em vez de um material PBR.

```ts
Material.setBasicMaterial(myEntity, {
	texture: Material.Texture.Common({
		src: 'assets/materials/wood.png',
	}),
})
```

### Textures de uma URL externa

Você pode apontar a texture do seu material para uma URL externa em vez de um path interno no projeto da scene.

```ts
Material.setBasicMaterial(myEntity, {
	texture: Material.Texture.Common({
		src: 'https://wearable-api.decentraland.org/v2/collections/community_contest/wearables/cw_tuxedo_tshirt_upper_body/thumbnail',
	}),
})
```

A URL deve começar com `https`, `http` URLs não são suportadas.

### Texture wrapping

Você pode definir como uma texture se alinha com uma superfície. Por padrão, a texture é esticada para ocupar a superfície uma vez, mas você pode escalá-la e deslocá-la.

Os seguintes campos estão disponíveis em todas as textures:

* `offset`: Desloca a texture para mudar seu alinhamento. O valor é um Vector2, em que ambos os eixos vão de 0 a 1, onde 1 é a largura ou altura completa da texture.
* `tiling`: Escala a texture. O valor padrão é o Vector 2 `[1, 1]`, o que faz a imagem se repetir uma vez cobrindo toda a superfície.
* `TextureWrapMode`: Determina o que acontece se a repetição da imagem não cobrir toda a superfície. Esta propriedade recebe seus valores do `TextureWrapMode` enum, que permite os seguintes valores:
  * `TextureWrapMode.TWM_CLAMP`: A texture é exibida apenas uma vez no tamanho especificado. O restante da superfície da mesh fica transparente. O valor de `tiling` é ignorado.
  * `TextureWrapMode.TWM_REPEAT`: A texture se repete tantas vezes quanto couber na mesh, usando o tamanho especificado.
  * `TextureWrapMode.TWM_MIRROR`: Assim como em wrap, a texture é repetida tantas vezes quanto couber, mas a orientação dessas repetições é espelhada.

```ts
Material.setPbrMaterial(myEntity, {
	texture: Material.Texture.Common({
		src: 'assets/materials/wood.png',
		wrapMode: TextureWrapMode.TWM_REPEAT,
		offset: Vector2.create(0, 0.2),
		tiling: Vector2.create(1, 1),
	}),
})
```

{% hint style="warning" %}
**📔 Observação**: O `offset` e `tiling` properties são suportadas apenas no client desktop do DCL 2.0.
{% endhint %}

Use este recurso para cobrir uma grande superfície com um padrão repetido. Por exemplo, repita a seguinte imagem:

![](https://2402076176-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-e0324d6080a0e815b172eafd56b5ece426ca68ca%2Ftiles.png?alt=media\&token=33b26659-761d-4005-9c43-29ca542204d1)

```ts
Material.setPbrMaterial(myEntity, {
	texture: Material.Texture.Common({
		src: 'assets/materials/wood.png',
		wrapMode: TextureWrapMode.TWM_REPEAT,
		tiling: Vector2.create(8, 8),
	}),
})
```

![](https://2402076176-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-6e66e1936998029bf4cd65f497509ae21896809a%2Ftiles-in-scene.png?alt=media\&token=42961e2a-7050-457b-9e2b-768497de08b5)

No exemplo abaixo, a texture usa um *espelhado* wrap mode, e cada repetição da texture ocupa apenas 1/4 da superfície. Isso significa que veremos 4 cópias da imagem, espelhadas entre si em ambos os eixos.

```ts
Material.setPbrMaterial(myEntity, {
	texture: Material.Texture.Common({
		src: 'materials/atlas.png',
		wrapMode: TextureWrapMode.TWM_MIRROR,
		tiling: Vector2.create(0.25, 0.25),
	}),
})
```

### Texture tweens

Faça uma texture deslizar suavemente usando um `Tween` component, configurado com o `TextureMove` mode. O tween altera gradualmente o valor do `offset` ou das `tiling` propriedades de uma texture ao longo de um período de tempo, de forma suave e otimizada.

{% hint style="warning" %}
**📔 Observação**: Texture Tweens é um recurso suportado apenas no client desktop do DCL 2.0.
{% endhint %}

Use o `Tween` component com o `setTextureMove` function para mover a texture entre duas posições.

```ts
Tween.setTextureMove(myEntity, Vector2.create(0, 0), Vector2.create(1, 0), 2000)
```

O texture tween recebe as seguintes informações:

* `entity`A entity da qual a texture será movida
* `start`Um Vector2 para a posição inicial
* `end`Um Vector2 para a posição final
* `duration`Quantos milissegundos leva para se mover entre as duas posições

Este outro parâmetro opcional também está disponível:

* `movementType`: define se o movimento será no `offset` ou das `tiling` field. Por padrão, usa `offset`.
* `easingFunction`: A curva da taxa de variação ao longo do tempo; o valor padrão é `EasingFunction.EF_LINEAR`. Outros valores fazem a mudança acelerar e/ou desacelerar em diferentes taxas.

```ts
const myEntity = engine.addEntity()

MeshRenderer.setPlane(myEntity)

Transform.create(myEntity, {
	position: Vector3.create(4, 1, 4),
})

Material.setPbrMaterial(myEntity, {
	texture: Material.Texture.Common({
		src: 'materials/water.png',
		wrapMode: TextureWrapMode.TWM_REPEAT,
	}),
})

Tween.setTextureMove(myEntity, Vector2.create(0, 0), Vector2.create(0, 1), 1000)
```

O exemplo acima executa um tween que dura 1 segundo e move a texture apenas uma vez. Para obter um movimento contínuo, por exemplo para simular a queda de uma cascata, você precisa usar `setTextureMoveContinuous`.

```ts
const myEntity = engine.addEntity()

MeshRenderer.setPlane(myEntity)

Transform.create(myEntity, {
	position: Vector3.create(4, 1, 4),
})

Material.setPbrMaterial(myEntity, {
	texture: Material.Texture.Common({
		src: 'materials/water.png',
		wrapMode: TextureWrapMode.TWM_REPEAT,
	}),
})

Tween.setTextureMoveContinuous(myEntity, Vector2.create(0, 1), 1)
```

O exemplo acima usa `setTextureMoveContinuous`com uma direction de `(0, 1)`e uma speed de 1 unidade por segundo.

O texture continuous tween recebe as seguintes informações:

* `entity`A entity da qual a texture será movida
* `direction`Um Vector2 para o movimento
* `speed`Quantas unidades por segundo a entity se moverá

Estes outros parâmetros opcionais também estão disponíveis:

* `movementType`: define se o movimento será no field de offset ou de tiling. Por padrão, usa offset.
* `duration`: Quantos milissegundos manter o movimento. Depois desse tempo, o movimento irá parar.

**Sequências complexas de tween**

Você também pode fazer os movimentos da texture seguirem uma sequência complexa com quantos passos quiser. Use o `sequence` field para listar quantos tweens você quiser; eles serão executados sequencialmente após o primeiro tween descrito no `Tween` component.

```ts
//(...)
Tween.setTextureMove(myEntity, Vector2.create(0, 0), Vector2.create(0, 1), 1000)

TweenSequence.create(myEntity, {
	sequence: [
		{
			mode: Tween.Mode.TextureMove({
				start: Vector2.create(0, 1),
				end: Vector2.create(1, 1),
			}),
			duration: 1000,
			easingFunction: EasingFunction.EF_LINEAR,
		},
		{
			mode: Tween.Mode.TextureMove({
				start: Vector2.create(1, 1),
				end: Vector2.create(1, 0),
			}),
			duration: 1000,
			easingFunction: EasingFunction.EF_LINEAR,
		},
		{
			mode: Tween.Mode.TextureMove({
				start: Vector2.create(1, 0),
				end: Vector2.create(0, 0),
			}),
			duration: 1000,
			easingFunction: EasingFunction.EF_LINEAR,
		},
	],
	loop: TweenLoop.TL_RESTART,
})
```

Observe que, ao definir um tween dentro de uma TweenSequence, você precisa usar o formato mais detalhado de `Tween.Mode.TextureMove` para definir o tween.

### Textures de múltiplas camadas

Você pode usar vários arquivos de imagem como camadas para compor textures mais realistas, por exemplo incluindo uma `bumpTexture` e uma `emissiveTexture`.

```ts
Material.setPbrMaterial(myEntity, {
	texture: Material.Texture.Common({
		src: 'materials/wood.png',
	}),
	bumpTexture: Material.Texture.Common({
		src: 'materials/woodBump.png',
	}),
	emissiveTexture: Material.Texture.Common({
		src: 'materials/glow.png',
	}),
})
```

O `bumpTexture` podem simular relevos e rugas em uma superfície, modificando como os normals da superfície se comportam em cada pixel.

![](https://2402076176-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-b8e239e871864457936864ad2e8021a22338b8ad%2Fwood-bump.png?alt=media\&token=30c048c4-50a0-42b8-8cb2-a3dd29c8c273)

O `emissiveTexture` podem acentuar o brilho em certas partes de um material, para alcançar efeitos muito interessantes.

**Definir UVs**

Outra alternativa para mudar a escala ou o alinhamento de uma texture é configurar *uv* properties no [component MeshRenderer](/creator/content-creator-pt/scenes-sdk7/fundamentos-de-conteudo-3d/shape-components.md).

Você define *u* e *v* coordinates na imagem 2D da texture para corresponder aos vertices da shape. Quanto mais vertices a entity tiver, mais *uv* coordinates precisam ser definidos na texture; uma plane, por exemplo, precisa ter 8 *uv* points definidos, 4 para cada uma de suas duas faces.

```ts
const meshEntity = engine.addEntity()
Transform.create(meshEntity, {
	position: Vector3.create(4, 1, 4),
})
MeshRenderer.setPlane(
	meshEntity,
	[
		0, 0.75,

		0.25, 0.75,

		0.25, 1,

		0, 1,

		0, 0.75,

		0.25, 0.75,

		0.25, 1,

		0, 1,
	]
)

Material.setPbrMaterial(myEntity, {
	texture: Material.Texture.Common({
		src: 'materials/wood.png',
		wrapMode: TextureWrapMode.TWM_REPEAT,
	}),
})
```

O exemplo a seguir inclui uma function que simplifica a definição de uvs. A `setUVs` function definida aqui recebe um número de rows e columns como parameters, e define os uvs para que a imagem da texture seja repetida um número específico de vezes.

```ts
const meshEntity = engine.addEntity()
Transform.create(meshEntity, {
	position: Vector3.create(4, 1, 4),
})
MeshRenderer.setBox(meshEntity, setUVs(3, 3))

Material.setPbrMaterial(myEntity, {
	texture: Material.Texture.Common({
		src: 'materials/atlas.png',
		wrapMode: TextureWrapMode.TWM_REPEAT,
	}),
})

function setUVs(rows: number, cols: number) {
	return [
		//Lado norte de plane sem rotação
		0, //canto inferior esquerdo
		0,

		cols, //canto inferior direito
		0,

		cols, //canto superior direito
		rows,

		0, //canto superior esquerdo
		rows,

		//Lado sul de plane sem rotação
		cols, // canto inferior direito
		0,

		0, // canto inferior esquerdo
		0,

		0, // canto superior esquerdo
		rows,

		cols, // canto superior direito
		rows,
	]
}
```

Para definir os UVs de uma `box` shape mesh, a mesma estrutura se aplica. Cada uma das 6 faces do cube usa 4 pares de coordinates, um para cada canto. Todos esses 48 valores são listados como um único array.

{% hint style="warning" %}
**📔 Observação**: As propriedades UV estão atualmente disponíveis apenas em `plane` e em `box` shapes. Além disso, *uv* os valores afetam igualmente todas as camadas da texture, já que são definidos na *shape*.
{% endhint %}

### Escala da texture

Quando textures são esticadas ou encolhidas para um tamanho diferente do da imagem original da texture, isso às vezes pode criar artifacts. Em um ambiente 3D, os efeitos da perspectiva causam isso naturalmente. Existem vários [filtragem de texture](https://en.wikipedia.org/wiki/Texture_filtering) algorithms que existem para compensar isso de diferentes maneiras.

O `Material` object usa o *bilinear* algoritmo por padrão, mas permite configurar para usar o *nearest neighbor* ou *trilinear* algorithms em vez disso, definindo o `filterMode` property da texture. Isso recebe um valor do `TextureFilterMode` enum:

* `TextureFilterMode.TFM_POINT`: Usa um algoritmo de "nearest neighbor". Esta configuração é ideal para gráficos no estilo pixel art, pois os contornos permanecerão nitidamente marcados à medida que a texture é vista maior na tela, em vez de ficarem borrados.
* `TextureFilterMode.TFM_BILINEAR`: Usa um algoritmo bilinear para estimar a cor de cada pixel.
* `TextureFilterMode.TFM_TRILINEAR`: Usa um algoritmo trilinear para estimar a cor de cada pixel.

```ts
Material.setPbrMaterial(myEntity, {
	texture: Material.Texture.Common({
		src: 'materials/atlas.png',
		filterMode: TextureFilterMode.TFM_BILINEAR,
	}),
})
```

## Materials sem iluminação

Na maioria das vezes, você vai querer que os materials da sua scene sejam afetados pelas condições de iluminação, incluindo sombras e a coloração causada pelas mudanças de matiz em diferentes momentos do dia. Mas, em outros casos, você pode querer mostrar as cores em seu estado puro. Isso é útil ao reproduzir videos, ou também para marcadores abstratos que precisam se destacar, destinados a sinalizar hints ao player.

Para criar um material sem iluminação, use `Material.setBasicMaterial`. Basic materials não têm todas as mesmas propriedades que os materiais PBR; eles têm apenas o essencial:

* `diffuseColor`: Color4 para a cor
* `texture`: Texture
* `alphaTexture`: Texture separada para a layer de transparência
* `alphaTest`: Limite para obter transparência com base na cor da texture
* `castShadows`: Se false, nenhuma sombra é projetada sobre outras entities na scene.

```ts
Material.setBasicMaterial(screen, {
	diffuseColor: Color4.Red(),
})
```

## Retratos de Avatar

Para exibir uma imagem em miniatura de qualquer player, use `Material.Texture.Avatar` ao definir a texture do seu material, passando o endereço de um player existente. Isso cria uma texture a partir de uma imagem 256x256 do player, mostrando cabeça e ombros. O player é exibido usando o conjunto de Wearables que o server atual registrou por último.

```ts
Material.setPbrMaterial(myEntity, {
	texture: Material.Texture.Avatar({
		userId: '0x517....',
	}),
})
```

![](https://2402076176-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-76248b67a42c940111a0d827d74acde8d5093f73%2FavatarTexture.png?alt=media\&token=cc232037-1e1e-4107-8f92-17b77e4a6521)

Você pode obter o retrato de qualquer player do Decentraland, mesmo que ele não esteja conectado no momento, e mesmo que não tenha um NAME do Decentraland reivindicado.

As seguintes propriedades são suportadas dentro do objeto que você passa como argumento:

* `userId`: ID do usuário cujo perfil você deseja exibir
* `filterMode`: Determina como os pixels na texture são esticados ou comprimidos quando renderizados. Isso recebe um valor do `TextureFilterMode` enum. Veja [Escala da Texture](#texture-scaling).
* `wrapMode`: Determina como uma texture é repetida sobre um objeto. Isso recebe um valor do `TextureWrapMode` enum. Veja [Repetição de Texture](#texture-wrapping).

## Materiais transparentes

Para tornar transparente um material com uma cor sólida, basta definir a cor como um `Color4`, e definir o 4º valor para algo entre *0* e *1*. Quanto mais próximo de *1*, mais opaco ele ficará.

```typescript
let transparentRed = Color4.create(1, 0, 0, 0.5)

Material.setPbrMaterial(meshEntity, {
	albedoColor: transparentRed,
})
```

Se um material usar uma textura .png que inclua transparência, ele será opaco por padrão, mas você pode ativar sua transparência definindo o `transparencyMode` para `MaterialTransparencyMode.MTM_ALPHA_BLEND`.

![](https://2402076176-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-7cf6142ee2bc727894e78f01d271556822ebe0fc%2Ftransparent-image.png?alt=media\&token=610b0414-bbdd-442a-ada9-7475df626999)

```typescript
Material.setPbrMaterial(floor, {
	texture: Material.Texture.Common({
		src: 'assets/scene/transparent-image.png',
	}),
	transparencyMode: MaterialTransparencyMode.MTM_ALPHA_BLEND,
})
```

O `transparencyMode` pode ter os seguintes valores:

* `MaterialTransparencyMode.MTM_OPAQUE`: Sem nenhuma transparência
* `MaterialTransparencyMode.MTM_ALPHA_TEST`: Cada pixel é totalmente opaco ou totalmente transparente, com base em um limite.
* `MaterialTransparencyMode.MTM_ALPHA_BLEND`: Valores intermediários são possíveis com base no valor de cada pixel.
* `MaterialTransparencyMode.MTM_ALPHA_TEST_AND_ALPHA_BLEND`: Usa uma combinação de ambos os métodos.
* `MaterialTransparencyMode.MTM_AUTO`: Determina o método com base na textura fornecida.

Se você definir o `transparencyMode` para `MaterialTransparencyMode.MTM_ALPHA_TEST`, você pode ajustar com precisão o limite usado para determinar se cada pixel é transparente ou não. Defina o `alphaTest` property entre *0* e *1*. Por padrão, seu valor é *0.5*.

```ts
// Usando alpha test
Material.setPbrMaterial(meshEntity1, {
	texture: Material.Texture.Common({
		src: 'images/myTexture.png',
	}),
	transparencyMode: MaterialTransparencyMode.MTM_ALPHA_TEST,
	alphaTest: 1,
})
```

Ao usar um [material unlit](#unlit-materials), você pode adicionar um `alphaTexture` para tornar apenas certas regiões do material transparentes, com base em uma textura.

{% hint style="warning" %}
**📔 Observação**: Deve ser uma imagem de um único canal. Nesta imagem, use a cor vermelha ou preta para determinar quais partes da textura real devem ser transparentes.
{% endhint %}

![](https://2402076176-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-29eeafc704d19336cc3b0dc023c91e278b4bcd94%2Fcircular-video-screen.png?alt=media\&token=13d1560a-3d64-4a17-943c-25338f931f48)

```ts
// Usando alpha test
Material.setPbrMaterial(meshEntity1, {
	texture: Material.Texture.Common({
		src: 'images/myTexture.png',
	}),
	alphaTexture: Material.Texture.Common({
		src: 'assets/scene/circle_mask.png',
		wrapMode: TextureWrapMode.TWM_MIRROR,
	}),
})
```

Isso pode ser usado de maneiras muito interessantes junto com vídeos. Veja [vídeo em reprodução](/creator/content-creator-pt/scenes-sdk7/media/video-playing.md).

## Vídeo em reprodução

Para transmitir vídeo de uma URL para um material, ou reproduzir um vídeo de um arquivo armazenado na cena, veja [vídeo em reprodução](/creator/content-creator-pt/scenes-sdk7/media/video-playing.md).

O vídeo é usado como uma textura em um material; você pode definir qualquer uma das outras propriedades dos materiais para alterar a aparência da tela de vídeo.

## Sintaxe avançada

A sintaxe completa para criar um `Materiais` componente, sem nenhum helper para simplificá-lo, é assim:

```ts
Material.create(myEntity, {
	material: {
		$case: 'pbr',
		pbr: {
			texture: {
				tex: {
					$case: 'texture',
					texture: {
						src: 'images/scene-thumbnail.png',
					},
				},
			},
		},
	},
})

Material.create(myEntity, {
	material: {
		$case: 'pbr',
		pbr: {
			texture: {
				tex: {
					$case: 'avatarTexture',
					avatarTexture: {
						userId: '0x517....',
					},
				},
			},
		},
	},
})
```

É assim que o protocolo base interpreta os componentes Materials. As funções auxiliares abstraem isso e expõem uma sintaxe mais amigável, mas nos bastidores elas geram essa sintaxe.

O `$case` campos permitem especificar um dos tipos permitidos. Cada tipo suporta um conjunto diferente de parâmetros. Há dois níveis de `$case` aqui:

* O `material` suporta os valores `pbr` e `unlit`, para definir o tipo de material.
* O `tex` campo dentro de uma texture suporta os seguintes valores, para definir o tipo de textura:
  * `texture`
  * `avatarTexture`
  * `videoTexture`

Dependendo do valor de `$case`, é válido definir o objeto para o tipo correspondente, passando quaisquer propriedades relevantes.

Para adicionar um `Material` componente a uma entity que potencialmente já tenha uma instância desse componente, use `Material.createOrReplace()`. As funções auxiliares como `Material.setPbrMaterial()` lidam com a substituição de instâncias existentes do componente, mas executar `Material.create()` em uma entity que já tenha esse componente retorna um erro.

## Modificar materiais glTF

Use o `GltfNodeModifiers` componente para modificar os materiais de um *glTF* modelo. *glTF* Este componente permite substituir os materiais de um `Material` modelo pelos seus próprios materiais. Você pode usar qualquer uma das propriedades do

Há duas maneiras de usar o `GltfNodeModifiers` componente:

* Modifique o material de todo o modelo deixando a `path` propriedade como uma string vazia.
* Modifique o material de um nó específico no modelo (ou de vários nós) definindo a `path` propriedade como o path para o nó.

### Modificar o material de todo o modelo

O exemplo a seguir mostra como modificar o material de um *glTF* modelo. Neste caso, o material de todo o modelo é modificado para ficar vermelho.

```ts
import { GltfNodeModifiers, GltfContainer, Transform } from '@dcl/sdk/ecs'

const myEntity = engine.addEntity()

GltfContainer.create(myEntity, {
	src: 'models/myModel.glb',
})

Transform.create(myEntity, {
	position: Vector3.create(4, 0, 4),
})

GltfNodeModifiers.create(myEntity, {
	modifiers: [
		{
			path: '',
			material: {
				material: {
					$case: 'pbr',
					pbr: {
						albedoColor: Color4.Red(),
					},
				},
			},
		},
	],
})
```

O `GltfNodeModifiers` componente tem as seguintes propriedades:

* `modifiers`: Um array de modifiers. Cada modifier tem as seguintes propriedades:
  * `path`: O path para o nó no modelo a ser modificado.
  * `material`: O material a ser usado.

O `path` propriedade é uma string que representa o path para o nó no *glTF* modelo a ser modificado. Se você quiser modificar o material de todo o modelo, pode usar uma string vazia. Se você quiser modificar o material de um nó específico, pode usar o path para o nó. O path deve apontar para um nó mesh, não para um nó vertex.

{% hint style="info" %}
**💡 Dica**: Você pode usar o [app Babylon Sandbox](https://sandbox.babylonjs.com/) para inspecionar o *glTF* modelo e encontrar o path para o nó que você deseja modificar.

Em alguns modelos, no entanto, o Babylon Sandbox pode listar paths que pertencem a vertexes em vez de meshes, o que não funcionará. Se você tentar usar um path inválido, o console da cena exibirá uma mensagem de erro que inclui a lista completa de paths válidos nesse modelo.
{% endhint %}

O `material` propriedade é um objeto que representa o material a ser usado. Ela precisa ser escrita usando a [sintaxe avançada](#advanced-syntax) para materiais, como mostrado no exemplo acima. Funções auxiliares como `Material.setPbrMaterial()` não podem ser usadas aqui.

### Modificar o material de um nó específico no modelo

O exemplo a seguir mostra como modificar o material de um nó específico no *glTF* modelo. Neste caso, o material da cabeça é modificado para usar uma textura alternativa.

```ts
import { GltfNodeModifiers, GltfContainer, Transform } from '@dcl/sdk/ecs'

const myEntity = engine.addEntity()

GltfContainer.create(myEntity, {
	src: 'models/myModel.glb',
})

Transform.create(myEntity, {
	position: Vector3.create(4, 0, 4),
})

GltfNodeModifiers.create(myEntity, {
	modifiers: [
		{
			path: 'M_Head_BaseMesh',
			material: {
				material: {
					$case: 'pbr',
					pbr: {
						texture: Material.Texture.Common({
							src: 'assets/scene/images/blinking-head.png',
						}),
					},
				},
			},
		},
	],
})
```

Um `GltfNodeModifiers` pode conter vários modifiers, cada um modificando um nó diferente no modelo. O exemplo a seguir mostra como modificar o material da cabeça e do corpo de um *glTF* modelo.

```ts
import { GltfNodeModifiers, GltfContainer, Transform } from '@dcl/sdk/ecs'

const myEntity = engine.addEntity()

GltfContainer.create(myEntity, {
	src: 'models/myModel.glb',
})

Transform.create(myEntity, {
	position: Vector3.create(4, 0, 4),
})

GltfNodeModifiers.create(myEntity, {
	modifiers: [
		{
			path: 'M_Head_BaseMesh',
			material: {
				material: {
					$case: 'pbr',
					pbr: {
						albedoColor: Color4.Red(),
					},
				},
			},
		},
		{
			path: 'M_Body_BaseMesh',
			material: {
				material: {
					$case: 'pbr',
					pbr: {
						albedoColor: Color4.Blue(),
					},
				},
			},
		},
	],
})
```

### Modificar campos de um material existente

O componente Material fornece uma interface simplificada para acessar e modificar propriedades do componente Material. Ele elimina a necessidade de navegar por estruturas de união profundamente aninhadas (`PBR` vs `Unlit`, `texture` vs `avatarTexture` vs `videoTexture`), tornando a manipulação de materiais mais intuitiva e menos propensa a erros.

Os métodos a seguir permitem uma manipulação fácil do `Material` componente:

* `Material.getFlat(entity: Entity): ReadonlyFlatMaterial`: Ele retorna um **somente leitura** `FlatMaterial` objeto acessor que fornece acesso direto de leitura às propriedades do material. Ele retornará um erro se a entity não tiver um `Material` componente. Para evitar isso, os próximos métodos podem ser usados como alternativa.

```ts
const src = Material.getFlat(entity).texture.src
```

* `Material.getFlatOrNull(entity: Entity): ReadonlyFlatMaterial | null`: Ele retorna um **somente leitura ou null**, dependendo se a entity tem ou não um `Material` component.

```ts
const src = Material.getFlatOrNull(entity)?.texture.src
```

* `Material.getFlatMutable(entity: Entity): FlatMaterial`: Ele retorna um **leitura e escrita** `FlatMaterial`objeto que permite modificar suas propriedades. Ele lançará um erro se a entity chamada não tiver o `Material` component.

```ts
const src = Material.getFlatMutable(entity).texture.src
```

* `Material.getFlatMutableOrNull(entity: Entity): FlatMaterial | null`: Ele retorna um **leitura e escrita ou null** `FlatMaterial` objeto que permite modificar suas propriedades. Caso a entity não tenha um `componente Material`, ele retornará `null`.

```ts
const flatMaterial = Material.getFlatMutableOrNull(entity)
if (flatMaterial) {
	flatMaterial.texture.src = myNewTextureFile
}
```

### Remover sombras de um modelo glTF

Para remover sombras de um *glTF* modelo, você pode definir a `castShadows` propriedade como `false` no `GltfNodeModifiers` objeto. Isso mantém o material original do modelo, mas impede que ele projete sombras. Isso é útil para modelos que não devem projetar sombras, como feixes de luz.

```ts
import { GltfNodeModifiers } from '@dcl/sdk/ecs'

GltfNodeModifiers.create(myEntity, {
	modifiers: [
		{
			path: '',
			castShadows: false,
		},
	],
})
```

{% hint style="info" %}
**💡 Dica**: Texturas usadas em materiais também podem ser aplicadas a efeitos de partículas. Veja [Particle System](/creator/content-creator-pt/scenes-sdk7/fundamentos-de-conteudo-3d/particle-system.md) para detalhes sobre o uso de texturas personalizadas e sprite sheets com partículas.
{% endhint %}

{% hint style="info" %}
**💡 Dica**: Para exemplos práticos de materiais, veja a [`52,-52-testing-gallery`](https://github.com/decentraland/sdk7-test-scenes/tree/main/scenes/52,-52-testing-gallery) cena de teste, que explora combinações de PBR metallic/roughness/emissive/normal-map lado a lado, [`74,-8-gltfnodemodifier`](https://github.com/decentraland/sdk7-test-scenes/tree/main/scenes/74,-8-gltfnodemodifier), que substitui materiais PBR e unlit em nós GLTF individuais, e [`0,3-texture-movement`](https://github.com/decentraland/sdk7-test-scenes/tree/main/scenes/0,3-texture-movement), que anima o deslocamento e a repetição da textura.
{% 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-pt/scenes-sdk7/fundamentos-de-conteudo-3d/materials.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.
