Unity TAA Jittering公式推导

        关于Jittering的公式,很多地方只是大概提了一下公式,这是Unity中的实现,使用的公式是:

matrix[0, 2] += offset.x * 2 / horizontal;
matrix[1, 2] += offset.y * 2 / vertical;

        具体参考代码(话说这函数定义horizontal,vertical意义不明,可能是为了提高计算精度?)

public static Matrix4x4 GetJitteredPerspectiveProjectionMatrix(Camera camera, Vector2 offset)
{
    float near = camera.nearClipPlane;
    float far = camera.farClipPlane;

    float vertical = Mathf.Tan(0.5f * Mathf.Deg2Rad * camera.fieldOfView) * near;
    float horizontal = vertical * camera.aspect;

    offset.x *= horizontal / (0.5f * camera.pixelWidth);
    offset.y *= vertical / (0.5f * camera.pixelHeight);

    var matrix = camera.projectionMatrix;

    matrix[0, 2] += offset.x / horizontal;
    matrix[1, 2] += offset.y / vertical;

    return matrix;
}

        现在来分析一下原理:

        先不管Jitter的数值是多少,我们把Jitter带入到投影矩阵中

\begin{pmatrix} \frac{n}{r} & 0 & Jitter_{x} & 0\\ 0 & \frac{n}{t} & Jitter_{y} & 0\\ 0 & 0 & -\frac{f+n}{f-n} & -\frac{2fn}{f-n}\\ 0 & 0 & -1 & 0\\ \end{pmatrix}

        然后计算clip space坐标的差值  

        {P_{clip}}' = {}{M_{proj}}'* P_{view} = P_{clip}+ \begin{pmatrix} Jitter_{x} * Z_{view}\\ Jitter_{y} * Z_{view}\\ 0\\ 0 \end{pmatrix}

        因为坐标值只涉及到xy的修改,所以后面都只看xy,下一步是到NDC空间

        {P_{ndc}}' = {\frac{P_{clip}}{w}}'= \frac{​{P_{clip}'}}{-Z_{view}} = P_{ndc} + \frac{Jitter_{xy} * Z_{view}}{-Z_{view}} = P_{ndc} - Jitter_{xy}

        以及屏幕空间

{P_{screen}}' = \frac{​{P_{ndc}}' + 1}{2} = P_{screen} - \frac{Jitter_{xy}}{2}

        现在把最初的Jitter数值带入进去

Jitter_{xy} = \frac{2*Offset_{xy}}{Resolution}

        得到最终的差异:

 {P_{screen}}' = P_{screen} - \frac{Offset_{xy}}{Resolution}

        其中Offset的xy介于[-0.5, 0.5]之间,到这一步作用已经很明显了,1除以屏幕分辨率得到的是每个像素的长宽,乘以Offset代表偏移的长度,表示往像素在水平和垂直分别偏移最多0.5个像素。

        在很多实现当中,比如https://zhuanlan.zhihu.com/p/138866533,会使用这样的公式

var jitteredProjection = camera.projectionMatrix;
jitteredProjection.m02 += (offset.x * 2 - 1) / camera.pixelWidth;
jitteredProjection.m12 += (offset.x * 2 - 1) / camera.pixelHeight;

        区别只是这里的分母多减了1,结果变成了

{P_{screen}}' = P_{screen} + \frac{0.5 - Offset_{xy}}{Resolution}

        实际上没有区别,只是这里Offset值域不一样,这里的是[0, 1]

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值