URP 渲染实战 / 第 1 章 从像素说起:GPU 渲染管线与坐标空间 / 案例 1.4
案例 1.4透视校正插值 vs 仿射插值入门
目标:复现 1.7 节说的“仿射插值”,看看没有透视校正的纹理是什么样子。
原理:HLSL 允许给 Varyings 的成员加插值修饰符(Interpolation Modifier)。noperspective 让这个值在屏幕空间里线性插值,跳过透视校正。同一份 UV 传两遍,一份默认,一份加 noperspective,片元里用开关选择。
Assets/Cookbook/Ch01/PerspectiveInterp.shader(节选:varyings)
struct Varyings { float4 positionCS : SV_POSITION; float2 uv : TEXCOORD0; // 默认:透视校正插值 noperspective float2 uvAffine : TEXCOORD1; // 在屏幕空间里线性插值(PS1 时代的效果) };

右图的地面上,纹理在两个三角形的公共对角线处明显“折断”,每个三角形内部的格子都朝同一方向歪斜。这正是 PS1 时代游戏的标志性瑕疵。注意右边那面斜墙:它几乎正对相机,深度变化很小,仿射插值的误差也就很小——误差大小取决于三角形内部 w(深度)的变化幅度。当年的游戏靠把大三角形细分成小三角形来缓解,就是这个原因。
noperspective 不只是用来怀旧。凡是本来就在屏幕空间里线性变化的量,用它插值才是“正确”的,下一个案例就是例子。其他修饰符还有 nointerpolation(不插值,整个三角形取第一个顶点的值,常用于传递整数 ID)、centroid(MSAA 下在覆盖区域的质心采样,防止采样点落在三角形外)等。
本案例出自《URP 渲染实战》第 1 章「从像素说起:GPU 渲染管线与坐标空间」。在章节中阅读上下文 →