advanced-rendering
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAdvanced Rendering in Decentraland
Decentraland 中的高级渲染
When to Use Which Rendering Feature
各渲染功能的适用场景
| Need | Component | When |
|---|---|---|
| Entity faces the camera | | Name tags, signs, sprite-like objects |
| Text in the 3D world | | Labels, signs, floating text above entities |
| Custom material appearance | | Metallic, rough, transparent, emissive surfaces |
| Show/hide without removing | | LOD systems, toggling objects, conditional display |
| Modify GLTF model nodes | | Override materials or shadow casting on specific mesh nodes |
Decision flow:
- Need text on screen? → Use build-ui (React-ECS Label) instead
- Need text in 3D space? → (+
TextShapeto face camera)Billboard - Need glowing/transparent materials? → with emissive/transparency
Material.setPbrMaterial - Need to override material on a model node? → with
GltfNodeModifiersarraymodifiers
| 需求 | 组件 | 使用场景 |
|---|---|---|
| 实体朝向摄像机 | | 名牌、标牌、精灵类对象 |
| 3D 世界中的文字 | | 标签、标牌、实体上方的浮动文字 |
| 自定义材质外观 | | 金属、粗糙、透明、自发光表面 |
| 无需移除即可显示或隐藏 | | LOD 系统、对象切换、条件显示 |
| 修改 GLTF 模型节点 | | 覆盖特定网格节点的材质或阴影投射 |
决策流程:
- 需要屏幕上的文字?→ 使用 build-ui(React-ECS Label),而不是 3D 文字
- 需要 3D 空间中的文字?→ 使用 (配合
TextShape朝向摄像机)Billboard - 需要发光或透明材质?→ 使用带有自发光或透明设置的
Material.setPbrMaterial - 需要覆盖模型节点的材质?→ 使用带有 数组的
modifiersGltfNodeModifiers
Billboard (Face the Camera)
Billboard(朝向摄像机)
Make entities always rotate to face the player's camera:
typescript
import { engine, Transform, Billboard, BillboardMode, MeshRenderer } from '@dcl/sdk/ecs'
import { Vector3 } from '@dcl/sdk/math'
const sign = engine.addEntity()
Transform.create(sign, { position: Vector3.create(8, 2, 8) })
MeshRenderer.setPlane(sign)
// Rotate only on Y axis (most common — stays upright)
Billboard.create(sign, {
billboardMode: BillboardMode.BM_Y
})使实体始终旋转并朝向玩家的摄像机:
typescript
import { engine, Transform, Billboard, BillboardMode, MeshRenderer } from '@dcl/sdk/ecs'
import { Vector3 } from '@dcl/sdk/math'
const sign = engine.addEntity()
Transform.create(sign, { position: Vector3.create(8, 2, 8) })
MeshRenderer.setPlane(sign)
// Rotate only on Y axis (most common — stays upright)
Billboard.create(sign, {
billboardMode: BillboardMode.BM_Y
})Billboard Modes
Billboard 模式
typescript
BillboardMode.BM_Y // Rotate on Y axis only (stays upright) — most common
BillboardMode.BM_ALL // Rotate on all axes (fully faces camera)
BillboardMode.BM_X // Rotate on X axis only
BillboardMode.BM_Z // Rotate on Z axis only
BillboardMode.BM_NONE // No billboard rotation- Prefer over
BM_Yfor most use cases — it looks more natural and is cheaper to render.BM_ALL - is useful for particles or effects that should always directly face the camera.
BM_ALL - No flag. The SDK7
oppositeDirectioncomponent exposes onlyBillboard— there is no way to invert which model face points at the camera. If a model shows its back instead of its front, rotate the model 180° on Y (billboardMode). On a parent-Billboard + child-model setup, apply the rotation to the child — the Billboard owns the parent's rotation.Quaternion.fromEulerDegrees(0, 180, 0) - Porting note: SDK6 → SDK7 ports occasionally show a billboarded model facing away from the camera that was correct under SDK6. The two SDKs appear to disagree on which face the billboard points at the camera. Same fix — rotate the displayed model 180° on Y. See [[migrate-sdk6-to-sdk7]] (Common Pitfalls) for context.
typescript
BillboardMode.BM_Y // Rotate on Y axis only (stays upright) — most common
BillboardMode.BM_ALL // Rotate on all axes (fully faces camera)
BillboardMode.BM_X // Rotate on X axis only
BillboardMode.BM_Z // Rotate on Z axis only
BillboardMode.BM_NONE // No billboard rotation- 大多数场景应优先使用 而不是
BM_Y——它看起来更自然,渲染成本也更低。BM_ALL - 适用于需要始终正对摄像机的粒子或特效。
BM_ALL - 不存在 标志。 SDK7 的
oppositeDirection组件仅公开Billboard——无法反转模型正面指向摄像机的方式。如果模型显示的是背面而不是正面,请在 Y 轴上将模型旋转 180°(billboardMode)。在父级 Billboard 与子级模型的结构中,应将旋转应用于子级——父级的旋转由 Billboard 控制。Quaternion.fromEulerDegrees(0, 180, 0) - 移植说明:从 SDK6 移植到 SDK7 后,有时原本在 SDK6 中正确朝向摄像机的 billboard 模型会朝向相反方向。两个 SDK 对 billboard 指向摄像机时模型面的处理似乎存在差异。可使用同样的方法解决——在 Y 轴上将显示的模型旋转 180°。有关背景信息,请参阅 [[migrate-sdk6-to-sdk7]](常见陷阱)。
Face another entity — targetEntity
targetEntity面向其他实体——targetEntity
targetEntityBillboardtargetEntity?: Entitytypescript
// Face a specific entity instead of the camera
Billboard.create(card, { targetEntity: sphere })
// Yaw-only tracking of a target (BM_Y respected while targeting)
Billboard.create(card, { targetEntity: target, billboardMode: BillboardMode.BM_Y })
// Retarget at runtime
Billboard.getMutable(card).targetEntity = otherEntity- Unset (default) → faces the main camera, exactly as before. is fully backwards-compatible.
targetEntity - Setting to the camera reserved entity (
targetEntity, idengine.CameraEntity) is equivalent to leaving it unset.2 - still applies:
billboardModewith aBM_Yyaws to face the target on the Y axis only.targetEntity - Gotcha: if the referenced target entity does not exist or is deleted, billboard reorientation is disabled (the entity freezes at its last orientation) until the target exists again.
- Multiplayer: a camera-facing billboard is computed locally per player (each player sees it facing themselves, nothing is synced). A billboard instead faces the same way for all players, because the target's position is scene state. Use
targetEntitywhen every player must see the same orientation.targetEntity
BillboardtargetEntity?: Entitytypescript
// Face a specific entity instead of the camera
Billboard.create(card, { targetEntity: sphere })
// Yaw-only tracking of a target (BM_Y respected while targeting)
Billboard.create(card, { targetEntity: target, billboardMode: BillboardMode.BM_Y })
// Retarget at runtime
Billboard.getMutable(card).targetEntity = otherEntity- 未设置(默认)→ 朝向主摄像机,与之前的行为完全相同。完全向后兼容。
targetEntity - 将 设置为摄像机保留实体(
targetEntity,ID 为engine.CameraEntity),效果等同于不设置该字段。2 - 仍然生效:使用
billboardMode时,targetEntity只会让实体在 Y 轴上转向目标。BM_Y - 注意:如果引用的目标实体不存在或已被删除,billboard 重定向功能会被禁用,实体将保持最后一次的朝向,直到目标实体重新存在。
- 多人游戏:朝向摄像机的 billboard 会在每名玩家的本地分别计算,因此每名玩家看到的实体都朝向自己,不进行任何同步。使用 的 billboard 则会因为目标位置属于场景状态而对所有玩家保持相同朝向。当所有玩家必须看到相同朝向时,应使用
targetEntity。targetEntity
TextShape (3D Text)
TextShape(3D 文字)
Render text directly in 3D space:
typescript
import { engine, Transform, TextShape, TextAlignMode } from '@dcl/sdk/ecs'
import { Vector3, Color4 } from '@dcl/sdk/math'
const label = engine.addEntity()
Transform.create(label, { position: Vector3.create(8, 3, 8) })
TextShape.create(label, {
text: 'Hello World!',
fontSize: 24,
textColor: Color4.White(),
outlineColor: Color4.Black(),
outlineWidth: 0.1,
textAlign: TextAlignMode.TAM_MIDDLE_CENTER
})- Keep readable — 16-32 for in-world text.
fontSize - Always add and
outlineColorfor legibility against any background.outlineWidth
直接在 3D 空间中渲染文字:
typescript
import { engine, Transform, TextShape, TextAlignMode } from '@dcl/sdk/ecs'
import { Vector3, Color4 } from '@dcl/sdk/math'
const label = engine.addEntity()
Transform.create(label, { position: Vector3.create(8, 3, 8) })
TextShape.create(label, {
text: 'Hello World!',
fontSize: 24,
textColor: Color4.White(),
outlineColor: Color4.Black(),
outlineWidth: 0.1,
textAlign: TextAlignMode.TAM_MIDDLE_CENTER
})- 确保 易于阅读——场景内文字建议使用 16-32。
fontSize - 始终添加 和
outlineColor,以确保文字在任何背景上都清晰可辨。outlineWidth
Text Alignment Options
文字对齐选项
typescript
TextAlignMode.TAM_TOP_LEFT
TextAlignMode.TAM_TOP_CENTER
TextAlignMode.TAM_TOP_RIGHT
TextAlignMode.TAM_MIDDLE_LEFT
TextAlignMode.TAM_MIDDLE_CENTER
TextAlignMode.TAM_MIDDLE_RIGHT
TextAlignMode.TAM_BOTTOM_LEFT
TextAlignMode.TAM_BOTTOM_CENTER
TextAlignMode.TAM_BOTTOM_RIGHTFor the floating-label pattern (Billboard + TextShape combined into a camera-facing label), see the Floating Label (Billboard + TextShape) section in .
{baseDir}/references/rendering-patterns.mdtypescript
TextAlignMode.TAM_TOP_LEFT
TextAlignMode.TAM_TOP_CENTER
TextAlignMode.TAM_TOP_RIGHT
TextAlignMode.TAM_MIDDLE_LEFT
TextAlignMode.TAM_MIDDLE_CENTER
TextAlignMode.TAM_MIDDLE_RIGHT
TextAlignMode.TAM_BOTTOM_LEFT
TextAlignMode.TAM_BOTTOM_CENTER
TextAlignMode.TAM_BOTTOM_RIGHT有关浮动标签模式(将 Billboard 与 TextShape 组合成朝向摄像头的标签),请参阅 中的**浮动标签(Billboard + TextShape)**部分。
{baseDir}/references/rendering-patterns.mdAdvanced PBR Materials
高级 PBR 材质
Metallic and Roughness
金属度与粗糙度
typescript
import { engine, Transform, MeshRenderer, Material, MaterialTransparencyMode } from '@dcl/sdk/ecs'
import { Color4, Color3 } from '@dcl/sdk/math'
// Shiny metal
Material.setPbrMaterial(entity, {
albedoColor: Color4.create(0.8, 0.8, 0.9, 1),
metallic: 1.0,
roughness: 0.1
})
// Rough stone
Material.setPbrMaterial(entity, {
albedoColor: Color4.create(0.5, 0.5, 0.5, 1),
metallic: 0.0,
roughness: 0.9
})typescript
import { engine, Transform, MeshRenderer, Material, MaterialTransparencyMode } from '@dcl/sdk/ecs'
import { Color4, Color3 } from '@dcl/sdk/math'
// Shiny metal
Material.setPbrMaterial(entity, {
albedoColor: Color4.create(0.8, 0.8, 0.9, 1),
metallic: 1.0,
roughness: 0.1
})
// Rough stone
Material.setPbrMaterial(entity, {
albedoColor: Color4.create(0.5, 0.5, 0.5, 1),
metallic: 0.0,
roughness: 0.9
})Transparency
透明效果
typescript
// Alpha blend — smooth transparency
Material.setPbrMaterial(entity, {
albedoColor: Color4.create(1, 0, 0, 0.5), // 50% transparent red
transparencyMode: MaterialTransparencyMode.MTM_ALPHA_BLEND
})
// Alpha test — cutout (binary visible/invisible based on threshold)
Material.setPbrMaterial(entity, {
texture: Material.Texture.Common({ src: 'assets/Images/cutout.png' }),
transparencyMode: MaterialTransparencyMode.MTM_ALPHA_TEST,
alphaTest: 0.5
})- is cheaper than
MTM_ALPHA_TEST— use cutout when smooth transparency isn't needed.MTM_ALPHA_BLEND
typescript
// Alpha blend — smooth transparency
Material.setPbrMaterial(entity, {
albedoColor: Color4.create(1, 0, 0, 0.5), // 50% transparent red
transparencyMode: MaterialTransparencyMode.MTM_ALPHA_BLEND
})
// Alpha test — cutout (binary visible/invisible based on threshold)
Material.setPbrMaterial(entity, {
texture: Material.Texture.Common({ src: 'assets/Images/cutout.png' }),
transparencyMode: MaterialTransparencyMode.MTM_ALPHA_TEST,
alphaTest: 0.5
})- 比
MTM_ALPHA_TEST成本更低——不需要平滑透明效果时应使用镂空方式。MTM_ALPHA_BLEND
Emissive (Glow Effects)
自发光(辉光效果)
typescript
// Glowing material (emissiveColor uses Color3, not Color4)
Material.setPbrMaterial(entity, {
albedoColor: Color4.create(0, 0, 0, 1),
emissiveColor: Color3.create(0, 1, 0), // Green glow
emissiveIntensity: 2.0
})
// Emissive with texture
Material.setPbrMaterial(entity, {
texture: Material.Texture.Common({ src: 'assets/Images/diffuse.png' }),
emissiveTexture: Material.Texture.Common({ src: 'assets/Images/emissive.png' }),
emissiveIntensity: 1.0,
emissiveColor: Color3.White()
})- Use with a dark
emissiveColorfor maximum glow visibility.albedoColor
typescript
// Glowing material (emissiveColor uses Color3, not Color4)
Material.setPbrMaterial(entity, {
albedoColor: Color4.create(0, 0, 0, 1),
emissiveColor: Color3.create(0, 1, 0), // Green glow
emissiveIntensity: 2.0
})
// Emissive with texture
Material.setPbrMaterial(entity, {
texture: Material.Texture.Common({ src: 'assets/Images/diffuse.png' }),
emissiveTexture: Material.Texture.Common({ src: 'assets/Images/emissive.png' }),
emissiveIntensity: 1.0,
emissiveColor: Color3.White()
})- 使用 时搭配较暗的
emissiveColor,可以让辉光效果更加明显。albedoColor
Texture Maps
纹理贴图
typescript
Material.setPbrMaterial(entity, {
texture: Material.Texture.Common({ src: 'assets/Images/diffuse.png' }),
bumpTexture: Material.Texture.Common({ src: 'assets/Images/normal.png' }),
emissiveTexture: Material.Texture.Common({ src: 'assets/Images/emissive.png' })
})typescript
Material.setPbrMaterial(entity, {
texture: Material.Texture.Common({ src: 'assets/Images/diffuse.png' }),
bumpTexture: Material.Texture.Common({ src: 'assets/Images/normal.png' }),
emissiveTexture: Material.Texture.Common({ src: 'assets/Images/emissive.png' })
})castShadows
castShadows
Both and accept (default ). Set to stop a surface from casting shadows without changing its appearance:
setPbrMaterialsetBasicMaterialcastShadows: booleantruefalsetypescript
Material.setPbrMaterial(entity, { albedoColor: Color4.Green(), castShadows: false })For disabling shadows on a specific node inside a GLTF model, use with instead (see below).
GltfNodeModifierscastShadows: falsesetPbrMaterialsetBasicMaterialcastShadows: booleantruefalsetypescript
Material.setPbrMaterial(entity, { albedoColor: Color4.Green(), castShadows: false })如需禁用 GLTF 模型内特定节点的阴影,请改用带有 的 ,详见下文。
castShadows: falseGltfNodeModifiersGltfContainer Collision Masks
GltfContainer 碰撞遮罩
Use collision masks to control which collision layers respond to the different mesh layers in a GLTF model. GLTF models have two mesh layers: visible meshes (what players see rendered), and invisible layers (collider meshes, named internally with _collider):
typescript
import { engine, Transform, GltfContainer, ColliderLayer } from '@dcl/sdk/ecs'
import { Vector3 } from '@dcl/sdk/math'
const model = engine.addEntity()
Transform.create(model, { position: Vector3.create(4, 0, 4) })
GltfContainer.create(model, {
src: 'models/myModel.glb',
visibleMeshesCollisionMask: ColliderLayer.CL_PHYSICS | ColliderLayer.CL_POINTER,
invisibleMeshesCollisionMask: ColliderLayer.CL_PHYSICS
})使用碰撞遮罩控制 GLTF 模型中不同网格层对应的碰撞层。GLTF 模型包含两个网格层:可见网格(玩家看到的渲染内容)和不可见层(碰撞体网格,内部名称带有 ):
_collidertypescript
import { engine, Transform, GltfContainer, ColliderLayer } from '@dcl/sdk/ecs'
import { Vector3 } from '@dcl/sdk/math'
const model = engine.addEntity()
Transform.create(model, { position: Vector3.create(4, 0, 4) })
GltfContainer.create(model, {
src: 'models/myModel.glb',
visibleMeshesCollisionMask: ColliderLayer.CL_PHYSICS | ColliderLayer.CL_POINTER,
invisibleMeshesCollisionMask: ColliderLayer.CL_PHYSICS
})VisibilityComponent
VisibilityComponent
Show or hide entities without removing them:
typescript
import { engine, VisibilityComponent } from '@dcl/sdk/ecs'
// Hide an entity
VisibilityComponent.create(entity, { visible: false })
// Toggle visibility
const visibility = VisibilityComponent.getMutable(entity)
visibility.visible = !visibility.visibleFor a distance-based LOD (Level of Detail) system that toggles per frame, see the LOD via VisibilityComponent section in .
VisibilityComponent{baseDir}/references/rendering-patterns.md无需移除实体即可显示或隐藏实体:
typescript
import { engine, VisibilityComponent } from '@dcl/sdk/ecs'
// Hide an entity
VisibilityComponent.create(entity, { visible: false })
// Toggle visibility
const visibility = VisibilityComponent.getMutable(entity)
visibility.visible = !visibility.visible有关每帧切换 的基于距离的 LOD(Level of Detail)系统,请参阅 中的通过 VisibilityComponent 实现 LOD部分。
VisibilityComponent{baseDir}/references/rendering-patterns.mdpropagateToChildren
propagateToChildren
Set on a to apply visibility to all children in the hierarchy at once. This avoids having to mark every child entity individually:
propagateToChildren: trueVisibilityComponenttypescript
VisibilityComponent.create(parentEntity, { visible: false, propagateToChildren: true })Rules (verified against the test scene):
1,0-visibility-comp-propagation- If a child has its own , that value wins regardless of what an ancestor propagates — even if the child's own
VisibilityComponentispropagateToChildren, the child stays at its ownfalsevalue and does not re-inherit the parent's.visible - If a child has no , it inherits from the nearest ancestor with
VisibilityComponent.propagateToChildren: true - A child that overrides an invisible parent to can itself set
visible: trueto force its own subtree visible again — propagation re-evaluates at each node that carries apropagateToChildren: true.VisibilityComponent - Propagation follows the live hierarchy: re-parenting an entity at runtime changes which ancestor's propagated visibility applies to it.
Transform.parent
在 上设置 ,即可一次性将可见性应用于层级结构中的所有子实体,从而无需逐个标记每个子实体:
VisibilityComponentpropagateToChildren: truetypescript
VisibilityComponent.create(parentEntity, { visible: false, propagateToChildren: true })规则(已通过 测试场景验证):
1,0-visibility-comp-propagation- 如果子实体拥有自己的 ,无论祖先节点传播什么值,子实体自身的值都会优先——即使子实体自己的
VisibilityComponent为propagateToChildren,它仍会保持自身的false值,不会重新继承父级的值。visible - 如果子实体没有 ,它会从最近一个设置了
VisibilityComponent的祖先节点继承可见性。propagateToChildren: true - 子实体可以将不可见的父级覆盖为 ,并自行设置
visible: true,从而再次强制其整个子树可见——传播机制会在每个包含propagateToChildren: true的节点重新计算。VisibilityComponent - 传播遵循实时的 层级结构:在运行时重新设置父实体,会改变应用可见性传播的祖先节点。
Transform.parent
Per-Node Modifiers (GltfNodeModifiers)
逐节点修改器(GltfNodeModifiers)
Override material or shadow casting on specific nodes within a GLTF model:
typescript
import { GltfNodeModifiers } from '@dcl/sdk/ecs'
GltfNodeModifiers.create(entity, {
modifiers: [
{
path: 'RootNode/Armor', // GLTF hierarchy path
castShadows: false // Disable shadow casting for this node
}
]
})To override the material or shadow casting of the entire model () — including the nested shape — see the GltfNodeModifiers — Whole-Model Material Override section in .
path: ''material: { material: { $case: 'pbr' | 'unlit', ... } }{baseDir}/references/rendering-patterns.mdModifier details (from the test scene):
74,-8-gltfnodemodifier- is the GLTF node hierarchy path,
path-separated (e.g./).Scene_root/shark_skeleton/Sphere/Sphere.001targets the whole model; a nested path targets one node and its descendants.path: '' - accepts either
material(full PBR:$case: 'pbr',albedoColor,emissiveColor, textures, …) oremissiveIntensity($case: 'unlit', …). Different nodes in the samediffuseColorarray can use different cases.modifiers - Textures work here too, including video: .
pbr: { texture: Material.Texture.Video({ videoPlayerEntity: someEntityWithVideoPlayer }) } - per node (no
castShadows: falseneeded) disables shadow casting for that node only.material - One array can contain many entries, each targeting a different
modifiersin a single call.path - Debug trick: passing a that does not exist logs the model's full GLTF node hierarchy to the scene console — use a deliberately wrong path to discover the correct node names.
path - Update with ; remove all overrides with
GltfNodeModifiers.createOrReplace(entity, { modifiers: [...] }).GltfNodeModifiers.deleteFrom(entity)
Node paths are engine-visible names baked into the GLB, not arbitrary — if a target node has no material of the requested kind, the override may be ignored.
覆盖 GLTF 模型内特定节点的材质或阴影投射:
typescript
import { GltfNodeModifiers } from '@dcl/sdk/ecs'
GltfNodeModifiers.create(entity, {
modifiers: [
{
path: 'RootNode/Armor', // GLTF hierarchy path
castShadows: false // Disable shadow casting for this node
}
]
})如需覆盖整个模型的材质或阴影投射()——包括嵌套的 结构——请参阅 中的GltfNodeModifiers——全模型材质覆盖部分。
path: ''material: { material: { $case: 'pbr' | 'unlit', ... } }{baseDir}/references/rendering-patterns.md修改器详情(来自 测试场景):
74,-8-gltfnodemodifier- 是以
path分隔的 GLTF 节点层级路径,例如/。Scene_root/shark_skeleton/Sphere/Sphere.001指向整个模型;嵌套路径则指向一个节点及其后代节点。path: '' - 可以使用
material(完整的 PBR 配置,包括$case: 'pbr'、albedoColor、emissiveColor、纹理等),也可以使用emissiveIntensity(包括$case: 'unlit'等)。同一个diffuseColor数组中的不同节点可以使用不同的 case。modifiers - 此处同样支持纹理,包括视频纹理:。
pbr: { texture: Material.Texture.Video({ videoPlayerEntity: someEntityWithVideoPlayer }) } - 逐节点的 无需设置
castShadows: false,即可仅禁用该节点的阴影投射。material - 一个 数组可以在一次调用中包含多个条目,每个条目指向不同的
modifiers。path - 调试技巧:传入不存在的 会将模型的完整 GLTF 节点层级输出到场景控制台——可以故意使用错误路径来查找正确的节点名称。
path - 使用 更新修改器;使用
GltfNodeModifiers.createOrReplace(entity, { modifiers: [...] })移除所有覆盖项。GltfNodeModifiers.deleteFrom(entity)
节点路径是烘焙在 GLB 中的、引擎可见的名称,不能随意指定——如果目标节点不存在所请求类型的材质,覆盖可能不会生效。
Avatar Texture
Avatar 纹理
Generate a texture from a player's avatar portrait:
typescript
Material.setPbrMaterial(portraitFrame, {
texture: Material.Texture.Avatar({ userId: '0x...' })
})This will fetch a thumbnail image with a closeup of the player's face, wearing the wearables that this player currently has on.
根据玩家的 Avatar 头像生成纹理:
typescript
Material.setPbrMaterial(portraitFrame, {
texture: Material.Texture.Avatar({ userId: '0x...' })
})这会获取一张缩略图,其中包含玩家面部的特写,并显示该玩家当前佩戴的可穿戴设备。
Texture Modes
纹理模式
Control how textures are filtered and wrapped:
typescript
import { TextureFilterMode, TextureWrapMode } from '@dcl/sdk/ecs'
Material.setPbrMaterial(entity, {
texture: Material.Texture.Common({
src: 'assets/Images/pixel-art.png',
filterMode: TextureFilterMode.TFM_POINT, // crisp pixels (no smoothing)
wrapMode: TextureWrapMode.TWM_REPEAT // tile the texture
})
})Filter modes: (pixelated), (smooth), (smoothest).
Wrap modes: (tile), (stretch edges), (mirror tile).
TFM_POINTTFM_BILINEARTFM_TRILINEARTWM_REPEATTWM_CLAMPTWM_MIRROR控制纹理的过滤和包装方式:
typescript
import { TextureFilterMode, TextureWrapMode } from '@dcl/sdk/ecs'
Material.setPbrMaterial(entity, {
texture: Material.Texture.Common({
src: 'assets/Images/pixel-art.png',
filterMode: TextureFilterMode.TFM_POINT, // crisp pixels (no smoothing)
wrapMode: TextureWrapMode.TWM_REPEAT // tile the texture
})
})过滤模式:(像素化)、(平滑)、(最平滑)。
包装模式:(平铺)、(拉伸边缘)、(镜像平铺)。
TFM_POINTTFM_BILINEARTFM_TRILINEARTWM_REPEATTWM_CLAMPTWM_MIRRORTexture Tweens
纹理 Tween
For animated texture patterns ( scrolling, slide-once, vs movement types, and looping via ) — all requiring a texture with — see the Texture Tweens section in .
Tween.setTextureMoveContinuousTween.setTextureMoveTMT_OFFSETTMT_TILINGTweenSequencewrapMode: TWM_REPEAT{baseDir}/references/rendering-patterns.md有关动画纹理图案——包括 滚动、 单次滑动、 与 移动类型,以及通过 实现循环——这些功能都要求纹理使用 ,请参阅 中的纹理 Tween部分。
Tween.setTextureMoveContinuousTween.setTextureMoveTMT_OFFSETTMT_TILINGTweenSequencewrapMode: TWM_REPEAT{baseDir}/references/rendering-patterns.mdFlatMaterial Accessors
FlatMaterial 访问器
The component provides shortcut methods that skip the nested union structure, making material access more ergonomic:
Material| Method | Returns | Throws if no material? |
|---|---|---|
| Read-only | Yes |
| Read-only | No |
| Read/write | Yes |
| Read/write | No |
typescript
// Read a property safely
const src = Material.getFlatOrNull(entity)?.texture?.src
// Mutate a texture in-place without knowing PBR vs Basic
Material.getFlatMutableOrNull(entity)!.texture = Material.Texture.Common({ src: 'assets/Images/new.png' })Material| 方法 | 返回值 | 没有材质时是否抛出异常? |
|---|---|---|
| 只读 | 是 |
| 只读 | 否 |
| 可读写 | 是 |
| 可读写 | 否 |
typescript
// Read a property safely
const src = Material.getFlatOrNull(entity)?.texture?.src
// Mutate a texture in-place without knowing PBR vs Basic
Material.getFlatMutableOrNull(entity)!.texture = Material.Texture.Common({ src: 'assets/Images/new.png' })Example scenes
示例场景
Engine-team test scenes exercising these APIs against the real runtime:
- https://github.com/decentraland/sdk7-test-scenes/tree/main/scenes/74,-8-gltfnodemodifier — overriding PBR/unlit materials, video textures, per-node colors and
GltfNodeModifierson specific GLTF nodes;castShadows/createOrReplace; wrong-path console-dump debug trick.deleteFrom - https://github.com/decentraland/sdk7-test-scenes/tree/main/scenes/1,0-visibility-comp-propagation —
VisibilityComponentacross a parent/child/grandchild hierarchy with runtime re-parenting, covering every override combination.propagateToChildren - https://github.com/decentraland/sdk7-test-scenes/tree/main/scenes/0,3-texture-movement — texture tweens via with
Tween.setTextureMoveandTextureMovementType.TMT_OFFSET, paired withTMT_TILINGloops; alsoTweenSequence+Billboard.TextShape - https://github.com/decentraland/sdk7-test-scenes/tree/main/scenes/52,-52-testing-gallery — PBR material sweeps (metallic/roughness/emissive/normal-map) and collision-mask combinations shown side by side.
GltfContainer
引擎团队提供的测试场景,用于在真实运行时中验证以下 API:
- https://github.com/decentraland/sdk7-test-scenes/tree/main/scenes/74,-8-gltfnodemodifier —— 使用 覆盖 PBR/unlit 材质、视频纹理、逐节点颜色以及特定 GLTF 节点的
GltfNodeModifiers;验证castShadows/createOrReplace;以及使用错误deleteFrom将节点层级转储到控制台的调试技巧。path - https://github.com/decentraland/sdk7-test-scenes/tree/main/scenes/1,0-visibility-comp-propagation —— 在父级、子级和孙级实体的层级结构中验证 的
VisibilityComponent,包括运行时重新设置父实体,并覆盖所有覆盖组合。propagateToChildren - https://github.com/decentraland/sdk7-test-scenes/tree/main/scenes/0,3-texture-movement —— 通过 和
Tween.setTextureMove、TextureMovementType.TMT_OFFSET实现纹理 Tween,并使用TMT_TILING循环;还包含TweenSequence与Billboard。TextShape - https://github.com/decentraland/sdk7-test-scenes/tree/main/scenes/52,-52-testing-gallery —— 并排展示 PBR 材质测试(金属度/粗糙度、自发光、法线贴图)以及 碰撞遮罩组合。
GltfContainer