EntityComponentSystemSamples HDRP 项目解析:Entities Graphics 特性示例场景全景指南
2026/9/16 18:02:33 网站建设 项目流程

EntityComponentSystemSamples HDRP 项目解析:Entities Graphics 特性示例场景全景指南

【免费下载链接】EntityComponentSystemSamples项目地址: https://gitcode.com/GitHub_Trending/en/EntityComponentSystemSamples

本项目(EntityComponentSystemSamples 仓库中的GraphicsSamples/HDRPSamples子工程)以 Unity DOTS 生态的com.unity.entities.graphics包(1.4.16 版)与 HDRP 渲染管线(17.2.0 版)为核心,通过 20 余个特性示例场景,系统演示了 Entities 在 HDRP 下的渲染能力:从光照烘焙、材质逐实例覆盖、运行时实体创建,到网格形变、LOD、运动模糊与透明排序。读完本文,你将掌握每个示例场景的玩法、操作步骤,以及其背后的 ECS 渲染机制与关键源码实现路径,可直接在本仓库中逐一打开场景进行验证与二次开发。

项目概览与核心渲染机制

Entities Graphics 与 SubScene 的渲染模型

HDRPSamples 是面向HDRP Entities Graphics的特性示例工程。其核心机制在于:当存在对应实体(Entity)时,Unity 用 Entities Graphics 渲染该 GameObject;当实体不存在时,则不使用 Entities Graphics 渲染。对于放在 SubScene 中的 GameObject,这一行为意味着 Unity在编辑模式(Edit Mode)、播放模式(Play Mode)以及打包后的 Player 中始终以 Entities Graphics 渲染它们——这正是 DOTS 烘焙(Baking)带来的运行路径统一。

特性示例场景全部位于 GraphicsSamples/HDRPSamples/Assets/SampleScenes 目录,按主题划分为0. Base6. Misc七个分类目录,绝大多数场景都把演示用的 GameObject 放入 SubScene 中烘焙为实体。工程运行环境可从仓库确认:Unity 编辑器版本为6000.2.10f1(见 ProjectVersion.txt),依赖com.unity.entities.graphics: 1.4.16com.unity.render-pipelines.high-definition: 17.2.0(见 Packages/manifest.json)。

场景总览表

主 README(GraphicsSamples/HDRPSamples/README.md)以表格形式给出了全部特性场景的一览,以下完整继承该场景清单:

场景说明
AmbientAndBlendProbes演示如何使用光照探针(light probes)
Lightmaps演示 Entities 的光照贴图支持
Lightprobes演示 Entities 的光照探针支持
BuiltInMaterialSHProperties演示覆盖内置材质的 SH 属性值
HDRPLitProperties演示不同 HDRP Lit 材质属性在实体上的覆盖
HDRPShaders演示 HDRP Lit、LitTessellation、Unlit、LayeredLit、LayeredLitTessellation 着色器的材质属性覆盖
MaterialOverridesSample演示无需写代码即可覆盖材质属性
ShaderGraphProperties演示 Shader Graph 着色器的材质属性覆盖
HybridEntitiesConversion演示可放入 SubScene 的图形相关伴随组件(companion components)
TriggerParticles演示如何从 ECS System 播放 VFX
EntityCreation演示如何在运行时高效创建由 Entities Graphics 渲染的实体
MaterialMeshChange演示在运行时更换实体上的材质与网格
RenderMeshUtilityExample演示RenderMeshUtility.AddComponentsAPI
MeshDeformations演示 BlendShape 与 SkinWeight 实体
SkinnedCharacter演示 SkinnedMeshRenderer 实体
DisabledEntities演示被禁用的实体
LODs演示 Entities Graphics 中的 LOD
MatrixPrevious演示移动实体与 HDRP 运动矢量(Motion Vectors)支持
Submesh演示带多个子网格(sub-mesh)的 Mesh 配合 Entities Graphics 使用
TransparencyOrdering演示透明实体的排序

运行方式:Base 场景切换器

