画面特效包
作用于整个画面的后处理包 (API 3):色差、胶片颗粒、CRT 等。清单字段、PackEffect、阶段、特效栈与在线图库。
什么是特效包
表面包 (surface) 替换单个角色材质的着色。特效包 ("type": "effect") 则作用于已完成的整个画面:色差、胶片颗粒、CRT 扫描线、故障效果、自定义暗角等。特效属于整个画面,而不是某个模型。
特效不随应用内置。请在着色器标签页的在线列表 (图库) 中安装,或导入 zip。图库目前提供 chromatic_aberration、film_grain 和 crt_scanlines。特效包需要 MMDX12 1.4.0 或更高版本 (API 版本 3)。
使用特效
- 在着色器标签页的在线列表中安装特效包。
- 在大厅的着色器标签页展开画面效果一行,或点击播放栏上的闪光按钮。
- 启用需要的特效,用箭头调整顺序,并调节滑块。
特效栈对最终图像从上到下依次执行,适用于播放画面、大厅预览以及实时视频和静帧渲染 (光栅、实时 RT、实时 PT)。不适用于离线 GI 渲染器、无光照和线框视图以及工作室的四视图。没有启用任何特效时,不会创建额外的渲染目标和渲染通道,画面与没有此功能的版本完全相同。
命令行中,--effect <id>[,<id>...] 在单次运行中替换特效栈,--effect none 清空。
文件夹结构
my_effect/
pack.json 清单 (与表面包相同的字段 + type / stage)
effect.hlsl 实现 PackEffect
preview.png 可选,建议 16:9
textures/ 可选,pack.json 的 "textures" (规则与表面包相同)
清单新增项
{
"format": 1,
"id": "film_grain",
"version": "1.0.0",
"apiVersion": 3,
"minAppVersion": "1.4.0",
"type": "effect",
"stage": "post",
"name": { "zh": "胶片颗粒", "en": "Film grain" },
"params": [
{ "key": "strength", "label": { "zh": "强度", "en": "Strength" }, "default": 0.12, "min": 0.0, "max": 0.6 }
]
}
"type": "effect"表示特效包 (默认为"surface")。"stage"为"post"(默认) 或"pre-bloom"。- 不使用
classes。params(最多 16 个) 和textures(最多 16 个) 与表面包的行为完全相同,参见清单。
| stage | 输入与输出 | 用途 |
|---|---|---|
post | 色调映射和颜色 LUT 之后的显示 sRGB,8 位 | 颗粒、扫描线、镜头色边、暗角 |
pre-bloom | 泛光之前的线性 HDR RGBA16F | 适合辉光或与曝光相关的特效 |
两个阶段的特效可以放在同一个栈中,每个阶段只按栈顺序运行属于自己的特效。
effect.hlsl
特效包实现一个函数:
float3 PackEffect(PackEffectInput i) { return i.color.rgb; }
PackEffectInput 字段:
| 字段 | 含义 |
|---|---|
uv | 纹素中心,0..1,左上角 = (0, 0) |
pixel | SV_Position.xy (像素) |
outputSize | 输出分辨率 (像素) |
time | 场景开始后的秒数 |
frameIndex | 帧计数器 (到 64 回绕) |
color | 此像素到目前为止的画面 (保留 alpha) |
depth | 原始设备深度,1 = 背景 (用 LinearZ() 转换) |
normal | 世界空间法线,背景处未定义 |
motion | 运动向量,uv(当前) - uv(上一帧) |
辅助函数:
gEffectSource.SampleLevel(gLinear, uv, 0)读取到目前为止画面的任意像素 (双线性、钳制)。镜头类特效就是这样查看周围像素的。PackParam(i)按pack.json顺序返回第 i 个参数的滑块值 (或默认值)。PackFxSampleTex(i, uv)、PackFxSampleTexLevel、PackFxTexSize、PackFxTexCount用于采样包内纹理。sRGB 纹理返回线性值。common.hlsli中的全部内容:Luminance、LinearZ、Ign、SrgbToLinear、gTime等。
line 是 HLSL 的保留字。
示例:色差
float3 PackEffect(PackEffectInput i) {
const float2 dir = i.uv - 0.5;
const float r = length(dir) * 1.41421356; // 中心为 0,角落为 1
const float2 offset = dir * (PackParam(0) * 0.03 * pow(r, PackParam(1)));
float3 c;
c.r = gEffectSource.SampleLevel(gLinear, i.uv + offset, 0).r;
c.g = i.color.g;
c.b = gEffectSource.SampleLevel(gLinear, i.uv - offset, 0).b;
return c;
}
红色和蓝色沿远离画面中心的方向采样,越靠近边缘偏移越大。
编译与调试
着色器在运行时用 DXC (ps_6_0) 编译。编译错误会跳过该特效,在 mmdx12.log 写入 [E] 行,并通过提示和着色器管理器中的状态告知,不会崩溃。应用运行时保存 effect.hlsl 会自动重新加载。
命令行可用 pack_check <文件夹|zip> --compile 检查,参见调试。发行版的 shaders/pack_template_effect 可作为起点。
发布
特效包与表面包使用相同的 zip 结构、版本和审核规则,参见发布。由于 API 版本为 3,请设置 "minAppVersion": "1.4.0"。