Unity中Shader裁剪空间推导(透视相机到裁剪空间的转化矩阵)

发布时间:2023年12月29日


前言

我们把顶点坐标信息转化为裁剪空间。有可能使用到正交相机信息 或 透视相机。我们在这篇文章中,推导一下透视相机视图空间下的坐标转化到裁剪空间的矩阵。

在这里插入图片描述


一、简单看一下 观察空间—>裁剪空间—>屏幕空间 的转化

在这里插入图片描述

1、观察空间(右手坐标系、透视相机)

在这里插入图片描述

2、裁剪空间(左手坐标系、且转化为了齐次坐标)

在这里插入图片描述

3、屏幕空间(把裁剪坐标归一化设置)

在这里插入图片描述

4、从观察空间到裁剪空间

用透视投影矩阵先转化到裁剪空间
然后,在转化为齐次坐标

5、从裁剪空间到屏幕空间后

? 1 ≤ x c w ≤ 1 -1 \leq \frac{x_c}{w}\leq1 ?1wxc??1

? w ≤ x c ≤ w -w \leq x_c\leq w ?wxc?w


二、透视相机的参数推导

在这里插入图片描述

  • 我们对于远裁剪面只是已知 f,其他参数都是未知

1、从XoY平面,求出Xv从观察空间到裁剪空间的坐标投影 Xp

在这里插入图片描述

  • 点 V 是观察空间下的模型顶点,xyz是已知的
    已知: ( x v , y v , z v ) 、 ? n (x_v,y_v,z_v) 、 -n (xv?,yv?,zv?)?n
  • 点P是该点在近裁剪面上的投影点,xyz是未知的
    未知: ( x p , y p , z p ) (x_p,y_p,z_p) (xp?,yp?,zp?)
  • 我们在 XoZ平面上,能求的就是 xp
    求: x p x_p xp?

z p = ? n z_p = -n zp?=?n

y p 在 X o Z 平面下,无法计算 y_p 在XoZ平面下,无法计算 yp?XoZ平面下,无法计算

  • v点向Z轴做垂线,原点连接v点,围成的两个三角形相似,可得:

x p x v = ? n z v \frac{x_p}{x_v} = \frac{-n}{z_v} xv?xp??=zv??n?

x p = ? n z v x v x_p = \frac{-n}{z_v} x_v xp?=zv??n?xv?

P = ( ? n z v x v , 未知 , ? n ) P = (\frac{-n}{z_v}x_v,未知,-n) P=(zv??n?xv?,未知,?n)

2、从YoZ平面,求出Yv从观察空间到裁剪空间的坐标投影 Yp

在这里插入图片描述

  • 点 V 是观察空间下的模型顶点,xyz是已知的
    已知: ( x v , y v , z v ) 、 ? n (x_v,y_v,z_v) 、 -n (xv?,yv?,zv?)?n
  • 点P是该点在近裁剪面上的投影点,xyz是未知的
    未知: ( x p , y p , z p ) (x_p,y_p,z_p) (xp?,yp?,zp?)
  • 我们在 YoZ平面上,能求的就是 yp
    求: y p y_p yp?

z p = ? n z_p = -n zp?=?n

x p 在 X o Z 平面下,无法计算 x_p 在XoZ平面下,无法计算 xp?XoZ平面下,无法计算

  • v点向Z轴做垂线,原点连接v点,围成的两个三角形相似,可得:

y p y v = ? n z v \frac{y_p}{y_v} = \frac{-n}{z_v} yv?yp??=zv??n?

y p = ? n z v y v y_p = \frac{-n}{z_v} y_v yp?=zv??n?yv?

P = ( ? n z v x v , ? n z v y v , ? n ) P = (\frac{-n}{z_v}x_v,\frac{-n}{z_v} y_v,-n) P=(zv??n?xv?,zv??n?yv?,?n)


三、把投影到近裁剪面的坐标 归一化设置

P = ( ? n z v x v , ? n z v y v , ? n ) P = (\frac{-n}{z_v}x_v,\frac{-n}{z_v} y_v,-n) P=(zv??n?xv?,zv??n?yv?,?n)

化到[-1,1]之间
具体参考Unity中Shader裁剪空间推导(正交相机到裁剪空间的转化矩阵)

1、求归一化设置后的 xn

  • l ≤ x ≤ r l \leq x \leq r lxr 化为: ? 1 ≤ 2 x w ≤ 1 -1 \leq \frac{2x}{w} \leq 1 ?1w2x?1

? 1 ≤ ? 2 n x v z v w ≤ 1 -1\leq \frac{-2nx_v}{z_vw}\leq 1 ?1zv?w?2nxv??1

? 1 ≤ ? 2 n w ? x v z v ≤ 1 -1\leq \frac{-2n}{w}·\frac{x_v}{z_v}\leq 1 ?1w?2n??zv?xv??1