0. Base目录下的 Base.unity 是导航入口场景,运行后可在播放模式下切换到工程内任意场景(见 0. Base/README.md)。切换逻辑由 SimpleSceneSwitch.cs 实现:界面右下角提供 Prev / Next 按钮(或按 Fire1 / Fire2 键)在 Build Settings 中的场景间轮转;切换时它会通过EntityManager.GetAllEntities()清理运行时生成的实体,但会跳过 SubScene、SceneSection 与场景流式单例等系统实体,避免误删引发报错。单独体验某个示例时,也可直接在 Project 窗口中打开对应分类目录下的场景文件并进入 Play 模式。

光照与烘焙示例(1. Lighting)

AmbientAndBlendProbes:SubScene 中的环境光与混合探针

该场景(AmbientAndBlendProbes.unity)演示 SubScene 中环境光与混合探针(blend probes)的工作方式:场景中有 2 个 SphereAmbient 与 2 个 SphereBlend 对象,其中 2 个在 SubScene 外、2 个在 SubScene 内,且两侧使用完全相同的MeshRenderer.Probes.LightProbes配置。操作要点(见 AmbientAndBlendProbes/README.md):在 Hierarchy 中选中任一球体,在 Inspector 的Mesh Renderer - Probes - Light Probes下观察其设置是 Off 还是 Blend Probes。该场景用于验证:烘焙进 Entities 后,光照探针的混合策略依然按原 MeshRenderer 配置生效。需要特别注意的是,SubScene 内的光照探针数据依赖探针锚点与包围体的放置,若自行修改场景需保持探针覆盖到实体区域。

Lightmaps:Entities 的光照贴图支持

Lightmaps.unity 场景(Lightmaps/README.md)由使用不同光照着色器(lit shaders)的球体组成,并启用烘焙全局光照(baked GI)。使用步骤:

  1. 在 Hierarchy 选中 Subscene,在 Inspector 点击Open打开;
  2. 进入Window > Rendering > Lighting
  3. 在 Scene 选项卡配置光照贴图设置,点击Generate Lighting烘焙;
  4. 保存场景与 SubScene,然后关闭 SubScene。

烘焙结果以光照贴图(lightmap)形式供 Entities Graphics 读取,实体的 UV 需与烘焙贴图对应,否则会出现漏光或错位。

Lightprobes:实体上的光照探针

Lightprobes.unity 场景(Lightprobes/README.md)用光照探针为不同光照着色器的球体打光。操作上需要注意的关键差异:SubScene 内的灯光标记为 Static,而球体不标记 Static。步骤:

  1. 打开 SubScene;
  2. 确认灯为 Static、球体非 Static;
  3. 进入Window > Rendering > Lighting
  4. 在 Scene 选项卡确保开启Baked Global Illumination,配置好光照贴图设置后点击Generate Lighting
  5. 保存并关闭 SubScene。

这种 Static 组合让探针烘焙为静态数据、实体本身保持动态变换,是光照探针 + ECS 实体的标准配合方式。

材质属性覆盖示例(2. MaterialProperties)

材质属性覆盖(material property override)是 Entities Graphics 实现逐实例(per-instance)材质差异的核心能力:不必复制材质,而是通过带[MaterialProperty]特性的 ECS 组件把数值写入渲染批量。仓库中的生成代码可直接印证这一点,例如 HDRPMyColorVector4OverrideOverrideGenerated.cs:

namespace Unity.Rendering { [MaterialProperty("_HDRPMyColor")] struct HDRPMyColorVector4Override : IComponentData { public float4 Value; } }

即:一个带[MaterialProperty("着色器属性名")]IComponentData结构体,其字段值会被注入到对应着色器属性中,实现同材质不同实例显示不同颜色/金属度/光滑度。

HDRPLitProperties:覆盖 HDRP Lit 核心属性

HDRPLitProperties.unity(HDRPLitProperties/README.md)中的球体使用 HDRP Lit 着色器并位于 SubScene 内,挂载在球体 MeshRenderer 上的材质覆盖 Authoring 组件会覆盖其颜色(Color)、光滑度(Smoothness)与金属度(Metallic)。若需覆盖其他 HDRP 材质属性,可以在 Inspector 中继续添加其他 HDRP Material Property Authoring 组件(如 Base Color、Emissive Color、Normal、Ambient Occlusion 等),每个组件烘焙后都会生成对应的[MaterialProperty]ECS 组件。

HDRPShaders:多着色器全家桶覆盖

