Skip to content

材质系统(Material System) ​

管理 GameGraph 3D 与 Urho2D 渲染材质的创建、属性设置、着色器配置。仅客户端可用(#if CLIENT)。

定义位置:GameGraph.MaterialSystem

材质类型 ​

类型用途关键属性
MaterialPBRPBR 金属度/粗糙度材质ColorFactor, MetallicFactor, RoughnessFactor
MaterialVertexColor贴图乘顶点颜色,提供固定的受光、无光、裁剪与混合模式Mode, AlbedoTexture, ColorFactor
MaterialFlatLambert无贴图 Lambert 纯色材质Color, Transparent
MaterialWater水面材质TintColor
MaterialUrho2DUrho2D 无光照精灵材质Texture, Color, BlendMode, DepthTestMode, DepthWrite
MaterialCustom通用参数访问SetFloat/SetColor/SetVector

选型建议 ​

需求推荐做法说明
常规模型、带贴图或金属度/粗糙度MaterialPBRSDK 当前最完整的通用材质入口
程序网格、体素 AO、逐顶点烘焙亮度MaterialVertexColorAlbedo、ColorFactor 和顶点 RGBA 相乘;透明语义由固定模式决定
树叶、栅栏等硬边透明表面MaterialVertexColor(..., LitAlphaCutout)按 Albedo Alpha 裁剪,并保留不透明深度与裁剪阴影
玻璃等半透明表面MaterialVertexColor(..., UnlitAlphaBlend)Alpha 混合且不写深度;按透明对象规则分组和排序
程序生成几何体、调试几何体、无贴图纯色对象MaterialFlatLambert受场景光照、阴影和 SSAO 影响,不是严格 Unlit
无贴图半透明纯色对象new MaterialFlatLambert(transparent: true)Color.A 参与 alpha 混合
单层水面MaterialWater对应 singlelayerwater pass
运行时 Mesh 粒子Editor/Techniques/Lambert/ParticleLambert.xml用 Mesh.Material(...).Technique(...) 覆盖 mesh emitter technique
特殊美术材质或项目自定义 techniqueMaterialCustom直接用属性名或 Technique.PropertyToID(...) 读写参数

MaterialVertexColor 是有贴图且要求网格提供 Color 顶点流的专用入口。无贴图纯色仍使用 MaterialFlatLambert;它不会因为新增顶点颜色材质而变成 Unlit。

对应变体已发布到 Editor、Windows、Android 和 iOS shadercache overlay。真实 Editor 已覆盖四档场景画质、HDR 开关、投影与两种程序网格路径。

MaterialVertexColor ​

MaterialVertexColor 将 AlbedoTexture × ColorFactor × 顶点颜色 组合为最终表面颜色。它适合方块网格、顶点 AO、天光/方块光烘焙和需要同一贴图在不同顶点显示不同亮度的程序生成几何体。该类型仅客户端可用,不改变 MaterialPBR 的顶点色或透明行为。

csharp
#if CLIENT
using System.Drawing;
using GameCore.Drawing;
using GameGraph.MaterialSystem;
using GameGraph.ResourceSystem;

var texture = Texture2D.Load("texture/voxel/stone.tga")
    ?? throw new InvalidOperationException("Voxel texture was not found.");

var material = new MaterialVertexColor(
    texture,
    VertexColorMaterialMode.UnlitOpaque)
{
    ColorFactor = new HdrColor(255, 255, 255, 255)
};

var mesh = new MeshBuilder()
    .SetPositions(positions)
    .SetNormals(normals)
    .SetTexCoords(uvs)
    .SetColors(vertexColors)
    .SetIndices(indices)
    .Build();
#endif

VertexColorMaterialMode 使用显式稳定编号,便于配置、触发器和序列化保持一致:

模式数值光照与 Alpha 语义
LitOpaque0受场景光照影响;按不透明对象绘制,不启用 Alpha 混合
UnlitOpaque1不受场景光照影响;适合把 AO 或体素亮度烘焙到顶点 RGB
LitAlphaCutout2受场景光照影响;按 Albedo Alpha 做硬裁剪,并让深度/阴影 pass 使用同一裁剪贴图
UnlitAlphaBlend3不受场景光照影响;最终 Alpha 为贴图、顶点色与 ColorFactor Alpha 的乘积,使用 Alpha 混合且不写深度

这些模式的 Alpha 语义是固定契约:LitAlphaCutout 的去留由 Albedo Alpha 决定,顶点 Alpha 不改变裁剪阈值;UnlitAlphaBlend 才使用连续顶点 Alpha。需要硬边洞口时不要改用 Alpha 混合,需要连续半透明时也不要用裁剪模式。切换 Mode 会整体切换到对应的固定 Technique,不会运行时改写共享 pass defines。

MeshBuilder.SetColors(...) 与 CustomGeometryComponent.DefineColor(...) 都可提交顶点颜色。受光模式应提供有效 Normal;UV 与 Color 是四种模式的必要数据。Tangent 仅在所选 shader 确实需要切线空间数据时提供,不应把它作为顶点色材质的通用前置条件。

四个固定 Technique 入口如下;KnownTechnique 与 KnownTechniquePath 使用相同属性名:

公开名称Technique XML
TexturedVertexColorLitOpaqueEngineRes/Techniques/DiffVCol.xml
TexturedVertexColorUnlitOpaqueEngineRes/Techniques/DiffVColUnlit.xml
TexturedVertexColorLitAlphaCutoutEngineRes/Techniques/DiffVColAlphaMask.xml
TexturedVertexColorUnlitAlphaBlendEngineRes/Techniques/DiffVColUnlitAlphaBlend.xml

一般代码直接构造 MaterialVertexColor 即可。只有诊断或需要读取路径时才使用上述 KnownTechnique / KnownTechniquePath。通过 Material.Load(...) 或组件读取已加载材质时,这四条路径会恢复为 MaterialVertexColor,Mode 与路径保持对应。

纹理来源边界 ​

  • 项目发布的普通纹理继续使用 Texture2D.Load(...)。资源系统会经由 TextureX 容器链路选择当前平台的压缩格式、mip 和采样数据;不要把发布资源改成启动时从原图重新上传。
  • 客户端运行时生成或修改的 Image 使用 Texture2D.CreateFromImage(...),并由创建者管理纹理生命周期。
  • RenderToTexture 使用 Texture2D.CreateRenderTarget(...)。它与发布纹理和运行时静态上传是三条不同路径。

VoxelMaterialSample 使用运行时 16×16 图片,只是为了生成确定性的视觉夹具。正式方块贴图仍应优先走 Texture2D.Load(...) 与 TextureX 发布链。样例同时对照经典顶点色四模式、PBR 顶点色不透明/裁剪,以及标准 PBR 混合/裁剪;每种路径都覆盖 MeshBuilder + StaticMeshComponent 与 CustomGeometryComponent。project.voxel_material_snapshot 返回逐格材质与纹理状态,project.voxel_render_profile 可查询或切换场景画质、HDR 和动态灯光。

MaterialPBR ​

csharp
var mat = new MaterialPBR(useAlbedoTexture: true, useAlphaChannel: false);
mat.ColorFactor = HdrColor.White;
mat.MetallicFactor = 0.5f;
mat.RoughnessFactor = 0.3f;
mat.EmissiveColor = new HdrColor(1f, 0.5f, 0f);
mat.EmissiveIntensity = 2.0f;
mat.UseDefaultTextures();  // 设置默认的 Albedo 和 MetalnessRoughness 贴图

已有自定义 Albedo 纹理时可直接传入构造函数,避免先创建无贴图材质再切换状态:

csharp
var texture = Texture2D.CreateFromImage(image, sRgb: true, mipLevels: 1)
    ?? throw new InvalidOperationException("Texture upload failed.");
var mat = new MaterialPBR(texture, useAlphaChannel: false);

需要明确区分连续透明与硬裁剪时,使用 PBRAlphaMode:

csharp
var glass = MaterialPBR.Create(glassTexture, PBRAlphaMode.AlphaBlend);
var leaves = MaterialPBR.Create(leavesTexture, PBRAlphaMode.AlphaCutout);

AlphaBlend 使用 Albedo Alpha 混合且不写深度;AlphaCutout 以固定阈值 0.5 裁剪颜色、深度和阴影。旧构造器的 useAlphaChannel: true 继续表示 AlphaBlend。UseAlphaChannel 也继续保留:从不透明模式设为 true 会进入混合模式,设为 false 会回到不透明;已经明确选择裁剪模式时,再设为 true 不会把它降级为混合。

代码创建的混合材质使用 PhysicalBasedRenderingAlphaBlend / PhysicalBasedRenderingAlphaBlendSolid。旧的 PhysicalBasedRenderingAlpha / PhysicalBasedRenderingAlphaSolid 路径继续保留给既有资源文件和路径比较;新代码不要用旧路径代替明确的 PBRAlphaMode。

程序化图片的生成、上传参数和资源释放见运行时程序化纹理指南。

属性 ​

属性类型说明
UseAlbedoTexturebool是否使用 Albedo 贴图(影响 Shader 选择)
UseAlphaChannelbool兼容入口;true 默认选择 Alpha 混合,false 选择不透明
AlphaModePBRAlphaModeOpaque、AlphaBlend 或 AlphaCutout;裁剪要求 Albedo 纹理
ColorFactorHdrColor颜色系数
EmissiveColorHdrColor自发光颜色
MetallicFactorfloat金属度(0-1)
RoughnessFactorfloat粗糙度(0-1)
EmissiveIntensityfloat自发光强度

贴图颜色空间与通道契约 ​

贴图的颜色空间由内容和用途决定,不能根据 .png、.tga 等后缀或是否使用 PBR 推断。常见 Albedo / Diffuse 是 sRGB 编码的颜色;法线、粗糙度、金属度和 AO 是线性数据。源素材明确使用线性颜色时,保留其约定,不再做 sRGB 解码。

输入颜色空间使用规则
常见 sRGB 编码的 Albedo / DiffusesRGB=true保留原始颜色字节,加载时解码;不要再手工做一次 gamma 转换
普通 RGB 法线sRGB=false先核对目标材质的法线编码、通道与 Y 方向约定
粗糙度、金属度、AO、混合数据图sRGB=false通道值是数据,sRGB 解码会改变这些值

项目贴图在首次加载前添加同名 XML。例如 res/props/crate.tga 的参数文件为 res/props/crate.xml:

xml
<texture><srgb enable="true" /></texture>

混合贴图 res/props/crate_mix.png 对应 res/props/crate_mix.xml:

xml
<texture><srgb enable="false" /></texture>

Texture2D.Load("props/crate.tga") 不会因绑定到颜色槽就自动补齐该声明。运行时创建纹理时,在 Texture2D.CreateFromImage(...) 的 sRgb 参数中明确指定颜色空间,见运行时程序化纹理指南。

混合贴图没有跨材质通用的通道布局。 当前两条 PBR 路线应分别处理:

材质 / Technique法线与数据图布局参数作用
MaterialPBR 的 Editor/Techniques/PBR_PackedNormal/DefaultMetallicRoughness.xmlnormal 槽(TextureUnit.Normal):R/G=法线 X/Y,B=粗糙度,A=金属度RoughnessFactor、MetallicFactor 是乘数;金属度还受 MetalMul0or1 控制
MaterialPBRVertexColor独立 NormalTexture;RoughnessMetalnessTexture 的 R=粗糙度、G=金属度RoughnessOffset、MetallicOffset 是加法偏移

普通 RGB 法线中的 B 是法线 Z,不能原样用作第一条路线的粗糙度。适配时保留原图,生成新的 RGBA 混合图:在源法线编码兼容的前提下保留 R/G,将实际粗糙度填入 B、金属度填入 A。法线 Y 方向不根据 Maker 来源或文件名自动翻转,应依据源约定并在固定光照下检查凹凸方向。glTF ORM 等打包图也应按其源通道定义重新组合。

对于上述 packed-normal Technique,混合图已保存最终粗糙度和金属度时,将两个 Factor 设为 1;例如 B=0.85 再乘 RoughnessFactor=0.85 会得到约 0.72,并非 0.85。材质文件需要金属效果时显式配置 <parameter name="MetalMul0or1" value="1" />。不要仅凭 MetallicFactor 非零就认定金属效果已经启用,仍需检查材质参数与实际反光。没有混合图时先保留网格法线,用材质系数控制表面;不要给其它 Technique 套用这张表。

resource_import_model_package 会为支持的源材质生成上述颜色空间声明;有普通法线时生成 RGBA 混合图,并将已写入通道的 Factor 设为 1。直接复制资源或用 GameGraph 引用裸贴图时,需要自行完成这些适配。详见项目模型资源包导入。

发白与法线异常的验证 ​

导入模型发白时,优先检查颜色贴图的 sRGB 设置。 若源 Albedo / Diffuse 是常见 sRGB 编码的颜色图,而实际纹理 SRGB=false,先在同名 XML 中设置 <srgb enable="true" />,重载贴图及材质,在相同镜头和光照下比较。确认颜色空间后,再排查灯光、环境反射、曝光与材质系数。源颜色明确为线性时保留 false;法线和混合数据图也保持 false。

先用 Runtime MCP material.probe 检查实际 Technique、贴图槽、纹理 s_rgb 和材质系数;也可读取纹理的 SRGB 属性。颜色纹理被按线性值使用时可能发白,数据图误用 sRGB 则可能改变凹凸与表面反光。亮度还受灯光、环境反射和曝光影响,单凭截图不能确定原因。

修改 XML 后重载贴图及引用它的材质;仍有缓存疑点时重新进入项目或调试。不要把对已加载纹理修改 SRGB 属性当作 GPU 资源已按新格式重建的证明。同一资源路径的纹理可能共享,需要不同颜色空间时使用不同资源路径和各自的 XML。

固定模型、镜头、光照和颜色系数,每次只改一个设置,拍摄修改前后与恢复后的画面,并检查未修改对象。贴图加载成功或已绑定到槽位,也不能代替实际法线、反光和颜色的验收。

逐张贴图验收 ​

导入验收覆盖场景实际使用的每个独立颜色贴图路径,包括角色、武器、地板和道具。某个模型的配置正确,不能代替其他资源的检查;手动复制或通过 Texture2D.Load 加载的贴图也需要检查。

  1. 从实际材质的颜色槽收集资源路径,逐张核对源颜色空间和同名 XML。常见 sRGB 编码颜色图设为 true,明确线性颜色图保留源约定;法线及混合数据图保持 false。
  2. 重载贴图和材质,或重新进入调试。在 scenegraph.materials 返回的贴图列表中按资源路径定位材质,再用 material.probe 的 nodeId 精确查询,确认每张贴图的实际 s_rgb,不能只检查磁盘上的 XML。
  3. 固定镜头、光照和材质系数比较前后画面,并检查未修改对象。资源加载成功不代表颜色空间已验收;补齐声明后也不要同时调亮灯光来抵消颜色变化。

MaterialPBRVertexColor ​

MaterialPBRVertexColor 用于需要法线、粗糙度/金属度和顶点 RGBA 的程序网格。它独立于 MaterialPBR,不会改变既有 PBR 对顶点 RGB 的处理。

csharp
var material = new MaterialPBRVertexColor(
    albedoTexture,
    normalTexture,
    roughnessMetalnessTexture,
    PBRVertexColorMaterialMode.Opaque);

material.ColorFactor = HdrColor.White;
material.RoughnessOffset = 0f;
material.MetallicOffset = 0f;

首版提供 Opaque 与 AlphaCutout 两种固定模式。裁剪始终读取 Albedo Alpha,并让颜色、深度和阴影使用同一个 0.5 阈值;不提供 PBR 顶点色 Alpha 混合,连续透明仍使用 MaterialPBR.Create(..., PBRAlphaMode.AlphaBlend) 或经典 MaterialVertexColor(UnlitAlphaBlend)。

网格必须提交 Position、Normal、UV、Color 和 Tangent。法线贴图以及粗糙度/金属度贴图是线性数据,运行时创建时应设置 sRgb: false。这条 PBR 路径读取混合贴图的 R=粗糙度、G=金属度,并分别加上 RoughnessOffset、MetallicOffset;它与 MaterialPBR 的 ShaderLab 参数契约不同。

属性类型说明
ModePBRVertexColorMaterialModeOpaque 或 AlphaCutout
AlbedoTextureTexture2D?sRGB Albedo,与材质乘色和顶点 RGBA 相乘
NormalTextureTexture2D?线性法线贴图
RoughnessMetalnessTextureTexture2D?线性混合贴图,R=粗糙度、G=金属度
ColorFactorHdrColorMatDiffColor 材质乘色
SpecularFactorHdrColorMatSpecColor 非金属高光颜色因子
RoughnessOffsetfloat加到混合贴图 R 通道的偏移
MetallicOffsetfloat加到混合贴图 G 通道的偏移

MaterialFlatLambert ​

csharp
var mat = new MaterialFlatLambert(transparent: true);
mat.Color = new HdrColor(1f, 0f, 0f, 0.5f);  // 半透明红色
属性类型说明
Transparentbool是否透明(影响 Shader 选择)
ColorHdrColor主颜色。透明模式下 Alpha 通道参与混合

MaterialFlatLambert 使用已缓存的 Lambert 渲染路径,适合程序生成 Mesh、调试几何体和无贴图纯色对象。它会受场景光照、阴影和 SSAO 影响,不是严格意义的 Unlit。需要“贴图 × 顶点色”的无光照路径时使用 MaterialVertexColor(UnlitOpaque);无贴图 Unlit 仍没有独立强类型入口。

MaterialUrho2D ​

MaterialUrho2D 使用已有的 Urho2D 顶点/像素 shader,为 StaticSprite2D.CustomMaterial 提供可独立配置的材质。输出颜色为主纹理、精灵顶点颜色和材质 Color 的乘积;精灵自身的 Color / Alpha 已包含在顶点颜色中。它不受场景光照影响。

csharp
#if CLIENT
using EngineInterface.Urho3DInterface.Graphics;
using GameCore.Drawing;
using GameGraph.MaterialSystem;

// staticSprite 是已设置 Sprite 的 StaticSprite2D。
var material = new MaterialUrho2D
{
    Texture = staticSprite.Sprite!.Texture,
    Color = new HdrColor(255, 255, 255, 255),
    BlendMode = staticSprite.BlendMode,
    DepthTestMode = CompareMode.Always
};
staticSprite.CustomMaterial = material;
#endif
配置项默认值行为
Texturenull主纹理,必须自行绑定;不自动跟随精灵换图
Color白色材质乘色,含 Alpha;可通过 KnownColorProperty.Urho2DColor 访问 MatDiffColor
BlendModeAlpha材质的混合方式,接管后不跟随精灵的 BlendMode
DepthTestModeLessEqualAlways 忽略已有深度遮挡,但仍可能被后续透明对象或 UI 覆盖
DepthWritefalse开启后透明纹素也可能写深度,不会自动做 Alpha 裁剪
继承的 CullModeNone默认双面绘制

每个 MaterialUrho2D 拥有独立 Technique,修改混合和深度状态不会修改其他材质。也可使用 KnownTechnique.Urho2D:它是按需创建的共享方案,修改 pass 前必须 Clone()。例如:

csharp
var technique = KnownTechnique.Urho2D.Clone();
technique.GetPass("alpha")!.DepthTestMode = CompareMode.Always;
var custom = new MaterialCustom(technique);
custom.CullMode = CullMode.None;
custom.Textures[TextureUnit.Diffuse] = staticSprite.Sprite!.Texture;
custom.Colors[KnownColorProperty.Urho2DColor] = new HdrColor(255, 255, 255, 255);

KnownTechnique / KnownColorProperty 位于 GameGraph.MaterialSystem.Enum。Urho2D 在内存中创建,不依赖新增 XML 文件,也没有 KnownTechniquePath.Urho2D;不要通过空 Technique.Path 判断材质类型。通过 MaterialCustom.ToKnownMaterial() 按路径识别时,不会自动转换为 MaterialUrho2D。

使用边界:

  • AnimatedSprite2D 会把同一个 CustomMaterial 用到所有批次。仅在明确共享同一纹理和混合方式时使用;此入口不自动适配多图集或混合方式不同的动画部件。
  • PremulAlpha 只改变混合状态,不自动预乘纹理或颜色;资源和颜色参数需要匹配对应混合约定。
  • 默认 shader 不读取通用 UV 平铺、滚动、旋转参数,也不提供灰度、描边、溶解、扭曲。
  • 需要客户端已经提供 Technique/Pass 接口及 Urho2D shadercache;新增依赖 API 不会给缺少底层接口的旧客户端补出能力。

MaterialWater ​

csharp
var mat = new MaterialWater();
mat.TintColor = new HdrColor(0f, 0.3f, 0.6f);

MaterialWater 使用 EngineRes/Techniques/SingleLayerWater.xml,其 pass 名为 singlelayerwater,可匹配 CEMapSSAO.xml 等 RenderPath 中的水体 pass。

MaterialCustom ​

通用材质,通过名称或预定义属性 ID 访问参数。

csharp
var technique = Technique.Find("path/to/technique.xml")
    ?? throw new InvalidOperationException("Technique not found.");
var mat = new MaterialCustom(technique);

// 按名称设置
mat.SetFloat("CustomParam", 1.0f);
mat.SetVector("UVScale", new Vector4(1, 1, 0, 0));
mat.SetColor("TintColor", someHdrColor);

// 按名称读取
float val = mat.GetFloat("CustomParam");
Vector4 vec = mat.GetVector("UVScale");
HdrColor col = mat.GetColor("TintColor");

// 按属性 ID(更高效)
uint id = Technique.PropertyToID("CustomParam");
mat.SetFloat(id, 1.0f);
float v = mat.GetFloat(id);

预定义属性访问器 ​

csharp
mat.Colors[KnownColorProperty.PBRColorFactor] = color;
mat.Floats[KnownFloatProperty.PBRMetallicFactor] = 0.5f;
mat.Vectors[KnownVectorProperty.SomeProperty] = vec4;

KnownColorProperty ​

PBRColorFactor, PBREmissiveColor, FlatLambertColor, VertexColorColorFactor, OverrideColor, WaterTintColor

KnownFloatProperty ​

PBRMetallicFactor, PBRRoughnessFactor, PBREmissiveIntensity

ToKnownMaterial ​

将 MaterialCustom 转换为具体类型(如果 Shader 匹配):

csharp
Material? typed = customMat.ToKnownMaterial();
if (typed is MaterialPBR pbr)
{
    pbr.MetallicFactor = 0.8f;
}

基类 Material ​

所有材质类型的共有成员。

属性 ​

属性类型说明
TechniqueTechnique?材质绑定的 Technique XML 渲染方案
TexturesMaterialTextureAccessor贴图访问器
StencilStateStencilState模板测试配置
CullModeCullMode背面剔除(None, CCW, CW)
FillModeFillMode填充模式(Solid, Wireframe, Point)
RenderOrderuint渲染顺序(值越大越晚渲染)

方法 ​

csharp
// 加载材质文件
static Material? Load(GameCore.ResourceType.Material materialPath);

// Technique Pass 控制
void SetPassEnabled(string passName, bool enabled);
void SetPassDepthWrite(string passName, bool depthWrite);
void SetPassColorWrite(string passName, bool colorWrite);

// 运行时诊断
bool HasPass(string passName, uint techniqueIndex = 0);
MaterialDebugInfo GetDebugInfo(IEnumerable<string>? passNames = null);
string DebugDescribe(IEnumerable<string>? passNames = null);

运行时诊断 ​

当材质在代码里已经赋给 StaticMeshComponent,但画面里看不到或和 RenderDoc 抓帧不一致时,先读取运行时材质快照,不要只猜 shader 或 C# 逻辑。

csharp
Game.Logger.LogInformation("black hole material: {Material}", material.DebugDescribe());

bool hasBase = material.HasPass("base");
bool hasAlpha = material.HasPass("alpha");
bool hasDepth = material.HasPass("depth");

var info = material.GetDebugInfo(["base", "alpha", "depth"]);

MaterialDebugInfo 常用字段:

字段说明
TechniquePath当前绑定的 technique XML 路径
TechniqueCount当前材质 technique 数量
Passes指定 pass 在各 technique 上是否存在
Properties已知材质类型的关键参数,例如 MatDiffColor、ColorFactor、Emissive_Mul
CullMode / FillMode / RenderOrder常见渲染状态
StencilState模板测试状态
VertexShaderDefines / PixelShaderDefines材质级 shader defines

也可以通过 Runtime MCP 在运行中的客户端里直接探测 SceneGraph 材质:

json
{
  "name": "material.probe",
  "arguments": {
    "query": "BlackHole",
    "passNames": ["base", "alpha", "depth"]
  }
}
json
{
  "name": "scenegraph.materials",
  "arguments": {
    "query": "Unlit",
    "includeCurrentScenes": true,
    "includeSession": true,
    "includeReplicated": true,
    "maxResults": 20,
    "passNames": ["base", "alpha", "depth"]
  }
}

scenegraph.materials 会遍历已加载 SCE 场景、脚本 session SceneGraph 和 replicated SceneGraph,覆盖 StaticMeshComponent 与 CustomGeometryComponent。StaticMesh 还返回 Mesh/LOD0 Geometry/VertexBuffer/IndexBuffer 元数据;CustomGeometry 返回 material slot 和顶点数,当前无法读取的精确 GPU layout 会明确标为 unavailable。材质条目同时包含常用纹理槽与实际 pass 状态。

material.probe / scenegraph.materials 参数说明:

参数类型说明
querystring可选。按节点名、材质类型名或 technique path 子串过滤
nodeIdintegermaterial.probe 可选。精确匹配 SceneGraph 节点 ID
materialIndexinteger可选。指定 StaticMesh 或 CustomGeometry 的几何体/材质槽索引
includeCurrentScenesbool是否包含已加载 SCE 场景,默认 true
includeSessionbool是否包含客户端脚本本地创建的 session SceneGraph,默认 true
includeReplicatedbool是否包含客户端订阅到的 replicated SceneGraph,默认 true
maxNodesinteger最多遍历节点数,默认 1000
maxResultsintegerscenegraph.materials 返回的最大材质条目数,默认 200
maxDiagnosticsinteger局部资源不可读诊断上限;列表默认跟随 maxResults,单点探测默认 50
passNamesstring[]需要检查的 pass 名。对 CEMapSSAO.xml 常用 ["base","alpha","depth","singlelayerwater"]

返回值里优先看 entry.graph、entry.drawable、entry.geometry / entry.custom_geometry、entry.material.technique_path、entry.material.passes、entry.material.textures 与渲染状态。瞬态失效只生成有界 diagnostics,不会让其他条目一起失败。static_mesh、shader_path、has_shader 等旧字段继续保留。

RenderPath 与 pass 排查 ​

RenderPath 只会执行它声明的 pass。若 technique 没有对应 pass,该对象不会参与那一轮渲染。MaterialFlatLambert 默认使用 EngineRes/Techniques/NoTextureFlatLambert.xml,它包含 base 和 depth pass;在 EngineRes/RenderPaths/CEMapSSAO.xml 这类先执行 pass="depth" 生成 SSAO 深度缓冲的 RenderPath 下,opaque FlatLambert 会参与 depth prepass。

EngineRes/Techniques/NoTextureFlatLambertAlpha.xml 提供 alpha pass;CEMapSSAO.xml 也会执行 alpha pass,所以透明 FlatLambert 从 pass 名匹配上看是成立的。MaterialWater 使用 EngineRes/Techniques/SingleLayerWater.xml,提供 singlelayerwater pass。若对象仍不可见,优先检查材质 alpha、RenderOrder、深度/混合状态、节点 scale、相机裁剪和 RenderDoc 中是否存在对应 draw call。

贴图 ​

csharp
material.Textures[TextureUnit.PBRAlbedo] = albedoTexture;
material.Textures[TextureUnit.PBRMetalnessR_RoughnessG] = specularTexture;

常用 TextureUnit:PBRAlbedo(0), Normal(1), PBRMetalnessR_RoughnessG(2), Emissive(3), PBRAmbientOcclusionMap(14), LightMap(16)

模板测试(Stencil) ​

csharp
material.StencilState = new StencilState
{
    StencilTest = true,
    StencilCompare = CompareMode.Equal,
    StencilRef = 1,
    StencilWriteMask = 0xFF,
    StencilReadMask = 0xFF,
    PassOp = StencilOp.Keep,
};

StencilState 字段 ​

字段类型默认值说明
StencilTestboolfalse是否启用
StencilCompareCompareModeAlways比较方式
StencilRefint0参考值
PassOpStencilOpKeep通过时操作
StencilReadMaskuint0读取掩码
StencilWriteMaskuint0写入掩码

CompareMode:Always, Equal, NotEqual, Less, LessEqual, Greater, GreaterEqual

StencilOp:Keep, Zero, Ref, Incr, Decr

SceneGraph 遮罩示例 ​

Stencil 只依赖材质渲染状态。SceneGraph 中使用遮罩时,先让写入模板的物体渲染,再让读取模板的物体渲染;用 RenderOrder 显式固定顺序,避免默认排序影响结果。

csharp
const int stencilRef = 1;

// 写入模板:先渲染,把覆盖区域写成 stencilRef
var maskMat = new MaterialPBR { RenderOrder = 10 };
maskMat.StencilState = new StencilState
{
    StencilTest = true,
    StencilCompare = CompareMode.Always,
    StencilRef = stencilRef,
    StencilReadMask = 0xFF,
    StencilWriteMask = 0xFF,
    PassOp = StencilOp.Ref,
};

// 读取模板:只在写入区域内渲染
var insideMat = new MaterialPBR { RenderOrder = 20 };
insideMat.StencilState = new StencilState
{
    StencilTest = true,
    StencilCompare = CompareMode.Equal,
    StencilRef = stencilRef,
    StencilReadMask = 0xFF,
    StencilWriteMask = 0,
    PassOp = StencilOp.Keep,
};
insideMat.SetPassDepthWrite("base", false);

// 读取模板:只在写入区域外渲染
var outsideMat = new MaterialPBR { RenderOrder = 30 };
outsideMat.StencilState = new StencilState
{
    StencilTest = true,
    StencilCompare = CompareMode.NotEqual,
    StencilRef = stencilRef,
    StencilReadMask = 0xFF,
    StencilWriteMask = 0,
    PassOp = StencilOp.Keep,
};
outsideMat.SetPassDepthWrite("base", false);

当读取物体的几何范围大于写入物体时,insideMat 只会显示在写入区域内,outsideMat 只会显示在写入区域外。若结果看起来只是普通叠色,优先检查 RenderOrder、StencilRef、StencilReadMask/StencilWriteMask 是否匹配,以及 Viewport 是否设置了预期的 RenderPath。

应用材质 ​

csharp
// 设置整体材质
meshComponent.Material = material;

// 按几何体索引设置
meshComponent.SetMaterial(0, material);

// 批量设置
meshComponent.Materials = new[] { mat1, mat2 };

Technique 与 Shader 的边界 ​

Technique 表示材质的渲染方案,可以从 XML 加载,也可以在内存中创建。它负责组织 pass、混合/深度状态、shader 名称与 defines,但不是真正的 HLSL/GLSL shader 源文件。未来如果开放运行时 shader 编译,将使用独立的 ShaderSource、ShaderStage、ShaderVariant、ShaderCompiler 等概念,不复用 Technique 名称。

csharp
// 查找 Technique XML
Technique? technique = Technique.Find("path/to/technique.xml");

// 参数名转 ID(用于 MaterialCustom 高效访问)
uint id = Technique.PropertyToID("MetallicFactor");

内置 Technique 路径(KnownTechniquePath) ​

常量路径
PhysicalBasedRenderingEditor/Techniques/PBR_PackedNormal/DefaultMetallicRoughness.xml
PhysicalBasedRenderingAlpha兼容旧资源:Editor/Techniques/PBR_PackedNormal/DefaultMetallicRoughnessTransparent.xml;新代码使用 PhysicalBasedRenderingAlphaBlend
PhysicalBasedRenderingSolidEditor/Techniques/PBR_PackedNormal/DefaultMetallicRoughnessSolid.xml
PhysicalBasedRenderingAlphaSolid兼容旧资源:Editor/Techniques/PBR_PackedNormal/DefaultMetallicRoughnessTransparentSolid.xml;新代码使用 PhysicalBasedRenderingAlphaBlendSolid
PhysicalBasedRenderingAlphaCutoutEngineRes/Techniques/PBR/DefaultMetallicRoughnessAlphaCutout.xml
PhysicalBasedRenderingAlphaBlendEngineRes/Techniques/PBR/DefaultMetallicRoughnessAlphaBlend.xml
PhysicalBasedRenderingAlphaBlendSolidEngineRes/Techniques/PBR/DefaultMetallicRoughnessAlphaBlendSolid.xml
DefaultLambertEditor/Techniques/Lambert/DefaultLambert.xml
ParticleLambertEditor/Techniques/Lambert/ParticleLambert.xml
UnlitStealthEditor/Techniques/Lambert/UnlitStealth.xml
GrayLevelFiveEditor/Techniques/PBR_PackedNormal/GrayLevelFive.xml
GrayLevelTwoEditor/Techniques/PBR_PackedNormal/GrayLevelTwo.xml
HairSimulationEditor/Techniques/PBR_PackedNormal/HairSimulation.xml
StaticObjectEditor/Techniques/PBR_PackedNormal/StaticObject.xml
FlatLambertEngineRes/Techniques/NoTextureFlatLambert.xml
FlatLambertAlphaEngineRes/Techniques/NoTextureFlatLambertAlpha.xml
WaterEngineRes/Techniques/SingleLayerWater.xml
TexturedVertexColorLitOpaqueEngineRes/Techniques/DiffVCol.xml
TexturedVertexColorUnlitOpaqueEngineRes/Techniques/DiffVColUnlit.xml
TexturedVertexColorLitAlphaCutoutEngineRes/Techniques/DiffVColAlphaMask.xml
TexturedVertexColorUnlitAlphaBlendEngineRes/Techniques/DiffVColUnlitAlphaBlend.xml
PhysicalBasedRenderingVertexColorEngineRes/Techniques/PBR/PBRMetallicRoughDiffNormalSpecVCol.xml
PhysicalBasedRenderingVertexColorAlphaCutoutEngineRes/Techniques/PBR/PBRMetallicRoughDiffNormalSpecVColMask.xml

部分 KnownTechniquePath 对应的 Technique XML 可在 resources/rendering-reference/ 中直接阅读。参考目录还包含常用 RenderPath、默认 Material 和 Day/Dusk/Night 光照预设。它们是文档副本,不会自动成为项目运行时资源;Technique 中引用的真正 shader/define 组合由已发布 shadercache 提供。

相关文档 ​