2026-05-03 20:37:58 +08:00
|
|
|
|
---
|
|
|
|
|
|
title: 自定义材质属性
|
|
|
|
|
|
date: 2026-05-03 00:00:00
|
|
|
|
|
|
excerpt: 新增 MaterialProperty、BlendMode 和材质标记
|
|
|
|
|
|
tags:
|
|
|
|
|
|
- ARC
|
|
|
|
|
|
- Rendering
|
|
|
|
|
|
- Material
|
|
|
|
|
|
rating: ⭐
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
# 自定义材质属性
|
|
|
|
|
|
|
|
|
|
|
|
返回 [[Rendering]]
|
|
|
|
|
|
|
|
|
|
|
|
## 概述
|
|
|
|
|
|
|
|
|
|
|
|
ARC 引擎在 UE4 材质系统中新增了多个材质属性(MaterialProperty)、混合模式(BlendMode)和材质标记,为卡通渲染的顶点变换和特殊效果提供材质图级别的控制能力。
|
|
|
|
|
|
|
|
|
|
|
|
## 新增材质属性
|
|
|
|
|
|
|
|
|
|
|
|
| 属性 | 枚举值 | 类型 | 用途 |
|
|
|
|
|
|
|------|--------|------|------|
|
|
|
|
|
|
| `MP_OrthoBlendWeight` | float | 顶点 | [[正交投影混合]]权重,0=透视,1=正交 |
|
|
|
|
|
|
| `MP_ScreenAlignedMeshOffset` | float3 | 顶点 | [[屏幕对齐网格]]偏移(像素单位) |
|
|
|
|
|
|
| `MP_ScreenAlignedMeshScale` | float3 | 顶点 | [[屏幕对齐网格]]缩放 |
|
|
|
|
|
|
| `MP_ScreenSpaceDepthOffset` | float | 顶点 | [[屏幕空间深度偏移]]值 |
|
|
|
|
|
|
| `MP_LocalPositionScale` | float3 | 顶点 | [[局部位置缩放]]系数 |
|
|
|
|
|
|
|
|
|
|
|
|
### Shader 端访问函数
|
|
|
|
|
|
|
|
|
|
|
|
在 `MaterialTemplate.ush` 中生成对应的访问函数:
|
|
|
|
|
|
|
|
|
|
|
|
```hlsl
|
|
|
|
|
|
float GetMaterialOrthoBlendWeight(FMaterialVertexParameters Parameters) { %s; }
|
|
|
|
|
|
float3 GetMaterialScreenAlignedMeshOffset(FMaterialVertexParameters Parameters) { %s; }
|
|
|
|
|
|
float3 GetMaterialScreenAlignedMeshScale(FMaterialVertexParameters Parameters) { %s; }
|
|
|
|
|
|
float GetMaterialScreenSpaceDepthOffset(FMaterialVertexParameters Parameters) { %s; }
|
|
|
|
|
|
float3 GetMaterialLocalPositionScale(FMaterialVertexParameters Parameters) { %s; }
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
`%s` 由 `HLSLMaterialTranslator` 在编译时替换为材质图表达式。
|
|
|
|
|
|
|
|
|
|
|
|
## 新增混合模式
|
|
|
|
|
|
|
|
|
|
|
|
| 混合模式 | 枚举值 | 混合公式 | 用途 |
|
|
|
|
|
|
|---------|--------|---------|------|
|
|
|
|
|
|
| `BLEND_X2Multiply` | — | `DestColor × SourceColor × 2` | 双倍乘法混合,用于深色叠加 |
|
|
|
|
|
|
| `BLEND_AdditiveForUI` | — | `Dest + Source × SourceAlpha` | UI 专用加法混合 |
|
|
|
|
|
|
|
|
|
|
|
|
### X2Multiply 雾效处理
|
|
|
|
|
|
|
|
|
|
|
|
在 `BasePassPixelShader.usf` 中为 X2Multiply 提供自定义雾效混合:
|
|
|
|
|
|
|
|
|
|
|
|
```hlsl
|
|
|
|
|
|
#elif MATERIALBLENDING_X2MULTIPLY
|
|
|
|
|
|
half3 FoggedColor = lerp(
|
|
|
|
|
|
float3(0.5, 0.5, 0.5), // 中灰(乘法中性色)
|
|
|
|
|
|
Color,
|
|
|
|
|
|
Fogging.aaa * Fogging.aaa);
|
|
|
|
|
|
Out.MRT[0] = half4(FoggedColor, Opacity);
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## 新增材质标记
|
|
|
|
|
|
|
|
|
|
|
|
| 标记 | 类型 | 说明 |
|
|
|
|
|
|
|------|------|------|
|
|
|
|
|
|
| `bScreenAlignedMesh` | bool | 启用[[屏幕对齐网格]]渲染模式 |
|
|
|
|
|
|
| `bForcedPrepass` | bool | 强制该材质走 Early-Z PrePass(ASW/Wizcorp) |
|
|
|
|
|
|
|
|
|
|
|
|
### bForcedPrepass
|
|
|
|
|
|
|
|
|
|
|
|
在 `BasePassRendering.cpp` 中控制深度绘制行为:
|
|
|
|
|
|
|
|
|
|
|
|
```cpp
|
|
|
|
|
|
// 强制 PrePass 的材质始终写入深度
|
|
|
|
|
|
if (Material.bForcedPrepass)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 走 DepthPass 而非依赖 BasePass 深度写入
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
可在材质实例中覆盖(`MaterialEditor` 中显示为可覆盖属性)。
|
|
|
|
|
|
|
|
|
|
|
|
## REDMaterialInstanceDynamic
|
|
|
|
|
|
|
|
|
|
|
|
新增 `REDMaterialInstanceDynamic` 类(`REDMaterialInstanceDynamic.h/.cpp`),扩展了标准 `UMaterialInstanceDynamic`,可能用于运行时的卡通渲染材质参数控制。
|
|
|
|
|
|
|
2026-05-03 21:38:46 +08:00
|
|
|
|
## 完整代码解析
|
|
|
|
|
|
|
|
|
|
|
|
### MaterialTemplate.ush — 新增材质属性访问函数
|
|
|
|
|
|
|
|
|
|
|
|
```hlsl
|
|
|
|
|
|
// MaterialTemplate.ush — 新增材质属性访问函数
|
|
|
|
|
|
// ASW Change : 2016/03/29 ~ 2016/06/29 Takuro.K
|
|
|
|
|
|
|
|
|
|
|
|
// 正交投影混合权重 (float)
|
|
|
|
|
|
// 材质图中连接到此 Pin 的表达式会在编译时替换 %s
|
|
|
|
|
|
float GetMaterialOrthoBlendWeight(FMaterialVertexParameters Parameters)
|
|
|
|
|
|
{
|
|
|
|
|
|
%s; // 由 HLSLMaterialTranslator 填充
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 屏幕对齐网格偏移 (float3, 像素单位, 基于1280x720)
|
|
|
|
|
|
float3 GetMaterialScreenAlignedMeshOffset(FMaterialVertexParameters Parameters)
|
|
|
|
|
|
{
|
|
|
|
|
|
%s;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 屏幕对齐网格缩放 (float3)
|
|
|
|
|
|
float3 GetMaterialScreenAlignedMeshScale(FMaterialVertexParameters Parameters)
|
|
|
|
|
|
{
|
|
|
|
|
|
%s;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 屏幕空间深度偏移 (float, 正值向远推)
|
|
|
|
|
|
float GetMaterialScreenSpaceDepthOffset(FMaterialVertexParameters Parameters)
|
|
|
|
|
|
{
|
|
|
|
|
|
%s;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 局部位置缩放 (float3, 在WorldTransform前应用)
|
|
|
|
|
|
float3 GetMaterialLocalPositionScale(FMaterialVertexParameters Parameters)
|
|
|
|
|
|
{
|
|
|
|
|
|
%s;
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### PixelDepthOffset 修复
|
|
|
|
|
|
|
|
|
|
|
|
```hlsl
|
|
|
|
|
|
// ASW Change : 2020/10/29 Takeshi.N
|
|
|
|
|
|
// 修复 PC 平台 PixelDepthOffset 为 0 或负值时的噪声问题
|
|
|
|
|
|
// 当 PDO <= 0 时,直接使用原始 SvPosition.z 而非计算值
|
|
|
|
|
|
DeviceDepth = lerp(
|
|
|
|
|
|
DeviceDepth, // PDO > 0:使用计算后的深度
|
|
|
|
|
|
MaterialParameters.SvPosition.z, // PDO <= 0:使用原始深度
|
|
|
|
|
|
step(PixelDepthOffset, 0) // step 函数:PDO<=0 返回 1
|
|
|
|
|
|
);
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2026-05-03 20:37:58 +08:00
|
|
|
|
## 关联文档
|
|
|
|
|
|
|
|
|
|
|
|
- [[正交投影混合]] — 使用 `MP_OrthoBlendWeight`
|
|
|
|
|
|
- [[屏幕对齐网格]] — 使用 `MP_ScreenAlignedMeshOffset/Scale`
|
|
|
|
|
|
- [[BasePass修改]] — `bForcedPrepass` 的影响
|
|
|
|
|
|
|
2026-05-03 21:38:46 +08:00
|
|
|
|
## 代码修改情况
|
|
|
|
|
|
|
|
|
|
|
|
| 文件路径 | 行号 | 修改类型 | 修改内容 |
|
|
|
|
|
|
|---------|------|---------|---------|
|
|
|
|
|
|
| `Shaders/Private/MaterialTemplate.ush` | L2235~L2240 | 新增 | `GetMaterialOrthoBlendWeight` 函数 |
|
|
|
|
|
|
| `Shaders/Private/MaterialTemplate.ush` | L2243~L2252 | 新增 | `GetMaterialScreenAlignedMeshOffset/Scale` 函数 |
|
|
|
|
|
|
| `Shaders/Private/MaterialTemplate.ush` | L2255~L2260 | 新增 | `GetMaterialScreenSpaceDepthOffset` 函数 |
|
|
|
|
|
|
| `Shaders/Private/MaterialTemplate.ush` | L2263~L2268 | 新增 | `GetMaterialLocalPositionScale` 函数 |
|
|
|
|
|
|
| `Shaders/Private/MaterialTemplate.ush` | L2584~L2587 | 新增 | PixelDepthOffset ≤ 0 时使用原始深度 |
|
|
|
|
|
|
| `Source/Runtime/Engine/Public/SceneTypes.h` | — | 新增 | `MP_OrthoBlendWeight` 等枚举值 |
|
|
|
|
|
|
| `Source/Runtime/Engine/Classes/Materials/Material.h` | — | 新增 | `bScreenAlignedMesh`、`bForcedPrepass` 标记 |
|
|
|
|
|
|
| `Source/Runtime/Engine/Classes/Materials/REDMaterialInstanceDynamic.h` | 全文 | **新增文件** | 自定义 MaterialInstanceDynamic |
|
|
|
|
|
|
| `Source/Runtime/Engine/Private/Materials/REDMaterialInstanceDynamic.cpp` | 全文 | **新增文件** | 实现 |
|
|
|
|
|
|
| `Source/Runtime/Engine/Private/Materials/HLSLMaterialTranslator.cpp` | — | 修改 | 新属性编译支持 |
|
|
|
|
|
|
| `Source/Editor/MaterialEditor/` | — | 修改 | 编辑器 UI 支持 |
|