HDRPShaders.unity(HDRPShaders/README.md)覆盖了 HDRP 的Lit、LitTessellation、Unlit、LayeredLit、LayeredLitTessellation以及Shader Graph PBR输出,演示对球体颜色与自发光(emissive)值的覆盖。操作要点:

  1. 选中LitRedEmissiveUnlitRedEmissive球体,观察其上的 HDRP Material Property Base Color Authoring 与 Emissive Color Authoring 组件;
  2. 选中LayeredLitLayeredLitTessellationMagenta,观察其 "Layered Lit Base Color 0 Authoring" 组件——这是 LayeredLitBaseColor0Authoring.cs 脚本,利用 HDRP LayeredLit 的_BaseColor0关键字逐层覆盖颜色;
  3. 选中PBRBlue球体,其上的 Material Color 组件展示了如何为自定义 Shader Graph 属性编写覆盖组件;
  4. 点击Edit编辑 Shader Graph,注意 Color 属性的 Node Settings 中开启了Hybrid Per Instanced选项——这是属性可被逐实例覆盖的前提。

ShaderGraphProperties:Shader Graph 属性覆盖

ShaderGraphProperties.unity(ShadergraphProperties/README.md)用使用 Shader Graph PBR 输出的立方体演示覆盖。选中CubeRed观察 Material Color 组件;编辑 Shader Graph 时注意其 Color 属性启用了Override Property DeclarationShader Declaration设为Hybrid Per Instance。自定义 Shader Graph 属性只有声明为 Hybrid Per Instance,实体上的覆盖组件才能生效。

MaterialOverridesSample:零代码配置覆盖

MaterialOverridesSample.unity(MaterialOverridesSample/README.md)演示完全不用写代码的覆盖方式:球体使用 HDRP Lit、HDRP Unlit 与 Shader Graph 材质;挂在 MeshRenderer 上的MaterialOverride 组件引用一个MaterialOverride 资产,该资产即配置覆盖哪些属性及其值。操作:选中名称含PerInstance的球体,观察 MaterialOverride 组件并点击其引用的资产查看已配置的属性。生成产物即上文展示的HDRPMyColorVector4OverrideOverrideGenerated.cs这类代码,并配套 HDRPMyMetallicFloatOverrideOverrideGenerated.cs(浮点型 metallic)与 HDRPMySmoothnessFloatOverrideOverrideGenerated.cs 等生成文件,可见同一机制同时支撑向量与标量属性。

BuiltInMaterialSHProperties:覆盖内置 SH 属性

BuiltInMaterialSHProperties.unity(BuiltInMaterialSHProperties/README.md)演示覆盖内置材质球谐(SH)属性(即Unity_SH系列)的值。球体由挂在 MeshRenderer 上的 Authoring 组件提供的 LightProbe SH 属性值照明。操作步骤:

  1. 在 Hierarchy 中选中某个 SubScene(工程内有SubsceneSHAr / SubsceneSHAg / SubsceneSHAb / SubsceneSHBr / SubsceneSHBg / SubsceneSHBb / SubsceneSHC / SubsceneEmpty等多个子场景,见 BuiltInMaterialSHProperties 目录);
  2. 点击Open打开;
  3. 选中球体对象,确认MeshRenderer > Probes > Light ProbesCustom Provided
  4. 修改Unity_SH内置材质属性 Authoring 组件上的值,观察球体光照变化;
  5. 保存并关闭 SubScene。

这使开发者可以绕过探针系统,直接用自定义 SH 系数控制实体光照。

混合组件示例(3. Hybrid Components)

HybridEntitiesConversion:SubScene 中的图形伴随组件

HybridEntitiesConversion.unity(HybridEntitiesConversion/README.md)演示可放入 SubScene 的图形相关伴随组件(companion components)。SubScene 中包含灯光(Lights)、体积(Volumes)与其他对象,Entities Graphics 对这些图形组件全部提供支持。需要注意:Particle System 在 SubScene 中不预览,但在运行时能正确模拟。操作上只需打开 SubScene 观察其中的对象与组件布局。

TriggerParticles:从 ECS System 播放 VFX

