> 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-ko/sdk7/3d/materials.md).

# 재질

기본 도형이 있는 엔티티에 재질과 텍스처를 추가하는 방법을 알아보세요.

## 재질

머티리얼은 다음을 추가하여 기본 도형(cube, sphere, plane 등)을 사용하는 엔티티에 적용할 수 있습니다: `재질` 컴포넌트입니다. 이 컴포넌트에는 머티리얼의 속성을 구성하고 텍스처를 추가하는 등의 작업을 할 수 있는 여러 필드가 있습니다.

*glTF* 모델에는 자체 머티리얼이 포함되어 있으며, 이는 모델과 함께 씬에 암묵적으로 가져와집니다. 이러한 머티리얼을 수정하거나 덮어쓰려면 다음을 사용하세요: `GltfNodeModifiers` 컴포넌트를 사용하여 모든 플레이어를 순회하세요. 자세한 내용은 [glTF 머티리얼 수정](#modify-gltf-materials) 자세한 내용은 다음을 참조하세요.

자체 머티리얼이 있는 3D 모델을 가져올 때, 모든 셰이더가 Decentraland 엔진에서 지원되는 것은 아니라는 점을 기억하세요. 표준 머티리얼과 PBR(물리 기반 렌더링) 머티리얼만 지원됩니다. 다음을 참조하세요: [외부 3D 모델 고려사항](https://github.com/decentraland/docs-creator/blob/main/creator/3d-modeling/materials/README.md) 자세한 내용은 다음을 참조하세요.

지원되는 머티리얼에는 여러 유형이 있습니다:

* PBR(물리 기반 렌더링): Decentraland에서 가장 일반적인 머티리얼 유형입니다. 단색이나 텍스처, metallic, emissive, transparency 등과 같은 다양한 속성을 지원합니다. 자세한 내용은 [PBR](https://en.wikipedia.org/wiki/Physically_based_rendering).
* 기본 머티리얼: 빛과 그림자에 반응하지 않으므로 빌보드 이미지를 표시하는 데 이상적입니다.

## Creator Hub의 Scene Editor를 사용하세요

엔티티에 머티리얼을 부여하는 가장 쉬운 방법은 Scene Editor를 사용하는 것입니다. 엔티티에 다음을 추가할 수 있습니다: **재질** 컴포넌트를 추가한 다음 Scene Editor UI에서 사용 가능한 모든 필드를 구성하세요. 다음을 참조하세요: [컴포넌트 추가](/creator/content-creator-ko/scene-editor/build/components.md#add-components).

## 머티리얼 추가

다음 예제는 PBR 머티리얼을 생성하고 일부 필드를 설정하여 빨간색과 금속성 속성을 부여합니다. 이 머티리얼은 박스 모양도 가진 엔티티에 추가되므로, 이 머티리얼로 박스를 색칠하게 됩니다.

```ts
//엔티티를 생성하고 모양을 할당
const meshEntity = engine.addEntity()
Transform.create(meshEntity, {
	position: Vector3.create(4, 1, 4),
})
MeshRenderer.setBox(meshEntity)

//머티리얼을 생성하고 필드를 구성
Material.setPbrMaterial(meshEntity, {
	albedoColor: Color4.Red(),
	metallic: 0.8,
	roughness: 0.1,
})
```

이미 다음을 가진 엔티티의 머티리얼을 변경하려면 `재질` 컴포넌트가 있다면 다음을 실행하세요: `Material.setPbrMaterial()` 또는 다른 헬퍼 함수를 사용하면 원래 머티리얼이 덮어써집니다. 원래 `재질` 를 제거할 필요도 없고, 고급 구문을 사용할 필요도 없습니다.

```ts
//엔티티를 생성하고 모양을 할당
const meshEntity = engine.addEntity()
Transform.create(meshEntity, {
	position: Vector3.create(4, 1, 4),
})
MeshRenderer.setBox(meshEntity)

//머티리얼을 생성하고 필드를 구성
Material.setPbrMaterial(meshEntity, {
	albedoColor: Color4.Red(),
})

//새 머티리얼 컴포넌트로 덮어쓰기
Material.setPbrMaterial(meshEntity, {
	albedoColor: Color4.Blue(),
})
```

{% hint style="warning" %}
**📔 참고**:  `재질` 컴포넌트는 다음을 통해 가져와야 합니다:

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

참고 [가져오기](/creator/content-creator-ko/sdk7/getting-started/coding-scenes.md#imports) 를 사용하면 이를 쉽게 처리할 수 있습니다.
{% endhint %}

## 머티리얼 색상

머티리얼에 단색을 지정합니다. PBR 머티리얼에서는 다음을 설정합니다: `albedoColor` 필드입니다. 알베도 색상은 빛에 반응하며 명암을 포함할 수 있습니다.

색상 값의 타입은 `Color4`이며, 다음으로 구성됩니다: *r*, *g* 및 *b* 값(빨강, 초록, 파랑)입니다. 각 값은 0과 1 사이의 값을 가집니다. 이 값을 다르게 설정하여 모든 가시 색상을 구성할 수 있습니다. 검정은 세 값을 모두 0으로 설정하세요. 흰색은 모두 1로 설정하세요.

{% hint style="warning" %}
**📔 참고**: 다음의 어떤 색상 값이라도 `albedoColor` 보다 큰 값으로 설정하면 *1*으로 표시되며 *발광하게*값이 클수록 더 강한 발광처럼 보입니다. 예를 들어, `{r: 15, g: 0, b: 0}` 는 매우 밝은 빨간빛을 만들어냅니다.
{% endhint %}

참고 [색상 유형](/creator/content-creator-ko/sdk7/3d/color-types.md) 색상 설정 방법에 대한 자세한 내용은

PBR 머티리얼에서 다음 필드도 편집하여 색상이 어떻게 인식되는지 미세 조정할 수 있습니다:

* *emissiveColor*: 머티리얼에서 방출되는 색상.
* *reflectivityColor*: 일명 *스페큘러 색상* 라는 다른 명칭으로도 불립니다.

빛과 그림자에 영향을 받지 않는 단색 머티리얼을 만들려면 PBR 머티리얼 대신 기본 머티리얼을 만드세요.

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

## 텍스처 사용

머티리얼의 다음을 설정하여 이미지 파일을 텍스처로 지정할 수 있습니다: `텍스처` 매개변수.

```ts
//엔티티를 생성하고 모양을 할당
const meshEntity = engine.addEntity()
Transform.create(meshEntity, {
	position: Vector3.create(4, 1, 4),
})
MeshRenderer.setBox(meshEntity)

//머티리얼을 생성하고 필드를 구성
Material.setPbrMaterial(meshEntity, {
	texture: Material.Texture.Common({
		src: 'assets/materials/wood.png',
	}),
})
```

위 예제에서 머티리얼의 이미지는 다음 폴더에 있습니다: `assets/materials` 폴더이며, 씬 프로젝트 폴더의 루트 수준에 위치합니다.

{% hint style="info" %}
**💡 팁**: 텍스처 이미지 파일은 다음 위치 어딘가에 보관하는 것을 권장합니다: `/assets` 폴더로 씬 내부에 분리해 두는 것을 권장합니다.
{% endhint %}

텍스처를 생성하는 동안 다음 추가 매개변수도 전달할 수 있습니다:

* `filterMode`: 렌더링될 때 텍스처의 픽셀이 늘어나거나 압축되는 방식을 결정합니다. 이 값은 다음에서 가져옵니다: `TextureFilterMode` 열거형입니다. 다음을 참조하세요: [텍스처 스케일링](#texture-scaling).
* `wrapMode`: 텍스처가 객체에 타일링되는 방식을 결정합니다. 이 값은 다음에서 가져옵니다: `TextureWrapMode` 열거형입니다. 다음을 참조하세요: [텍스처 래핑](#texture-wrapping).

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

빛과 그림자에 영향을 받지 않는 텍스처를 만들려면 PBR 머티리얼 대신 기본 머티리얼을 만드세요.

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

### 외부 URL의 텍스처

씬 프로젝트의 내부 경로 대신 외부 URL을 텍스처 대상으로 지정할 수 있습니다.

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

URL은 다음으로 시작해야 합니다: `https`, `http` URL은 지원되지 않습니다.

### 텍스처 래핑

텍스처가 표면에 어떻게 정렬되는지 설정할 수 있습니다. 기본적으로 텍스처는 표면 전체를 한 번 덮도록 늘어나지만, 크기 조정과 오프셋을 적용할 수 있습니다.

모든 텍스처에서 다음 필드를 사용할 수 있습니다:

* `offset`: 텍스처의 정렬을 변경하기 위해 텍스처를 이동합니다. 값은 Vector2이며, 두 축 모두 0에서 1까지의 값을 가집니다. 여기서 1은 텍스처의 전체 너비 또는 높이입니다.
* `tiling`: 텍스처의 크기를 조정합니다. 기본값은 Vector 2 `[1, 1]`이며, 이미지가 표면 전체를 덮으면서 한 번 반복되게 합니다.
* `TextureWrapMode`: 이미지 타일링이 표면 전체를 덮지 못할 때 어떻게 되는지 결정합니다. 이 속성은 다음에서 값을 가져옵니다: `TextureWrapMode` 열거형이며, 다음 값을 허용합니다:
  * `TextureWrapMode.TWM_CLAMP`: 텍스처는 지정된 크기로 한 번만 표시됩니다. 메시 표면의 나머지 부분은 투명하게 남습니다. 값 `tiling` 무시됩니다.
  * `TextureWrapMode.TWM_REPEAT`: 텍스처는 지정된 크기에 맞는 만큼 메시 전체에 반복됩니다.
  * `TextureWrapMode.TWM_MIRROR`: wrap과 마찬가지로 텍스처는 맞는 만큼 반복되지만, 이러한 반복의 방향이 반전됩니다.

```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" %}
**📔 참고**:  `offset` 및 `tiling` 속성은 DCL 2.0 데스크톱 클라이언트에서만 지원됩니다.
{% endhint %}

이 기능을 사용하여 큰 표면을 타일 패턴으로 덮을 수 있습니다. 예를 들어, 다음 이미지를 반복하세요:

![](https://3980763956-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-e0324d6080a0e815b172eafd56b5ece426ca68ca%2Ftiles.png?alt=media)

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

![](https://3980763956-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-6e66e1936998029bf4cd65f497509ae21896809a%2Ftiles-in-scene.png?alt=media)

아래 예제에서 텍스처는 다음을 사용합니다: *미러* 랩 모드이며, 텍스처의 각 반복은 표면의 1/4만 차지합니다. 즉, 서로를 기준으로 양쪽 축에서 미러링된 이미지 사본 4개를 보게 됩니다.

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

### 텍스처 트윈

다음을 사용하여 텍스처가 부드럽게 이동하도록 만드세요: `트윈` 컴포넌트를 다음과 함께 설정하세요: `TextureMove` 모드입니다. 트윈은 시간에 따라 텍스처의 `offset` 또는 `tiling` 속성 값을 부드럽고 최적화된 방식으로 점진적으로 변경합니다.

{% hint style="warning" %}
**📔 참고**: 텍스처 트윈은 DCL 2.0 데스크톱 클라이언트에서만 지원되는 기능입니다.
{% endhint %}

사용하세요 `트윈` 다음을 가진 컴포넌트를 `setTextureMove` 함수를 사용하여 텍스처를 두 위치 사이에서 이동합니다.

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

텍스처 트윈은 다음 정보를 사용합니다:

* `entity`: 텍스처를 이동시킬 엔티티
* `start`: 시작 위치를 나타내는 Vector2
* `end`: 종료 위치를 나타내는 Vector2
* `지속 시간`: 두 위치 사이를 이동하는 데 걸리는 밀리초 수

다음 선택적 매개변수도 사용할 수 있습니다:

* `movementType`: 이동이 다음에서 이루어질지 정의합니다: `offset` 또는 `tiling` 필드입니다. 기본값은 다음입니다: `offset`.
* `easingFunction`: 시간에 따른 변화율 곡선이며, 기본값은 다음입니다: `EasingFunction.EF_LINEAR`입니다. 다른 값은 서로 다른 속도로 변화가 가속 및/또는 감속되게 합니다.

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

위 예제는 1초 동안 실행되는 트윈을 수행하며, 텍스처는 한 번만 이동합니다. 연속적인 움직임을 구현하려면, 예를 들어 폭포가 떨어지는 모습을 시뮬레이션하려면 다음을 사용해야 합니다: `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)
```

위 예제는 다음을 사용합니다: `setTextureMoveContinuous`와 방향은 `(0, 1)`이며, 속도는 초당 1 단위입니다.

연속 텍스처 트윈은 다음 정보를 사용합니다:

* `entity`: 텍스처를 이동시킬 엔티티
* `방향`: 이동을 위한 Vector2
* `속도`: 엔티티가 초당 몇 단위만큼 이동할지

다음의 다른 선택적 매개변수도 사용할 수 있습니다:

* `movementType`: 이동이 offset 필드에서 이뤄질지 tiling 필드에서 이뤄질지를 정의합니다. 기본값은 offset입니다.
* `지속 시간`: 이동을 유지할 밀리초 수입니다. 이 시간이 지나면 이동이 멈춥니다.

**복잡한 트윈 시퀀스**

텍스처 이동을 원하는 만큼 많은 단계로 이루어진 복잡한 시퀀스로 만들 수도 있습니다. 다음을 사용하세요: `sequence` 필드에 원하는 만큼 트윈을 나열하면, 다음에 설명된 첫 번째 트윈 이후 순차적으로 실행됩니다: `트윈` 컴포넌트를 부여해야 합니다.

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

TweenSequence 안에서 트윈을 정의할 때는 다음의 더 상세한 형식을 사용해야 함을 유의하세요. `Tween.Mode.TextureMove` 트윈을 정의합니다.

### 다층 텍스처

여러 이미지 파일을 레이어로 사용하여 더 현실적인 텍스처를 구성할 수 있습니다. 예를 들어 다음을 포함할 수 있습니다: `bumpTexture` 그리고 `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',
	}),
})
```

그 `bumpTexture` 표면의 각 픽셀에서 표면 노멀의 동작을 수정하여 돌기와 주름을 시뮬레이션할 수 있습니다.

![](https://3980763956-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-b8e239e871864457936864ad2e8021a22338b8ad%2Fwood-bump.png?alt=media)

그 `emissiveTexture` 머티리얼의 특정 부분에서 빛나는 효과를 강조하여 매우 흥미로운 효과를 낼 수 있습니다.

**UV 설정**

텍스처의 크기나 정렬을 변경하는 또 다른 방법은 다음을 구성하는 것입니다: *uv* 속성을 [MeshRenderer 컴포넌트에](/creator/content-creator-ko/sdk7/3d/shape-components.md).

다음을 설정합니다: *u* 및 *v* 텍스처의 2D 이미지에서 도형의 꼭짓점에 대응하는 좌표입니다. 엔티티의 꼭짓점 수가 많을수록 더 많은 *uv* 좌표를 텍스처에 정의해야 합니다. 예를 들어 평면은 8개의 *uv* 점을 정의해야 하며, 양쪽 면마다 4개씩입니다.

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

다음 예제에는 UV 설정을 간소화하는 함수가 포함되어 있습니다. 이 `setUVs` 여기에서 정의된 함수는 행과 열의 수를 매개변수로 받아, 텍스처 이미지가 특정 횟수만큼 반복되도록 UV를 설정합니다.

```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 [
		//회전되지 않은 평면의 북쪽 면
		0, //왼쪽 아래 모서리
		0,

		cols, //오른쪽 아래 모서리
		0,

		cols, //오른쪽 위 모서리
		rows,

		0, //왼쪽 위 모서리
		rows,

		//회전되지 않은 평면의 남쪽 면
		cols, //오른쪽 아래 모서리
		0,

		0, //왼쪽 아래 모서리
		0,

		0, //왼쪽 위 모서리
		rows,

		cols, //오른쪽 위 모서리
		rows,
	]
}
```

다음의 UV를 설정하려면: `박스` 메시 모양에도 같은 구조가 적용됩니다. 큐브의 6개 면 각각은 4쌍의 좌표를 가지며, 각 모서리마다 하나씩입니다. 이 48개의 모든 값은 하나의 배열로 나열됩니다.

{% hint style="warning" %}
**📔 참고**: UV 속성은 현재 다음에서만 사용할 수 있습니다: `평면` 그리고 다음에서도 `박스` 모양에서 사용할 수 있습니다. 또한, *uv* 값은 모든 텍스처 레이어에 동일하게 영향을 미칩니다. 이는 다음에 설정되기 때문입니다: *모양*.
{% endhint %}

### 텍스처 스케일링

텍스처가 원본 이미지와 다른 크기로 늘어나거나 줄어들면, 때때로 아티팩트가 생길 수 있습니다. 3D 환경에서는 원근 효과로 인해 이것이 자연스럽게 발생합니다. 이를 다양한 방식으로 보정하는 여러 [텍스처 필터링](https://en.wikipedia.org/wiki/Texture_filtering) 알고리즘이 있습니다.

그 `재질` 객체는 기본적으로 *바이리니어* 알고리즘을 사용하지만, 대신 다음을 사용하도록 구성할 수 있습니다: *최근접 이웃* 또는 *트라이리니어* 알고리즘으로 바꿀 수 있으며, 이를 위해 다음을 설정합니다: `filterMode` 텍스처의 속성입니다. 이 값은 다음에서 가져옵니다: `TextureFilterMode` 열거형의 다음 값 중 하나입니다:

* `TextureFilterMode.TFM_POINT`: "최근접 이웃" 알고리즘을 사용합니다. 이 설정은 픽셀 아트 스타일 그래픽에 이상적입니다. 화면에서 텍스처가 더 크게 보일 때도 흐려지지 않고 윤곽이 선명하게 유지되기 때문입니다.
* `TextureFilterMode.TFM_BILINEAR`: 각 픽셀의 색상을 추정하기 위해 바이리니어 알고리즘을 사용합니다.
* `TextureFilterMode.TFM_TRILINEAR`: 각 픽셀의 색상을 추정하기 위해 트라이리니어 알고리즘을 사용합니다.

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

## 언릿 머티리얼

대부분의 경우 씬의 머티리얼이 그림자를 포함한 조명 조건의 영향을 받고, 시간대에 따른 색조 변화로 물들기를 원할 것입니다. 하지만 경우에 따라 색상을 원래 상태 그대로 보여주고 싶을 수도 있습니다. 이는 비디오 재생이나, 플레이어에게 힌트를 알리는 용도로 눈에 띄어야 하는 추상적 마커에도 유용합니다.

언릿 머티리얼을 만들려면 다음을 사용하세요: `Material.setBasicMaterial`. 기본 머티리얼은 PBR 머티리얼과 완전히 같은 속성을 가지지 않으며, 필수적인 것만 가집니다:

* `diffuseColor`: 색상을 위한 Color4
* `텍스처`: 텍스처
* `alphaTexture`: 투명도 레이어용 별도 텍스처
* `alphaTest`: 텍스처 색상에 따라 투명도를 달성하기 위한 임계값
* `castShadows`: false이면 씬의 다른 엔티티에 그림자가 투영되지 않습니다.

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

## 아바타 초상화

어떤 플레이어의 썸네일 이미지도 표시하려면 다음을 사용하세요: `Material.Texture.Avatar` 머티리얼의 텍스처를 설정할 때, 기존 플레이어의 주소를 전달합니다. 이렇게 하면 플레이어의 256x256 이미지에서 머리와 어깨가 보이는 텍스처가 생성됩니다. 플레이어는 현재 서버가 마지막으로 기록한 착용 아이템 세트를 입은 상태로 표시됩니다.

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

![](https://3980763956-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-76248b67a42c940111a0d827d74acde8d5093f73%2FavatarTexture.png?alt=media)

현재 연결되어 있지 않더라도, 그리고 Decentraland 이름을 아직 등록하지 않았더라도 어떤 Decentraland 플레이어의 초상화도 가져올 수 있습니다.

전달하는 객체 안에서는 다음 속성이 지원됩니다:

* `userId`: 표시하려는 프로필의 사용자 ID
* `filterMode`: 렌더링될 때 텍스처의 픽셀이 늘어나거나 압축되는 방식을 결정합니다. 이 값은 다음에서 가져옵니다: `TextureFilterMode` 열거형입니다. 다음을 참조하세요: [텍스처 스케일링](#texture-scaling).
* `wrapMode`: 텍스처가 객체에 타일링되는 방식을 결정합니다. 이 값은 다음에서 가져옵니다: `TextureWrapMode` 열거형입니다. 다음을 참조하세요: [텍스처 래핑](#texture-wrapping).

## 투명한 머티리얼

단색 머티리얼을 투명하게 만들려면 색상을 다음으로 정의하기만 하면 됩니다: `Color4`, 그리고 네 번째 값을 다음 사이의 값으로 설정하세요: *0* 및 *1*. 다음에 가까울수록 *1*더 불투명해집니다.

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

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

머티리얼이 투명도를 포함한 .png 텍스처를 사용하면 기본적으로 불투명하지만, 다음을 설정하여 투명도를 활성화할 수 있습니다: `transparencyMode` 를 `MaterialTransparencyMode.MTM_ALPHA_BLEND`.

![](https://3980763956-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-7cf6142ee2bc727894e78f01d271556822ebe0fc%2Ftransparent-image.png?alt=media)

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

그 `transparencyMode` 다음 값을 가질 수 있습니다:

* `MaterialTransparencyMode.MTM_OPAQUE`: 투명도 없음
* `MaterialTransparencyMode.MTM_ALPHA_TEST`: 각 픽셀은 임계값에 따라 완전히 불투명하거나 완전히 투명합니다.
* `MaterialTransparencyMode.MTM_ALPHA_BLEND`: 각 픽셀의 값에 따라 중간값도 가능합니다.
* `MaterialTransparencyMode.MTM_ALPHA_TEST_AND_ALPHA_BLEND`: 두 방법을 조합하여 사용합니다.
* `MaterialTransparencyMode.MTM_AUTO`: 제공된 텍스처에 따라 방법을 결정합니다.

다음을 설정하면 `transparencyMode` 를 `MaterialTransparencyMode.MTM_ALPHA_TEST`각 픽셀이 투명한지 여부를 판별하는 데 사용되는 임계값을 세밀하게 조정할 수 있습니다. 다음을 설정하세요: `alphaTest` 속성을 다음 범위로: *0* 및 *1*. 기본값은 다음입니다: *0.5*.

```ts
//알파 테스트 사용
Material.setPbrMaterial(meshEntity1, {
	texture: Material.Texture.Common({
		src: 'images/myTexture.png',
	}),
	transparencyMode: MaterialTransparencyMode.MTM_ALPHA_TEST,
	alphaTest: 1,
})
```

다음을 사용하는 경우: [언릿 머티리얼](#unlit-materials)에서는 다음을 추가할 수 있습니다. `alphaTexture` 텍스처를 기반으로 머티리얼의 특정 영역만 투명하게 만들 수 있습니다.

{% hint style="warning" %}
**📔 참고**: 이것은 단일 채널 이미지여야 합니다. 이 이미지에서는 빨간색 또는 검은색을 사용하여 실제 텍스처의 어떤 부분을 투명하게 할지 결정하세요.
{% endhint %}

![](https://3980763956-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-29eeafc704d19336cc3b0dc023c91e278b4bcd94%2Fcircular-video-screen.png?alt=media)

```ts
//알파 테스트 사용
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,
	}),
})
```

이것은 비디오와 함께 매우 흥미로운 방식으로 사용할 수 있습니다. 다음을 참조하세요: [비디오 재생](/creator/content-creator-ko/sdk7/media/video-playing.md).

## 비디오 재생

URL에서 비디오를 머티리얼로 스트리밍하거나, 씬에 저장된 파일에서 비디오를 재생하려면 다음을 참조하세요: [비디오 재생](/creator/content-creator-ko/sdk7/media/video-playing.md).

비디오는 머티리얼의 텍스처로 사용되며, 다른 머티리얼 속성을 설정하여 비디오 화면의 모습을 변경할 수 있습니다.

## 고급 문법

다음을 생성하기 위한 전체 문법은 `재질` 컴포넌트이며, 이를 단순화하는 헬퍼 없이 보면 다음과 같습니다:

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

기본 프로토콜은 Material 컴포넌트를 이렇게 해석합니다. 헬퍼 함수는 이를 추상화하고 더 친숙한 구문을 제공하지만, 내부적으로는 이 구문을 출력합니다.

그 `$case` 필드를 사용하면 허용된 유형 중 하나를 지정할 수 있습니다. 각 유형은 다른 매개변수 집합을 지원합니다. 다음에는 두 단계의 `$case` 가 있습니다:

* 그 `material` 필드는 다음 값을 지원합니다 `pbr` 및 `unlit`, 머티리얼의 종류를 정의합니다.
* 그 `tex` 텍스처 안의 필드는 다음 값을 지원하며, 텍스처의 종류를 정의합니다:
  * `텍스처`
  * `avatarTexture`
  * `videoTexture`

다음의 값에 따라 `$case`, 해당 종류에 맞는 객체를 정의하고 관련된 속성을 전달하는 것이 유효합니다.

다음을 추가하려면: `재질` 이미 이 컴포넌트의 인스턴스가 있을 수 있는 엔티티에 컴포넌트를 추가하려면 다음을 사용하세요: `Material.createOrReplace()`. 다음과 같은 헬퍼 함수는 `Material.setPbrMaterial()` 기존 컴포넌트 인스턴스 덮어쓰기를 처리하지만, 다음을 실행하면 `Material.create()` 이미 이 컴포넌트를 가진 엔티티에서는 오류가 반환됩니다.

## glTF 머티리얼 수정

사용하세요 `GltfNodeModifiers` 컴포넌트는 다음의 머티리얼을 수정하는 데 사용됩니다: *glTF* 모델입니다. 이 컴포넌트를 사용하면 다음의 머티리얼을 덮어쓸 수 있습니다: *glTF* 모델의 머티리얼을 사용자 지정 머티리얼로 바꿀 수 있습니다. 다음의 어떤 속성도 사용할 수 있습니다: `재질` 텍스처, 비디오 텍스처, 언릿 머티리얼 등을 포함한 컴포넌트.

다음을 사용하는 방법은 두 가지가 있습니다. `GltfNodeModifiers` 컴포넌트:

* 전체 모델의 머티리얼을 수정하려면 `경로` 속성을 빈 문자열로 두세요.
* 를 설정하여 모델의 특정 노드(또는 여러 노드)의 머티리얼을 수정합니다. `경로` 속성을 노드 경로로 설정하세요.

### 전체 모델의 머티리얼 수정

다음 예시는 *glTF* 모델의 머티리얼을 수정하는 방법을 보여줍니다. 이 경우 전체 모델의 머티리얼이 빨간색으로 수정됩니다.

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

그 `GltfNodeModifiers` 컴포넌트에는 다음 속성이 있습니다:

* `modifiers`: 수정자 배열입니다. 각 수정자에는 다음 속성이 있습니다:
  * `경로`: 수정할 모델 내 노드의 경로입니다.
  * `material`: 사용할 머티리얼입니다.

그 `경로` 속성은 *glTF* 모델에서 수정할 노드의 경로를 나타내는 문자열입니다. 전체 모델의 머티리얼을 수정하려면 빈 문자열을 사용할 수 있습니다. 특정 노드의 머티리얼을 수정하려면 해당 노드의 경로를 사용할 수 있습니다. 경로는 버텍스 노드가 아니라 메시 노드를 가리켜야 합니다.

{% hint style="info" %}
**💡 팁**: 다음을 사용할 수 있습니다. [Babylon Sandbox 앱](https://sandbox.babylonjs.com/) 를 사용해 *glTF* 모델을 검사하고 수정하려는 노드의 경로를 찾을 수 있습니다.

하지만 일부 모델에서는 Babylon 샌드박스가 메시가 아니라 버텍스에 속한 경로를 나열할 수 있으며, 이는 작동하지 않습니다. 유효하지 않은 경로를 사용하려고 하면 씬의 콘솔에 해당 모델에서 유효한 경로 전체 목록을 포함한 오류 메시지가 표시됩니다.
{% endhint %}

그 `material` 속성은 사용할 머티리얼을 나타내는 객체입니다. 위 예시에서와 같이 [고급 구문](#advanced-syntax) 을 사용해 머티리얼을 작성해야 합니다. 다음과 같은 헬퍼 함수는 `Material.setPbrMaterial()` 여기서는 사용할 수 없습니다.

### 모델의 특정 노드 머티리얼 수정

다음 예시는 *glTF* 모델의 특정 노드 머티리얼을 수정하는 방법을 보여줍니다. 이 경우 머리의 머티리얼이 대체 텍스처를 사용하도록 수정됩니다.

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

하나의 `GltfNodeModifiers` 에는 여러 수정자를 포함할 수 있으며, 각 수정자는 모델의 서로 다른 노드를 수정합니다. 다음 예시는 *glTF* 모델로 함께 내보냅니다.

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

### 기존 머티리얼의 필드 수정

Material 컴포넌트는 Material 컴포넌트 속성에 접근하고 수정할 수 있는 간소화된 인터페이스를 제공합니다. 깊게 중첩된 유니온 구조를 탐색할 필요를 없애며(`PBR` 대 `Unlit`, `텍스처` 대 `avatarTexture` 대 `videoTexture`), 머티리얼 조작을 더 직관적이고 오류가 덜 나게 만듭니다.

다음 메서드를 사용하면 `재질` 컴포넌트:

* `Material.getFlat(entity: Entity): ReadonlyFlatMaterial`: 를 반환합니다. **읽기 전용** `FlatMaterial` 액세서 객체로, 머티리얼 속성에 대한 직접 읽기 접근을 제공합니다. 엔티티에 `재질` 컴포넌트가 없으면 오류가 반환됩니다. 이를 피하려면 다음 메서드를 대안으로 사용할 수 있습니다.

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

* `Material.getFlatOrNull(entity: Entity): ReadonlyFlatMaterial | null`: 를 반환합니다. **읽기 전용 또는 null**, 엔티티에 `재질` 컴포넌트를 부여해야 합니다.

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

* `Material.getFlatMutable(entity: Entity): FlatMaterial`: 를 반환합니다. **읽기/쓰기** `FlatMaterial`객체로, 해당 속성을 수정할 수 있게 합니다. 호출된 엔티티에 `재질` 컴포넌트를 부여해야 합니다.

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

* `Material.getFlatMutableOrNull(entity: Entity): FlatMaterial | null`: 를 반환합니다. **읽기/쓰기 또는 null** `FlatMaterial` 객체로, 해당 속성을 수정할 수 있게 합니다. 엔티티에 `Material 컴포넌트`가 없으면 `null`.

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

### glTF 모델에서 그림자 제거

다음에서 그림자를 제거하려면 *glTF* 모델의 `castShadows` 속성을 `false` 의 `GltfNodeModifiers` 객체를 설정하면 됩니다. 이렇게 하면 모델의 원래 머티리얼은 유지되지만 그림자를 드리우지 않게 됩니다. 이는 광선과 같이 그림자를 드리우도록 의도되지 않은 모델에 유용합니다.

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

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

{% hint style="info" %}
**💡 팁**: 머티리얼에 사용된 텍스처는 파티클 효과에도 적용할 수 있습니다. 자세한 내용은 [파티클 시스템](/creator/content-creator-ko/sdk7/3d/particle-system.md) 를 참조하여 파티클에서 사용자 지정 텍스처와 스프라이트 시트를 사용하는 방법을 확인하세요.
{% endhint %}

{% hint style="info" %}
**💡 팁**: 머티리얼의 작동 예시는 다음을 참조하세요. [`52,-52-testing-gallery`](https://github.com/decentraland/sdk7-test-scenes/tree/main/scenes/52,-52-testing-gallery) 테스트 씬으로, PBR 메탈릭/거칠기/발광/노멀 맵 조합을 나란히 훑어보며 보여줍니다. [`74,-8-gltfnodemodifier`](https://github.com/decentraland/sdk7-test-scenes/tree/main/scenes/74,-8-gltfnodemodifier)이는 개별 GLTF 노드의 PBR 및 언릿 머티리얼을 덮어쓰며, [`0,3-texture-movement`](https://github.com/decentraland/sdk7-test-scenes/tree/main/scenes/0,3-texture-movement)텍스처 오프셋과 타일링을 애니메이션합니다.
{% 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 dynamically by asking a question.

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

```
GET https://docs.decentraland.org/creator/content-creator-ko/sdk7/3d/materials.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
