1. 概述
需要说明的是,球体投影到像素空间的结果可能不是一个正圆,其半径或者直径大小只能估算而没有确定的值。根据参考资料,球体投影到像素空间的半径的计算公式为:
r a d i u s [ c l i p _ s p a c e ] = r a d i u s ∗ c o t ( f o v / 2 ) / Z (0) radius_{[clip\_space]} = radius * cot(fov / 2) / Z \tag{0} radius[clip_space]=radius∗cot(fov/2)/Z(0)
其中radius是球体的半径,fov是摄像机视场角,z是球心到摄像机位置的距离。当然,由于最后得到的是裁剪空间的大小,需要换算到屏幕像素空间。
2. 详论
根据我的理解,这个公式也是近似的。本人通过参考文献得到的推导方式如下所示。
使用参考文章4中的插图:
球体投影到像素空间的半径其实就是h的像素长度。此时,有:
t a n θ = r a d i u s [ c l i p _ s p a c e ] / z [ c l i p _ s p a c e ] (1) tan\theta = radius_{[clip\_space]} / z_{[clip\_space]} \tag{1} tanθ=radius[clip_space]/z[clip_space](1)
球体被投影到裁剪空间:
由投影变换的性质可知:
t a n ( f o v y / 2 ) = 1 / z [ c l i p _ s p a c e ] (2) tan(fovy / 2) = 1 / z_{[clip\_space]} \tag{2} tan(fovy/2)=1/z[clip_space](2)
联立(1)(2)式有,
r
a
d
i
u
s
[
c
l
i
p
_
s
p
a
c
e
]
=
t
a
n
θ
∗
c
o
t
(
f
o
v
y
/
2
)
(3)
radius_{[clip\_space]} = tan\theta * cot(fovy / 2) \tag{3}
radius[clip_space]=tanθ∗cot(fovy/2)(3)
根据世界空间的集合关系,有:
t
a
n
θ
=
r
/
l
(4)
tan\theta = r / l \tag{4}
tanθ=r/l(4)
式(4)带入式(3)中,有:
r
a
d
i
u
s
[
c
l
i
p
_
s
p
a
c
e
]
=
r
∗
c
o
t
(
f
o
v
y
/
2
)
/
l
(5)
radius_{[clip\_space]} = r * cot(fovy / 2) / l \tag{5}
radius[clip_space]=r∗cot(fovy/2)/l(5)
在摄像机距离球心比较远的情况下,可以认为:
l
≈
d
l \approx d
l≈d
也就是式(0)的由来。如果需要计算准确一点,那么:
l
=
d
2
−
r
2
(6)
l = \sqrt{d^2 - r^2} \tag{6}
l=d2−r2(6)
上式带入式(5),就会有:
r
a
d
i
u
s
[
c
l
i
p
_
s
p
a
c
e
]
=
r
∗
c
o
t
(
f
o
v
y
/
2
)
/
d
2
−
r
2
(7)
radius_{[clip\_space]} = r * cot(fovy / 2) / \sqrt{d^2 - r^2} \tag{7}
radius[clip_space]=r∗cot(fovy/2)/d2−r2(7)
最后换算到屏幕像素空间:
r
a
d
i
u
s
[
s
c
r
e
e
n
_
s
p
a
c
e
]
=
r
⋅
c
o
t
(
f
o
v
y
2
)
⋅
h
e
i
g
h
t
2
d
2
−
r
2
(8)
radius_{[screen\_space]} = \frac{r \cdot cot(\frac{fovy}{2}) \cdot height} {2\sqrt{d^2 - r^2}} \tag{8}
radius[screen_space]=2d2−r2r⋅cot(2fovy)⋅height(8)