2、求归一化设置后的 yn

  • l ≤ y ≤ r l \leq y \leq r lyr 化为: ? 1 ≤ 2 y h ≤ 1 -1 \leq \frac{2y}{h} \leq 1 ?1h2y?1

? 1 ≤ ? 2 n y v z v h ≤ 1 -1\leq\frac{-2ny_v}{z_vh}\leq1 ?1zv?h?2nyv??1

? 1 ≤ ? 2 n h ? y v z v ≤ 1 -1\leq\frac{-2n}{h}·\frac{y_v}{z_v}\leq1 ?1h?2n??zv?yv??1

3、得到最后化简的公式

由于NDC下的坐标由透视除法而得
我们假设透视除法中的 w 为 -zv
还原到裁剪空间还需要乘以 -zv

  • X:

? 1 ≤ ? 2 n w ? x v z v ≤ 1 -1\leq \frac{-2n}{w}·\frac{x_v}{z_v}\leq 1 ?1w?2n??zv?xv??1

x n = ? 2 n w x v z v x_n = \frac{-2n}{w}\frac{x_v}{z_v} xn?=w?2n?zv?xv??

? x n z v = 2 n w x v -x_nz_v = \frac{2n}{w}x_v ?xn?zv?=w2n?xv?

  • Y:

? 1 ≤ ? 2 n h ? y v z v ≤ 1 -1\leq\frac{-2n}{h}·\frac{y_v}{z_v}\leq1 ?1h?2n??zv?yv??1

y n = ? 2 n h y v z v y_n = \frac{-2n}{h}\frac{y_v}{z_v} yn?=h?2n?zv?yv??

? y n z v = 2 n h y v -y_n z_v= \frac{2n}{h}y_v ?yn?zv?=h2n?yv?

  • Z:

z n = ? z_n = ? zn?=?

? z n z v = ? z v ? -z_nz_v = -z_v? ?zn?zv?=?zv??

  • W:

w = 1 w = 1 w=1

? w n z v = ? z v -w_nz_v = -z_v ?wn?zv?=?zv?


四、构建转化矩阵

裁剪空间下的点 = 观察空间下的基向量 在 裁剪空间下的矩阵 * 点在观察空间下的坐标

P c = [ V c ] ? P v P_c = [V_c]·P_v Pc?=[Vc?]?Pv?

P c = [ C v ] ? 1 ? P v P_c = [C_v]^{-1}·P_v Pc?=[Cv?]?1?Pv?

P c = [ C v ] T ? P v P_c = [C_v]^{T}·P_v Pc?=[Cv?]T?Pv?

  • ? x n z v = 2 n w x v -x_nz_v = \frac{2n}{w}x_v ?xn?zv?=w2n?xv?
  • ? y n z v = 2 n h y v -y_n z_v= \frac{2n}{h}y_v ?yn?zv?=h2n?yv?
  • ? z n z v = ? z v ? -z_nz_v = -z_v? ?zn?zv?=?zv??
  • ? w n z v = ? z v -w_nz_v = -z_v ?wn?zv?=?zv?

[ 2 v w 0 ? ? 0 2 n h ? ? 0 0 ? ? 0 0 ? ? ] T = [ 2 v w 0 0 0 0 2 n h 0 0 ? ? ? ? ? ? ? ? ] \begin{bmatrix} \frac{2v}{w} & 0 & ? &?\\ 0 & \frac{2n}{h} & ? &?\\ 0 & 0 & ? &?\\ 0 & 0 & ? & ?\\ \end{bmatrix}^T =\begin{bmatrix} \frac{2v}{w} & 0 & 0 & 0 \\ 0 & \frac{2n}{h} & 0 &0\\ ? & ? & ? &?\\ ? & ? & ? & ?\\ \end{bmatrix} ?w2v?000?0h2n?00??????????? ?T= ?w2v?0???0h2n????00???00??? ?

[ 2 v w 0 0 0 0 2 n h 0 0 ? ? ? ? ? ? ? ? ] ? [ x v y v z v 1 ] = ( ? x n z v , ? y n z v , ? z n z v , ? w n z v ) \begin{bmatrix} \frac{2v}{w} & 0 & 0 & 0 \\ 0 & \frac{2n}{h} & 0 &0\\ ? & ? & ? &?\\ ? & ? & ? & ?\\ \end{bmatrix} · \begin{bmatrix} x_v\\ y_v\\ z_v\\ 1\\ \end{bmatrix} = (-x_nz_v,-y_nz_v,-z_nz_v,-w_nz_v) ?w2v?0???0h2n????00???00??? ?? ?xv?yv?zv?1? ?=(?xn?zv?,?yn?zv?,?zn?zv?,?wn?zv?)

