PT / GI 包

pt_surface.hlsl:在路径追踪与离线 GI 渲染器中应用着色器包。PackEvaluate、PtPackIn / PtPackOut、贴图、降噪器与限制。

什么是 PT / GI 包

表面包(surface.hlsl)通过 PackShade 为光栅与光线追踪的相机视图着色。路径追踪器(--render pt、PT 视频渲染器)和离线 GI 渲染器(GI 静帧与视频)在同一个计算着色器内追踪所有光线,因此 PackShade 无法在其中运行。包可以用第二个文件 pt_surface.hlsl 参与,它描述命中点处的材质。光的传输(太阳阴影、间接光、辐照度缓存、降噪器)仍由渲染器负责。

需要 MMDX12 1.5.0 或更高版本。没有该文件的包在 PT 与 GI 中使用默认着色,旧版本会忽略该文件。

文件

my_pack/
  pack.json        清单(不变)
  surface.hlsl     光栅 / 实时 RT        (PackShade)
  pt_surface.hlsl  路径追踪 / 离线 GI    (PackEvaluate)
  shared.hlsli     可选:两个文件共用的数学

两个文件都可以 #include "shared.hlsli"(位于包文件夹中),外观只需写一次。在线图库的 nimble_toon 就是这样做的。

PackEvaluate

PtPackOut PackEvaluate(PtPackIn i);

PtPackIn

字段含义
pos, normal, V, uv世界坐标位置、着色法线、朝向相机的方向、纹理坐标
L, sunVis朝向太阳的方向,由追踪的阴影光线得到的太阳可见度 0..1(漫反射弹射时为 0)
baseColor线性纹理色 × 材质色,不含光照
materialClass由 classes 规则决定的 PACK_BODY / SKIN / FACE / EYE / HAIR / WEAPON
params[16]按 pack.json 顺序的滑块值
headPos, headScale, headRight, headUp, headForward, headValid与 PackSurface 相同的头部骨骼坐标系

PtPackOut(请为每个字段赋值;有字段从未被赋值时 pack_check 会警告)

字段含义
albedo线性表面颜色,漫反射弹射和降噪器看到的值
shadowTint乘在阴影一侧的线性系数
shadowBias以 N.L 为单位平移明暗交界线(平滑后的脸部法线:dot(Nsmooth, L) - dot(normal, L))
terminator明暗交界 smoothstep 的 N.L 端点 (lo, hi);(0, 0) 表示引擎默认值
specular叠加的线性辐射亮度(边缘光、光泽、matcap),会乘以 sunVis
flatFace使用引擎的平坦脸部处理(该表面没有间接光渐变)

渲染器如何使用

  • 相机光线以及镜面 / 玻璃链:lerp(albedo * shadowTint, albedo, term * sunVis) * sunIntensity + specular * sunVis,其中 term = smoothstep(lo, hi, N.L + shadowBias)。
  • 漫反射弹射(其他表面收集的光):只使用 albedo,卡通项不会在收集光线上运行。
  • 不要再加环境光项:路径追踪器会追踪真实的间接光。
  • 半兰伯特色阶 threshold ± softness 可换算为 terminator = (2 * (threshold - softness) - 1, 2 * (threshold + softness) - 1)。

贴图

可以使用 pack.json 中声明的贴图(仅显式 LOD,没有隐式导数):

float4 PtPackSampleTex(uint i, float2 uv);                 // 第 0 级
float4 PtPackSampleTexLevel(uint i, float2 uv, float lod);
uint   PtPackTexCount();
float2 PtPackTexSize(uint i);

越界索引或缺失的文件与 PackSampleTex 一样返回白色。sRGB 贴图按线性值采样。

限制

  • 仅作用于角色,舞台和道具不会被包着色。
  • 同一场景中有多个不同的 PT 包时使用第一个(日志中会有警告)。
  • 离线 GI 渲染器绘制应用默认的描边(PackEdge 作用于光栅与 RT)。
  • 降噪器把包的直接光与默认卡通光同样处理。静帧测试中,硬 step() 高光的边缘保持清晰;快速运动下的表现尚未验证。
  • 请避免在 PackEvaluate 中使用无界循环:GPU 挂起会导致应用退出。
  • 用 pack_check <目录> --compile 检查:它会编译光栅、离线 GI 与路径追踪三个变体。