材质
了解如何为具有基础几何形状的实体添加材质和纹理。
材质
可以通过添加一个 材质 组件。此组件包含多个字段,可让你配置材质属性、添加纹理等。
glTF 模型包含其自己的材质,这些材质会与模型一起被隐式导入到场景中。要修改或覆盖这些材质,请使用 GltfNodeModifiers 组件遍历所有玩家。参见 修改 glTF 材质 了解更多详情。
在导入带有自身材质的 3D 模型时,请记住 Decentraland 引擎并不支持所有着色器。仅支持标准材质和 PBR(基于物理的渲染)材质。参见 外部 3D 模型注意事项 了解更多详情。
支持的材质有不同类型:
PBR(基于物理的渲染):Decentraland 中最常见的材质类型。它支持纯色或纹理,以及金属度、自发光、透明度等不同属性。阅读更多关于 PBR.
基础材质:它们不会响应光照和阴影,因此非常适合显示公告板图像。
在 Creator Hub 中使用 Scene Editor
给实体添加材质的最简单方法是使用场景编辑器。你可以向你的实体添加一个 材质 组件,然后在场景编辑器 UI 上配置所有可用字段。参见 添加组件.
添加材质
下面的示例创建了一个 PBR 材质,并将其部分字段设置为红色和金属属性。此材质被添加到一个同时具有盒子形状的实体,因此它会使用此材质为盒子着色。
//创建实体并分配形状
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() 或其他任一辅助函数,它就会覆盖原始材质。无需移除原始的 材质 ,也无需使用高级语法。
材质颜色
给材质设置纯色。在 PBR 材质中,你设置 albedoColor 字段。Albedo 颜色会响应光照,并且可以包含阴影。
颜色值的类型是 Color4,由 r, g 和 b 个值组成(红、绿和蓝)。这三个值都取 0 到 1 之间的值。通过为它们设置不同的值,你可以组合出任何可见颜色。黑色时,将三个值都设为 0。白色时,全部设为 1。
📔 注意:如果你在 albedoColor 中将任何颜色设为高于 1的值,它将显示为 发光,且值越高,强度越强。例如, {r: 15, g: 0, b: 0} 会产生非常明亮的红色辉光。
参见 颜色类型 了解如何设置颜色的更多详情。
你还可以在 PBR 材质中编辑以下字段,以微调其颜色的感知效果:
emissiveColor:材质发出的颜色。
reflectivityColor:也称为 镜面颜色 ,在其他命名法中。
要创建一个不受环境光照和阴影影响的纯色材质,请创建基础材质而不是 PBR 材质。
使用纹理
通过设置 纹理 参数,将图像文件设为材质上的纹理。
在上面的示例中,材质的图像位于一个 assets/materials 文件夹中,该文件夹位于场景项目文件夹的根级别。
在创建纹理时,你还可以传递其他参数:
filterMode:决定纹理中的像素在渲染时如何被拉伸或压缩。此项取值来自TextureFilterMode枚举。参见 纹理缩放.wrapMode:决定纹理如何平铺到对象上。此项取值来自TextureWrapMode枚举。参见 纹理平铺.
要创建一个不受环境光照和阴影影响的纹理,请创建基础材质而不是 PBR 材质。
来自外部 URL 的纹理
你可以将材质的纹理指向一个外部 URL,而不是场景项目中的内部路径。
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:与平铺类似,纹理会按可容纳的次数重复,但这些重复的方向会镜像。
📔 注意: offset 和 tiling 属性仅在 DCL 2.0 桌面客户端中受支持。
使用此功能可以用平铺图案覆盖大片表面。例如,重复以下图像:


