zoukankan      html  css  js  c++  java
  • Opengl和D3D画面左右颠倒的推导

      这些天状态很差,没什么力气,只能写些无聊的证明这里很简单的证明Ogl和D3D所画图像左右颠倒的原因

    假设目前摄像机方向向量为V, 摄像机的Up向量为U。摄像机的位置为P

    Opengl中的视矩阵计算

    由于Opengl是右手坐标系,

    视坐标系的Z轴向量被定义为-V, 定义为N

    Y轴定义为U

    X = Y X ZX是叉积)定义为R

     

    那么视距阵为

    Rx  Ry Vz   -dot(R, P)

    Ux  Uy Uz  -dot(U, P)

    Nx  Ny Nz  -dot(N, P)

    0   0   0    1

     

    看下Direct3D下左手坐标系的视矩阵

    视坐标系的Z轴向量被定义为V, 定义为N’

    Y轴定义为U’

    X = Y X ZX是叉积)定义为R’

    显然 N’ = -N

         U’ = U

         R’ = U’ X N’ = U X (-N) = -R

    那么D3D中的视矩阵是

    -Rx  -Ry  -Vz    dot(R, P)

    Ux   Uy  Uz    -dot(U, P)

    -Nx  -Ny  -Nz    dot(N, P)

    0    0    0      1

    这里没有把D3D写成左乘矩阵的形式,而和Opengl一样写成了右乘形式。

     

    接下来看对于世界坐标系中点(X ,Y ,Z):

    Opengl把它变换到视坐标系中以后是(Xv ,Yv ,Zv

    D3D变换后(Xv’ ,Yv ‘,Zv’

    通过上面的2个矩阵容易看出(Xv’ ,Yv ‘,Zv’ = -Xv ,Yv ,-Zv

    这里可以看出 在视坐标系中X Z已经发生了颠倒,接着看2种坐标系下的投影   矩阵

    Opengl

    2n/W 0     0       0

     0  2n/H    0       0

     0   0   -(n+f)/(f-n)  -2nf/(f-n)

     0   0  -1          0

     

    D3D:

    2n/W 0     0       0

     0  2n/H    0       0

     0   0    f/(f-n)    -nf/(f-n)

     0   0    1        0

    再将视点坐标系中的点通过上述投影变换以后很容易就看出在最终的齐次坐标系中D3D中的点(Xy)在Opengl那边得到的是(-X y)当然Z也不同因为上述投影矩阵中OpenglZClamp到了(-11D3DClamp到了(01)但是屏幕上的点最终是一个(XY)的2D的点因此 由于X的正负颠倒所以在屏幕上最终是左右颠倒的

    最后说一句脱离了左右手坐标系和坐标原点去谈论一个点的坐标是毫无意义的因为即使2个点的坐标数值相同,在不同的坐标系中他们也代表了不同的空间位置!

  • 相关阅读:
    android截屏
    生产者消费者 ProducerConsumer
    实现RunOnUiThread和RunOnUiThreadBlock
    快速断网恢复方法
    JFrame2
    JFrame
    圆角矩形shader
    [转]Apache commons 工具包应用
    转载 [Java]读取文件方法大全
    转:aop的学习
  • 原文地址:https://www.cnblogs.com/fishboy82/p/1319417.html
Copyright © 2011-2022 走看看