光栅化与属性插值
全库目录221
本文目录9
同一个三角形的UV在斜面上扭曲,往往是屏幕插值没有还原透视关系。光栅器先判断覆盖,再插值顶点属性,重心权重与clip w各有用途。我们从共享边覆盖开始,再看透视校正与导数,利用棋盘格区分坐标错误和过滤误差。
三角形覆盖
经过裁剪和透视除法后,三角形落到屏幕坐标。光栅器根据边函数判断一个样本点位于三角形内部、外部还是边界。
对边从 指向 ,定义 。它是有向面积的两倍,符号表示点位于边的哪一侧。对逆时针三角形,三个边函数都为正的点在内部;除以整三角形的有向面积就得到对应重心权重。屏幕Y轴向下时绕序符号要同步改变。面积为零的退化三角形不能做这次除法。
共享边需要统一规则,否则两个三角形可能同时覆盖或同时漏掉边界样本。常见实现使用 Top-left Rule,但具体定义由 API 规范决定。
共享边样本的归属
以屏幕Y向上、逆时针边界作为教学约定,边函数大于零表示内部。边函数恰好为零时,需要半开边界规则。例如将向下的边,以及向左的水平边标为包含边:dy<0 || (dy==0 && dx<0)。这对应此坐标约定的上边/左边归属;API若使用向下Y和不同绕序,判断式必须随之变化。
正方形A=(0,0)、B=(2,0)、C=(2,2)、D=(0,2)拆成ABC与ACD。共享边在第一片中为C→A,dy=-2,包含边上样本(1,1);第二片的A→C,dy=2,不包含该样本。两片内部都能覆盖自己的区域,共享边却只由一片拥有。若对全部零值都接受,会重复混合;全部拒绝则留下裂缝。实际光栅器还在规定的子像素精度和采样位置上计算覆盖,本例用于解释归属规则。
重心坐标
三角形内的点可以表示为三个顶点的加权和:
三个 就是重心坐标。光栅器用它插值颜色、UV、法线等 Vertex Shader 输出。
透视正确插值
透视投影后,屏幕距离和三维距离不再线性对应。如果直接在屏幕空间线性插值 UV,纹理会在倾斜表面上滑动或扭曲。
透视正确插值会先插值 和 :
取一条边的屏幕中点,两个端点的 为1和2,属性值为0和1。屏幕平均得到0.5,透视插值则为 。远端在屏幕上被压缩,屏幕中点并不是原始线段的参数中点。这也是倾斜棋盘格需要校正的原因。
Shader 语言通常默认对普通 Varying 使用透视正确插值。noperspective、flat/nointerpolation 等修饰符会改变行为。
屏幕空间导数
Pixel Shader 常按 2x2 Quad 一起执行。ddx 和 ddy 可以用相邻 Lane 的值估计屏幕方向变化。纹理系统据此估计 Mipmap LOD。
控制流发散、三角形边缘和 Helper Invocation 会让导数行为更复杂。不要在不一致分支中假设导数一定稳定。
取一个2×2像素组,上排属性值为(2,4),下排为(5,9)。按行作差,上排ddx为2,下排为4;按列作差,左列ddy为3,右列为5。导数反映邻近调用的属性变化,不是把当前值代入一个解析求导器。三角形边外的辅助调用可补足差分,但没有覆盖的调用并不输出同样的颜色或副作用;在只有部分调用执行的分支里,也不能假设所需邻居都提供了相同定义的值。具体fine/coarse导数选择按着色语言约定。
透视插值的计算轮廓
输入是屏幕空间重心权重、三个顶点的 UV 和裁剪坐标 w,输出当前采样点的 UV。裁剪已经完成,w 非零,权重之和为 1。
float2 InterpolateUv(float3 weights, float3 clipW,
float2 firstUv, float2 secondUv, float2 thirdUv)
{
float3 corrected = weights / clipW;
float denominator = corrected.x + corrected.y + corrected.z;
float2 numerator = corrected.x * firstUv
+ corrected.y * secondUv
+ corrected.z * thirdUv;
return numerator / denominator;
}这是光栅器默认透视插值的数学轮廓,普通片元 Shader 无需手写重复计算。将三个 w 设为相同,结果退化为屏幕线性插值;w 不同时用倾斜棋盘格比较两种结果。
验证方法
- 用共享边三角形检查漏缝与重复覆盖。
- 在倾斜棋盘格平面上对比透视正确和屏幕线性插值。
- 输出 UV 导数及 mip 等级,检查三角形边界和不一致分支。
相关主题
实现与验证:raster_models.py 与 test_raster.py检查透视中点反例及相同w的退化情形,运行 python -B 知识库/examples/revision/test_raster.py。正文HLSL是数学片段,完整光栅器覆盖、导数及GPU画面尚未运行。
参考资料
- Microsoft Direct3D 11 Rasterization Rules:2026-10-22核读Triangle Rasterization Rules和Multisample Anti-Aliasing,支持共享边、样本覆盖和2×2导数执行说明。
- 透视插值数值例由本页公式及CPU模型独立复算。