在下面的示例中,纹理使用了一个 镜像 平铺模式,并且纹理的每次重复只占表面的 1/4。这意味着我们会看到 4 张图像副本,它们在两个轴上彼此镜像。
纹理补间
通过使用一个 补间 组件,让纹理平滑滑动,并用 TextureMove 模式。tween 会逐渐更改 offset 或 tiling 纹理属性值,在一段时间内以平滑且优化的方式进行。
📔 注意:Texture Tween 是仅在 DCL 2.0 桌面客户端中受支持的功能。
使用 补间 组件,并使用 setTextureMove 函数在两个位置之间移动纹理。
纹理补间接受以下信息:
实体:要移动其纹理的实体start:表示起始位置的 Vector2end:表示结束位置的 Vector2持续时间:在两个位置之间移动需要多少毫秒
另外还有一个可选参数:
movementType:定义移动是否会在offset或tiling字段上。默认使用offset.easingFunction:随时间变化速率的曲线,默认值是EasingFunction.EF_LINEAR。其他值会使变化以不同速度加速和/或减速。
上面的示例运行一个持续 1 秒的 tween,并且只移动纹理一次。要实现持续移动,例如模拟瀑布的下落,你需要使用 setTextureMoveContinuous.
上面的示例使用 setTextureMoveContinuous,方向为 (0, 1),速度为每秒 1 个单位。
连续纹理补间接受以下信息:
实体:要移动其纹理的实体方向:表示移动的 Vector2速度:实体每秒将移动多少单位
还有这些其他可选参数可用:
movementType:定义移动作用于偏移字段还是平铺字段。默认使用偏移。持续时间:持续移动多少毫秒。到这段时间后,移动将停止。
复杂的 tween 序列
你还可以让纹理移动遵循一个复杂序列,步骤数量不限。使用 sequence 字段来列出任意数量的 tween,它们会在 补间 组件。
请注意,在 TweenSequence 中定义补间时,你需要使用更详细的 Tween.Mode.TextureMove 来定义该 tween。
多层纹理
你可以使用多个图像文件作为图层来组合出更逼真的纹理,例如包括一个 bumpTexture 和一个 emissiveTexture.
该 bumpTexture 可以通过修改表面法线在每个像素上的表现方式,来模拟表面的凹凸和皱褶。

该 emissiveTexture 可以增强材质某些部分的发光效果,以实现非常有趣的效果。
设置 UV
另一种改变纹理缩放或对齐方式的办法,是配置 uv 属性,位于 MeshRenderer 组件.
你设置 u 和 v 坐标在纹理的二维图像上与形状的顶点对应。实体拥有的顶点越多,需要在纹理上定义的 uv 坐标就越多,例如一个平面需要有 8 个 uv 点被定义,每一面各 4 个。
下面的示例包含一个简化 UV 设置的函数。 setUVs 这里定义的函数接收行数和列数作为参数,并设置 UV,使纹理图像重复指定的次数。
为一个 盒子 网格形状设置 UV 时,适用相同的结构。立方体的 6 个面中的每一个都使用 4 对坐标,每个角各一对。这 48 个值都作为单个数组列出。
📔 注意:Uv 属性目前仅适用于 平面 以及 盒子 形状。此外, uv 值会同等影响所有纹理层,因为它们是设置在 形状.
纹理缩放
当纹理被拉伸或缩小到与原始纹理图像不同的尺寸时,有时会产生伪影。在 3D 环境中,透视效果会自然造成这一点。存在各种 纹理过滤 算法可用来以不同方式对此进行补偿。
该 材质 对象默认使用 双线性 算法作为默认值,但你可以将其配置为使用 最近邻 或 三线性 算法来代替,只需设置纹理的 filterMode 属性。此项取值来自 TextureFilterMode 枚举:
TextureFilterMode.TFM_POINT:使用“最近邻”算法。此设置非常适合像素风格图形,因为当纹理在屏幕上显示得更大时,其轮廓仍会保持清晰,而不会变得模糊。TextureFilterMode.TFM_BILINEAR:使用双线性算法来估算每个像素的颜色。TextureFilterMode.TFM_TRILINEAR:使用三线性算法来估算每个像素的颜色。
无光照材质
大多数情况下,你会希望场景中的材质受光照条件影响,包括阴影以及被不同时段的色调变化所染色。但在某些情况下,你可能希望颜色保持纯净状态。这在播放视频时很有用,也适用于需要突出显示的抽象标记,它们用于向玩家提示信息。
要创建无光照材质,请使用 Material.setBasicMaterial。基础材质并不具备与 PBR 材质相同的所有属性,它们只包含最基本的:
diffuseColor:用于颜色的 Color4纹理:纹理alphaTexture:用于透明层的单独纹理alphaTest:基于纹理颜色实现透明度的阈值castShadows:如果为 false,则不会向场景中的其他实体投射阴影。
头像肖像
要显示任何玩家的缩略图,请使用 Material.Texture.Avatar 在设置材质纹理时,传入一个现有玩家的地址。这样会从该玩家 256x256 的图像创建纹理,显示头部和肩膀。玩家会显示为当前服务器最近记录的穿戴物。

你可以获取任何 Decentraland 玩家的人像,即使他们当前没有连接,也即使他们没有已认领的 Decentraland 名称。
以下属性可在你作为参数传入的对象中使用:
userId要显示其资料的用户 IDfilterMode:决定纹理中的像素在渲染时如何被拉伸或压缩。此项取值来自TextureFilterMode枚举。参见 纹理缩放.wrapMode:决定纹理如何平铺到对象上。此项取值来自TextureWrapMode枚举。参见 纹理平铺.
透明材质
要让纯色材质变为透明,只需将颜色定义为一个 Color4,并将第 4 个值设为 0 到 0 和 1之间的某个值。 1越接近
如果材质使用包含透明度的 .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.
当使用一个 无光照材质中,你可以可视化地添加一个 alphaTexture 来根据纹理仅使材质的某些区域透明时。
📔 注意:这必须是一张单通道图像。在这张图像中,使用红色或黑色来确定真实纹理的哪些部分应该是透明的。