TriggerParticles.unity(TriggerParticles/README.md)演示如何从 ECS System 播放 VFX Graph:SubScene 内有一个球体与一个 VFX Graph,JumpingSpherePSSystem脚本驱动球体跳跃,并在球体触地瞬间播放 VFX。VFX Graph 烘焙为伴随组件后可从 ECS 脚本访问。核心实现见 JumpingSpherePSSystem.cs:

// 让球体上下跳动:根据时间修改 LocalTransform foreach (var translation in SystemAPI.Query<RefRW<LocalTransform>>().WithAll<JumpingSphereTag>()) { translation.ValueRW.Position = new float3(0, y, 0); } // 触地时播放粒子系统(y < 0.05f) foreach (var particleSystem in SystemAPI.Query<SystemAPI.ManagedAPI.UnityEngineComponent<VisualEffect>>().WithAll<JumpingSpherePSTag>()) { if (y < 0.05f) particleSystem.Value.Play(); }

要点:通过SystemAPI.ManagedAPI.UnityEngineComponent<VisualEffect>查询伴随组件引用,配合JumpingSphereTag/JumpingSpherePSTag两个标签(其 Authoring 见 JumpingSpherePSTagAuthoring.cs 与 JumpingSphereTagAuthoring.cs)实现解耦触发。

API 示例(4. API Examples)

EntityCreation:Burst 作业中高效创建渲染实体

EntityCreation.unity(EntityCreation/README.md)演示如何用RenderMeshDescriptionRenderMeshUtility.AddComponentsAPI 配合Instantiate高效创建由 Entities Graphics 渲染的实体,并通过 ECS 组件设置颜色。其脚本 TestEntityCreationAPI.cs 是完整可复用的运行时实体创建模板,核心流程如下:

var filterSettings = RenderFilterSettings.Default; filterSettings.ShadowCastingMode = ShadowCastingMode.Off; filterSettings.ReceiveShadows = false; var renderMeshArray = new RenderMeshArray(new[] { Material }, Meshes.ToArray()); var renderMeshDescription = new RenderMeshDescription { FilterSettings = filterSettings, LightProbeUsage = LightProbeUsage.Off, }; // 创建一个"原型实体",一次性添加全部渲染组件 var prototype = entityManager.CreateEntity(); RenderMeshUtility.AddComponents( prototype, entityManager, renderMeshDescription, renderMeshArray, MaterialMeshInfo.FromRenderMeshArrayIndices(0, 0)); entityManager.AddComponentData(prototype, new MaterialColor()); // 在 Burst 并行作业中批量克隆原型实体 var spawnJob = new SpawnJob { Prototype = prototype, Ecb = ecbJob.AsParallelWriter(), // ...配置数量、网格数组、包围盒等 }; var spawnHandle = spawnJob.Schedule(EntityCount, 128);

SpawnJobIJobParallelFor)在Execute内用Ecb.Instantiate克隆原型,再用SetComponent写入每实例不同的LocalToWorldMaterialColorMaterialMeshInfoRenderBounds——其中RenderBounds必须按真实网格设置以保证剔除正确(见MeshBounds数组的构建与Meshes[i].bounds.ToAABB())。场景中默认参数为EntityCount = 10000ObjectScale = 0.1fRadius = 10Twists = 16,选中 Hierarchy 中的Spawner对象即可在 Inspector 中调整这些参数,然后点击 Play 观察生成的彩色球体螺旋。这正是"克隆原型 + Burst 作业 + ECB"的官方推荐高效路径。

RenderMeshUtilityExample:AddComponents 最小示例

RenderMeshUtilityExample.unity(RenderMeshUtilityExample/README.md)是RenderMeshUtility.AddComponents的精简演示,由 AddComponentsExample.cs 实现。与上一示例相比,它展示了:

  • 用带命名参数的便捷构造器创建描述:new RenderMeshDescription(shadowCastingMode: ShadowCastingMode.Off, receiveShadows: false)
  • 勾选m_differentMaterial时,为每个实例运行时克隆材质并按 HSV 生成不同颜色(同时设置_Color_BaseColor,兼容 Built-in 与 HD 管线),构造RenderMeshArray后调用ResetHash128()刷新哈希;
  • m_w × m_h(默认 30×30)网格布局克隆实体,用MaterialMeshInfo.FromRenderMeshArrayIndices(matIndex, 0)为每实例指定材质索引。

