3D 广告牌精灵背后的数学原理是什么?(原为:3D 变换矩阵到 2D 矩阵) [英] What are the maths behind 3D billboard sprites? (was: 3D transformation matrix to 2D matrix)
问题描述
我在空间中有一个 3D 点.点的确切方向/位置通过 4x4 变换矩阵表示.
I have a 3D point in space. The point's exact orientation/position is expressed through a 4x4 transformation matrix.
我想画一个广告牌(3D Sprite)这点.我知道该点的投影位置(即 3D->2D);广告牌正对着相机,所以这也很有帮助.我不知道广告牌应该具有的缩放比例!
I want to draw a billboard (3D Sprite) to this point. I know the projected position (i.e. 3D->2D) of the point; the billboard is facing the camera so that's very helpful too. What I don't know is the scaling that the billboard should have!
为了让事情变得更复杂,4x4 矩阵可能有各种变换:3D 旋转、3D 缩放、3D 转置.假设相机尽可能简单:定位在 (0,0,0),不旋转.
To make things more complex, the 4x4 matrix may have all sorts of transformations: 3D rotation, 3D scaling, 3D transposition. Assume that the camera is as simple as it can be: position at (0,0,0), no rotation.
那么,我可以从这个 4x4 矩阵中提取"广告牌精灵的缩放比例吗?
So, can I "extract" the scaling of the billboard sprite from this 4x4 matrix?
我有一个 3D 仿射变换 4x4 矩阵.我需要将它(项目)转换为 2D 仿射变换 3x3 矩阵,如下所示:
I have a 3D affine transformation 4x4 matrix. I need to convert it (project) to a 2D affine transformation 3x3 matrix, which looks like this:
3D 旋转是无关紧要的,如果存在可能会被丢弃;我只对翻译感兴趣,最重要的是缩放.
3D rotations are irrelevant and if present may be discarded; I am only interested in translation and most importantly scaling.
谁能帮忙算出6 4 个值中每一个的方程式?(假设 tx, ty 也是已知的)
Can anyone help with the equations for each of the six 4 values? (lets say tx, ty are also known)
附加信息:
Matrix3D 是 3D 点的全局变换,例如 (0,0,0).其目的是投影到二维平面(计算机屏幕)上.
The Matrix3D is the global transformation of a 3D point, say (0,0,0). Its purpose is to be projected on a 2D plane (the computer screen).
我知道如何将 3D 点投影到 2D 空间,我正在寻找的是保留位置以外的附加变换信息,即 缩放:如您所知,缩放 在 2D 平面上投影点时,属性也会改变.
I know how to project a 3D point to 2D space, what I am looking for is to preserve additional transformation information beyond position, i.e. scaling: as you may know, the scaling property is also altered when projecting the point on a 2D plane.
我还忘了提到透视投影属性也是已知的,即:
I also forgot to mention that the perspective projection properties are also known, i.e.:
field of view (single value)
focal length (single value)
projection center (viewpoint position - 2D value)
推荐答案
如果你不使用球坐标系,那么这个任务是不可解决的,因为在投影前丢弃 Z 坐标会移除与投影点的距离,因此你不会知道如何应用透视.
if you not using spherical coordinate system then this task is not solvable because discarding Z-coordinate before projection will remove the distance form the projection point and therefore you do not know how to apply perspective.
你有两个选择(除非我忽略了什么):
You have two choices (unless I overlooked something):
应用 3D 变换矩阵
然后只使用 x,y - 结果的坐标
and then use only x,y - coordinates of the result
为旋转/投影创建 3x3 变换矩阵
并在应用它之前或之后添加偏移向量.请注意,这种方法不使用齐次坐标!!!
and add offset vector before or after applying it. Be aware that this approach do not use homogenous coordinates !!!
等式以求清晰
不要忘记 3x3
矩阵 + 向量变换不是累积的!!!这就是使用 4x4
转换的原因.现在你可以扔掉最后一行矩阵/向量 (Xz,Yz,Zz), (z0)
然后输出向量就是 (x', y')
.当然在这之后你不能使用逆变换,因为你失去了 Z 坐标.
Do not forget that 3x3
matrix + vector transforms are not cumulative !!! That is the reason why 4x4
transforms are used instead. Now you can throw away the last row of matrix/vector (Xz,Yz,Zz), (z0)
and then the output vector is just (x', y')
. Of course after this you cannot use the inverse transform because you lost Z coordinate.
缩放是通过改变轴方向向量的大小来完成的
顺便说一句.如果您的投影平面也是 XY
-没有旋转的平面,则:
Btw. if your projection plane is also XY
-plane without rotations then:
x' = (x-x0)*d/(z-z0)
y' = (y-y0)*d/(z-z0)
(x,y,z)
- 指向项目(x',y')
- 投影点(x0,y0,z0)
- 投影原点d
- 焦距
(x,y,z)
- point to project
(x',y')
- projected point
(x0,y0,z0)
- projection origin
d
- focal length
[Edit2] 问题编辑后意义完全不同
我假设您希望精灵始终面向相机.它很丑,但简化了草,树,...
I assume you want sprite always facing camera. It is ugly but simplifies things like grass,trees,...
M
- 你的矩阵P
- M
内的投影矩阵
如果你的 M = (0,0,0)
原点没有旋转/缩放/倾斜,那么 M=P
pnt
- 你的广告牌的点(我假设为中心)(w=1
)[GCS]
dx,dy
- 一半大小的广告牌 [LCS]
A,B,C,D
- 广告牌的投影边缘 [GCS]
[GCS]
- 全局坐标系[LCS]
- 局部坐标系
M
- your matrix
P
- projection matrix inside M
If you have origin of M = (0,0,0)
without rotations/scaling/skew then M=P
pnt
- point of your billboard (center I assume) (w=1
) [GCS]
dx,dy
- half sizes of billboard [LCS]
A,B,C,D
- projected edges of your billboard [GCS]
[GCS]
- global coordinate system
[LCS]
- local coordinate system
如果你知道投影矩阵
我假设它是 glFrustrum 或 gluPerspective ...然后:
I assume it is glFrustrum or gluPerspective ... then:
(x,y,z,w)=(M*(P^-1))*pnt // transformed center of billboard without projection
A=P*(x-dx,y-dy,z,w)
B=P*(x-dx,y+dy,z,w)
C=P*(x+dx,y+dy,z,w)
D=P*(x+dx,y-dy,z,w)
如果您的 M
矩阵太复杂,#1 无法工作
If your M
matrix is too complex for #1 to work
MM=(M*(P^-1)) // transform matrix without projection
XX=MM(Xx,Xy,Xz) // X - axis vector from MM [GCS](look at the image above on the right for positions inside matrix)
YY=MM(Yx,Yy,Yz) // Y - axis vector from MM [GCS]
X =(M^-1)*XX*dx // X - axis vector from MM [LCS] scaled to dx
Y =(M^-1)*YY*dy // Y - axis vector from MM [LCS] scaled to dy
A = M*(pnt-X-Y)
B = M*(pnt-X+Y)
C = M*(pnt+X+Y)
D = M*(pnt+X-Y)
[Edit3] 仅缩放
MM=(M*(P^-1)) // transform matrix without projection
sx=|MM(Xx,Xy,Xz)| // size of X - axis vector from MM [GCS] = scale x
sy=|MM(Yx,Yy,Yz)| // size of Y - axis vector from MM [GCS] = scale y
这篇关于3D 广告牌精灵背后的数学原理是什么?(原为:3D 变换矩阵到 2D 矩阵)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!