# MeshRendererComponent **命名空间**: `XCEngine::Components` **类型**: `class` **头文件**: `XCEngine/Components/MeshRendererComponent.h` **描述**: 保存材质槽、阴影开关和渲染层等绘制配置,声明“这个对象上的 Mesh 应该如何被渲染”。 ## 角色概述 `MeshRendererComponent` 负责的是“绘制配置”,不是“几何来源”。 - [MeshFilterComponent](../MeshFilterComponent/MeshFilterComponent.md) 负责网格 - `MeshRendererComponent` 负责材质槽和渲染附加参数 两者配合后,`RenderSceneExtractor` 才能把场景对象整理成可提交到渲染管线的可见项。 ## 当前实现行为 ### 1. 同时维护材质 handle 和路径数组 内部维护两套并行数组: - `m_materials` - `m_materialPaths` 这和 `MeshFilterComponent` 的思路一致,目的是同时满足: - 运行时快速拿资源 - 序列化时稳定写路径 ### 2. 材质槽会按需自动扩容 `SetMaterialPath()` 和 `SetMaterial()` 在写入指定槽位前,都会先调用内部 `EnsureMaterialSlot(index)`。 因此: - 可以直接写入一个较大的槽位索引 - 中间缺失槽位会被自动补成空材质 `tests/Components/test_mesh_render_components.cpp` 已覆盖这一行为。 ### 3. 越界读取是“安全空值”语义 按当前实现: - `GetMaterial(index)` 越界时返回 `nullptr` - `GetMaterialHandle(index)` 越界时返回静态空 handle - `GetMaterialPath(index)` 越界时返回静态空字符串 这让上层调用少了很多显式边界判断,但也意味着调用者不能把空返回值误读成“这个槽位一定存在但内容为空”。 ### 4. 反序列化按路径重建槽位 `Deserialize()` 会: - 先清空旧材质与标记 - 解析 `materials=` 字段 - 用 `|` 分隔多材质路径 - 对每个槽位调用 `SetMaterialPath()` 尝试重新加载 即使资源此刻没有加载成功,路径数组也会被保留下来。这一点同样有测试覆盖。 ## 阴影和渲染层的现实状态 当前组件公开了: - `GetCastShadows()` / `SetCastShadows()` - `GetReceiveShadows()` / `SetReceiveShadows()` - `GetRenderLayer()` / `SetRenderLayer()` 但按当前 [RenderSceneExtractor](../../Rendering/RenderSceneExtractor/RenderSceneExtractor.md) 实现,场景提取时还没有看到这些字段被真正消费。也就是说: - 这些字段当前可以保存 - 也可以被序列化 - 但它们还没有完整接入当前已取证的渲染提取路径 文档必须把这一点说清楚,避免用户把“字段存在”误解成“功能已完整生效”。 ## 序列化语义 当前写出: - `materials`,多个路径用 `|` 分隔 - `castShadows` - `receiveShadows` - `renderLayer` 测试还覆盖了“末尾空材质槽”会被保留的情况,这对编辑器材质槽 UI 很重要。 ## 线程语义 - 当前实现没有内部加锁。 - 资源路径解析和材质切换默认按主线程配置路径使用。 ## 当前实现限制 - 当前文档目录原先缺少 `GetMaterialPath()` 和 `SetMaterialPath()` 独立方法页,本轮已补齐。 - `castShadows`、`receiveShadows` 和 `renderLayer` 还没有完整接入当前已取证的场景提取逻辑。 - 它只负责声明绘制配置,不等于完整 renderer feature 集合。 ## 相关方法 - [GetMaterialCount](GetMaterialCount.md) - [GetMaterial](GetMaterial.md) - [GetMaterialHandle](GetMaterialHandle.md) - [GetMaterialPath](GetMaterialPath.md) - [GetMaterialPaths](GetMaterialPaths.md) - [SetMaterial](SetMaterial.md) - [SetMaterialPath](SetMaterialPath.md) - [SetMaterials](SetMaterials.md) - [ClearMaterials](ClearMaterials.md) - [GetCastShadows](GetCastShadows.md) - [SetCastShadows](SetCastShadows.md) - [GetReceiveShadows](GetReceiveShadows.md) - [SetReceiveShadows](SetReceiveShadows.md) - [GetRenderLayer](GetRenderLayer.md) - [SetRenderLayer](SetRenderLayer.md) - [Serialize](Serialize.md) - [Deserialize](Deserialize.md) ## 相关文档 - [当前模块](../Components.md) - [MeshFilterComponent](../MeshFilterComponent/MeshFilterComponent.md) - [RenderSceneExtractor](../../Rendering/RenderSceneExtractor/RenderSceneExtractor.md) - [BuiltinForwardPipeline](../../Rendering/Pipelines/BuiltinForwardPipeline/BuiltinForwardPipeline.md) - [API 总索引](../../../main.md)