选中Spawner配置Meshm_materialm_differentMaterialm_wm_h后点 Play 即可看到成片立方体,是理解渲染数组(RenderMeshArray)与实体克隆的最小可运行范例。

MaterialMeshChange:运行时切换材质与网格

MaterialMeshChange.unity(MaterialMeshChange/README.md)含两个实体:一个按帧切换网格、一个切换材质。实现上 MeshChangerAuthoring.cs 与 MaterialChangerAuthoring.cs 是"Authoring + Baker + System"三件套的典范:

  • Authoring 组件用[RegisterBinding(typeof(MeshChanger), "frequency")]等特性把 Inspector 字段绑定到运行时组件,Baker 通过AddComponentObject加入实体(TransformUsageFlags.Dynamic);
  • 系统在OnStartRunning中通过World.GetOrCreateSystemManaged<EntitiesGraphicsSystem>()拿到渲染系统,调用RegisterMaterial(material)/RegisterMesh(mesh)得到BatchMaterialID/BatchMeshID
  • OnUpdate中每frequency帧翻转active标志,并直接改写MaterialMeshInfoMaterialIDMeshID实现切换,无需重建实体或材质实例。

操作步骤:打开 SubScene → 选中MeshChangeMaterialChangeGameObject 观察 Authoring 组件 → 关闭 SubScene 进入 Play 模式,两个对象烘焙为实体后由 ECS System 驱动周期性的网格/材质互换。

形变示例(5. Deformation)

前置条件:ENABLE_COMPUTE_DEFORMATIONS 脚本宏

MeshDeformations 与 SkinnedCharacter 两个形变场景都要求在Edit > ProjectSettings > Player > Other SettingsScripting Define Symbols中添加ENABLE_COMPUTE_DEFORMATIONS定义符号,否则计算着色器形变路径不会编译。这是运行形变示例前必须完成的配置步骤。

MeshDeformations:BlendShape 与蒙皮权重实体

MeshDeformations.unity(MeshDeformations/README.md)用三色网格区分三种形变组合:红色网格用 BlendShape(混合形状)形变,蓝色网格仅用蒙皮(skinning),紫色网格两种方法叠加于同一网格。所有数值与变换都由一套简单动画系统写入 ECS 变换组件,再由 Mesh Deformation 系统据此计算蒙皮矩阵。操作:打开某个 SubScene(BlendShapeSubScene/SkinningSubScene/CombinedSubScene),选中cube_test_mesh对象,确认其材质使用的 Shader Graph 包含 Compute Deformation 节点。

SkinnedCharacter:计算着色器 vs 顶点着色器蒙皮

SkinnedCharacter.unity(SkinnedCharacter/README.md)展示四个使用网格形变的动画角色,同时演示两条蒙皮路径:

  • 顶点着色器形变(蓝色角色):Shader Graph 必须使用Linear Blend Skinning 节点
  • 计算着色器形变(粉色角色):Shader Graph 必须使用Compute Deformation 节点

两个 SubScene(ComputeSubScene/VertexSubScene)分别对应两条路径。选中Geom_Body_LOD0可检查其材质对应的节点设置。底层蒙皮矩阵计算逻辑可参考 CalculateSkinMatrixSystem.cs:它先并行收集BoneTag骨骼的LocalToWorldRootTag根的逆矩阵(NativeParallelHashMap),然后在CalculateSkinMatricesJob中逐个骨骼执行skinMatrix = rootWorldToLocal * boneLocalToWorld * bindPose,把结果写入DynamicBuffer<SkinMatrix>,并在PresentationSystemGroup中排在DeformationsInPresentation之前执行,供形变系统拾取。配套的简单动画系统(写入LocalTransform)与 Authoring 组件见 CommonAssets/Scripts/SimpleAnimationSystem 目录。

杂项示例(6. Misc)

DisabledEntities:禁用实体与 DisableRendering

DisabledEntities.unity(DisabledEntities/README.md)场景含 3 个立方体,其中 1 个被禁用,因此屏幕只渲染 2 个。要点:禁用实体与在编辑器中禁用 GameObject 无异,禁用会关闭实体的一切;若只想停止渲染而保留其他逻辑,应在 ECS 脚本中给实体添加DisableRendering标签组件。操作:打开 SubScene 选中被禁用的 Cube,在 Inspector 确认其处于 disabled 状态。