这与视频结合起来可以用在非常有趣的方式中。参见 视频播放.
视频播放
要将 URL 中的视频流输入材质,或播放存储在场景中的文件视频,请参见 视频播放.
视频被用作材质上的纹理时,你可以设置材质的任何其他属性来改变视频屏幕的外观。
高级语法
创建 材质 组件的完整语法,不借助任何简化它的辅助函数,如下所示:
这就是基础协议如何解释 Materials 组件的方式。辅助函数将其抽象掉并提供更友好的语法,但在幕后它们输出的是这种语法。
该 $case 字段允许你指定其中一种允许的类型。每种类型都支持一组不同的参数。有两层 $case 如下:
该
材质字段支持以下值pbr和unlit,用于定义材质的种类。该
tex字段在纹理内部支持以下值,用于定义纹理的种类:纹理avatarTexturevideoTexture
根据 $case,在这种情况下,你可以定义对应种类的对象,并传入任何相关属性。
要向一个 材质 组件添加到一个可能已经有该组件实例的实体上,请使用 Material.createOrReplace()。像 Material.setPbrMaterial() 这样的辅助函数会处理覆盖现有组件实例的问题,但对一个已经有此组件的实体运行 Material.create() 会返回错误。
修改 glTF 材质
使用 GltfNodeModifiers 组件来修改一个 glTF 模型的材质。此组件允许你使用自己的材质覆盖一个 glTF 模型的材质。你可以使用该 材质 组件,包括纹理、视频纹理、无光照材质等。
有两种方式使用 GltfNodeModifiers 组件:
通过将整个模型的材质修改为
path属性留空字符串。通过将模型中特定节点(或多个节点)的材质修改为设置
path属性为该节点的路径。
修改整个模型的材质
以下示例展示了如何修改一个 glTF 模型的材质。在这种情况下,整个模型的材质被修改为红色。
该 GltfNodeModifiers 组件具有以下属性:
modifiers:一个修饰符数组。每个修饰符具有以下属性:path:要修改的模型中节点的路径。材质:要使用的材质。
该 path 属性是一个字符串,表示模型中要修改的节点路径。 glTF 如果你想修改整个模型的材质,可以使用空字符串。如果你想修改某个特定节点的材质,可以使用该节点的路径。该路径必须指向一个网格节点,而不是顶点节点。
该 材质 属性是一个表示要使用的材质的对象。它需要使用 高级语法 来编写材质,如上面的示例所示。像 Material.setPbrMaterial() 这样的辅助函数在这里不能使用。
修改模型中特定节点的材质
以下示例展示了如何修改 glTF 模型中特定节点的材质。在这种情况下,头部的材质被修改为使用另一张纹理。
一个 GltfNodeModifiers 可以包含多个修饰符,每个修饰符修改模型中的不同节点。以下示例展示了如何修改一个 glTF 模型。
修改现有材质中的字段
Material 组件提供了一个简化的接口,用于访问和修改 Material 组件属性。它消除了深入嵌套的联合结构(PBR 与 Unlit, 纹理 与 avatarTexture 与 videoTexture)之间的导航,使材质操作更加直观,也更不容易出错。
以下方法可轻松操作 材质 组件:
Material.getFlat(entity: Entity): ReadonlyFlatMaterial:它返回一个 只读FlatMaterial访问器对象,可直接读取材质属性。如果实体没有材质组件,就会返回错误。为避免这种情况,可以使用接下来的方法作为替代。
Material.getFlatOrNull(entity: Entity): ReadonlyFlatMaterial | null:它返回一个 只读或空值,具体取决于实体是否具有材质组件。
Material.getFlatMutable(entity: Entity): FlatMaterial:它返回一个 读写FlatMaterial对象,允许修改它的属性。如果被调用的实体没有材质组件。
Material.getFlatMutableOrNull(entity: Entity): FlatMaterial | null:它返回一个 读写或空值FlatMaterial对象,允许修改它的属性。如果实体没有Material 组件,则会返回null.
从 glTF 模型中移除阴影
要从一个 glTF 模型中移除阴影,你可以设置 castShadows 属性设为 false 在 GltfNodeModifiers 对象。这会保留模型原有的材质,但会阻止它投射阴影。这对于不需要投射阴影的模型很有用,例如光束。
最后更新于