最后一行由于相乘结果为1可以得出,把最后未知部分设为A,B
[ 2 v w 0 0 0 0 2 n h 0 0 0 0 A B 0 0 ? 1 0 ] ? [ x v y v z v 1 ] \begin{bmatrix} \frac{2v}{w} & 0 & 0 & 0 \\ 0 & \frac{2n}{h} & 0 &0\\ 0 & 0 & A &B\\ 0 & 0 & -1 & 0\\ \end{bmatrix} · \begin{bmatrix} x_v\\ y_v\\ z_v\\ 1\\ \end{bmatrix} ?w2v?000?0h2n?00?00A?1?00B0? ?? ?xv?yv?zv?1? ?

z c = A z v + B z_c = Az_v+B zc?=Azv?+B

? z n z v = ? z v -z_nz_v = -z_v ?zn?zv?=?zv?

z c ? z v = A z v + B ? z v \frac{z_c}{-z_v} = \frac{Az_v+B}{-z_v} ?zv?zc??=?zv?Azv?+B?

z n = A z v + B ? z v z_n = \frac{Az_v+B}{-z_v} zn?=?zv?Azv?+B?

1、在OpenGL[-1,1]下:

z n = A z v + B ? z v z_n = \frac{Az_v+B}{-z_v} zn?=?zv?Azv?+B?

{ z v = ? n , z n = ? 1 z v = ? f , z n = 1 \begin{cases} z_v = -n,z_n=-1 \\ z_v = -f,z_n = 1 \end{cases} {zv?=?n,zn?=?1zv?=?f,zn?=1?

{ ? 1 = ? A n + B n 1 = ? A f + B f \begin{cases} -1 = \frac{-An+B}{n}\\ 1 = \frac{-Af + B}{f} \end{cases} {?1=n?An+B?1=f?Af+B??

{ ? n = ? A n + B f = ? A f + B \begin{cases} -n = -An+B\\ f = -Af + B \end{cases} {?n=?An+Bf=?Af+B?

B = A n ? n B = An - n B=An?n

f = ? A f + A n ? n f = -Af +An-n f=?Af+An?n

f + n = A ( n ? f ) f + n= A(n-f) f+n=A(n?f)

A = n + f n ? f A = \frac{n+f}{n-f} A=n?fn+f?

B = n + f n ? f n ? n B = \frac{n+f}{n-f}n-n B=n?fn+f?n?n

B = n 2 + f n n ? f n 2 ? n f n ? f B = \frac{n^2 + fn}{n-f}\frac{n^2-nf}{n-f} B=n?fn2+fn?n?fn2?nf?

B = 2 n f n ? f B = \frac{2nf}{n-f} B=n?f2nf?

2、在DirectX[1,0]下:

z n = A z v + B ? z v z_n = \frac{Az_v+B}{-z_v} zn?=?zv?Azv?+B?

{ z v = ? n , z n = 1 z v = ? f , z n = 0 \begin{cases} z_v = -n,z_n=1 \\ z_v = -f,z_n = 0 \end{cases} {zv?=?n,zn?=1zv?=?f,zn?=0?

{ 1 = ? A n + B n 0 = ? A f + B f \begin{cases} 1 = \frac{-An+B}{n}\\ 0 = \frac{-Af+B}{f} \end{cases} {1=n?An+B?0=f?Af+B??

{ n = ? A n + B 0 = ? A f + B \begin{cases} n = -An+B\\ 0 = -Af+B \end{cases} {n=?An+B0=?Af+B?

B = A f B = Af B=Af

n = ? A n + A f n = -An+Af n=?An+Af

n = A ( f ? n ) n = A(f-n) n=A(f?n)

A = n f ? n A =\frac{n}{f-n} A=f?nn?

B = n f f ? n B = \frac{nf}{f-n} B=f?nnf?

3、把A、B代入矩阵得

  • OpenGL
    [ 2 v w 0 0 0 0 2 n h 0 0 0 0 n + f n ? f 2 n f n ? f 0 0 ? 1 0 ] \begin{bmatrix} \frac{2v}{w} & 0 & 0 & 0 \\ 0 & \frac{2n}{h} & 0 &0\\ 0 & 0 & \frac{n+f}{n-f} &\frac{2nf}{n-f}\\ 0 & 0 & -1 & 0\\ \end{bmatrix} ?w2v?000?0h2n?00?00n?fn+f??1?00n?f2nf?0? ?
  • DirectX
    [ 2 v w 0 0 0 0 2 n h 0 0 0 0 n f ? n n f f ? n 0 0 ? 1 0 ] \begin{bmatrix} \frac{2v}{w} & 0 & 0 & 0 \\ 0 & \frac{2n}{h} & 0 &0\\ 0 & 0 & \frac{n}{f-n} &\frac{nf}{f-n}\\ 0 & 0 & -1 & 0\\ \end{bmatrix} ?w2v?000?0h2n?00?00f?nn??1?00f?nnf?0? ?
文章来源:https://blog.csdn.net/qq_51603875/article/details/135273329
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。