LODs:实体的多级细节

LODs.unity(LODs/README.md)用一片立方体网格演示 Entities Graphics 的 LOD,每个 LOD 级用不同颜色区分。操作:打开 SubScene 选中Root对象,其下包含 100 个 LodGroup 子节点,每个子节点都挂有 LOD Group 组件;烘焙后这些 LOD 组会映射为实体的 LOD 组件,由 Entities Graphics 按距离自动切换(配套的 CameraMovement.cs 方便玩家飞行观察切换效果)。

MatrixPrevious:运动矢量与运动模糊

MatrixPrevious.unity(MatrixPrevious/README.md)演示多个实体的移动如何配合 HDRP 运动矢量(Motion Vectors)正确响应运动模糊。场景中球体父级为BallsGameObject,每个球体带 Sphere ID Authoring 组件,由 MoveBallsSystem.cs 逐帧平移:系统先为缺失BallOriginalTranslation的球体记录初始位置,随后调度MoveBallIJobChunk,Burst 编译)基于ElapsedTime在圆周上平移每个球体(见 SphereIdAuthoring.cs 提供的标识组件)。进入 Play 模式后,球体烘焙为实体并以运动模糊拖尾运动——这验证了 Entities Graphics 会自动维护上一帧矩阵以生成正确的运动矢量。

Submesh:一个实体对应一个材质

Submesh.unity(Submesh/README.md)演示带 3 个子网格的单个 GameObject:其 Mesh 含 3 个 sub-mesh,并配 3 个独立材质。由于 Entities 每个实体只支持一个材质,这类 GameObject 会被烘焙成多个实体(每个材质一个)。操作步骤:

  1. 确认 SubScene 处于关闭状态;
  2. 打开Window > Entities > Hierarchy
  3. 导航到 SubScene,展开带层级结构的实体;
  4. 观察由同一 Authoring GameObject 烘焙出的 3 个实体。

TransparencyOrdering:透明实体深度排序

TransparencyOrdering.unity(TransparencyOrdering/README.md)场景含大量半透明立方体,正确的渲染需要从后到前(back-to-front)排序。Entities Graphics 通过DepthSorted_Tag标签组件实现:实体使用透明材质烘焙时,该标签会被自动添加。操作步骤:

  1. 确认 SubScene 关闭;
  2. 打开Window > Entities > Hierarchy
  3. 选中层级底部的某个实体;
  4. 观察该实体带有DepthSorted_Tag标签组件。

该标签提示渲染器按深度排序该批实体,从而获得正确的透明混合结果。

总结:从示例场景到生产实践的映射

结合全部 20 个特性场景(HDRPSamples 主 README)与仓库源码,可以归纳出 Entities Graphics + HDRP 生产环境下的几条关键实践路径:

  • 光照一体化:SubScene 中的灯光、探针、光照贴图均可烘焙为 ECS 数据(1. Lighting),Static/非 Static 的组合决定烘焙方式;
  • 逐实例渲染差异化[MaterialProperty]组件、MaterialOverride 资产、Hybrid Per Instance 声明三位一体(2. MaterialProperties),是替代"复制材质"的高效方案;
  • 运行时动态内容RenderMeshUtility.AddComponents+ 原型克隆 + Burst 作业是官方推荐的高效实体创建路径(4. API Examples),RegisterMaterial/RegisterMesh支持运行时无重建地切换材质网格;
  • 高级渲染特性:形变(BlendShape/蒙皮)、LOD、运动矢量、透明排序、子网格拆分等均有专门场景验证(5. Deformation6. Misc)。

每个场景目录下都配有独立 README 与可直接运行的 Authoring/System 源码,是学习 Entities Graphics 1.4.x + HDRP 17.x 组合特性的最佳教材:先在 Base.unity 中播放切换全部场景,再针对感兴趣的类别打开 SubScene 查看组件配置,最后对照本文给出的源码路径深入阅读实现,即可快速掌握这套渲染栈的核心用法。

【免费下载链接】EntityComponentSystemSamples项目地址: https://gitcode.com/GitHub_Trending/en/EntityComponentSystemSamples

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询