OpenGL ES 视图变换讲解

学习opengl必须搞懂视图变换

坐标变换的全局图

OpenGL中的坐标处理过程包括模型变换、视变换、投影变换、视口变换等过程,如下图所示: 


在上面的图中,注意,OpenGL只定义了裁剪坐标系、规范化设备坐标系和屏幕坐标系,而局部坐标系(模型坐标系)、世界坐标系和照相机坐标系都是为了方便用户设计而自定义的坐标系,它们的关系如下图所示(来自Chapter 7. World in Motion):


图中左边的过程包括模型变换、视变换,投影变换,这些变换可以由用户根据需要自行指定,这些内容在顶点着色器中完成;而图中右边的两个步骤,包括透视除法、视口变换,这两个步骤是OpenGL自动执行的,在顶点着色器处理后的阶段完成。


模型变换——从模型坐标系到世界坐标系

局部坐标系(模型坐标系)是为了方便构造模型而设立的坐标系,建立模型时我们无需关心最终对象显示在屏幕哪个位置。模型的原点定位也可以有所不同,例如下面在模型坐标系定义的模型: 


局部坐标系可以理解,就是自身所有顶点之间的关系。 

模型变换的主要目的是通过变换使得用顶点属性定义或者3d建模软件构造的模型,能够按照需要,通过缩小、平移等操作放置到场景中合适的位置。通过模型变换后,物体放置在一个全局的世界坐标系中,世界坐标系是所有物体交互的一个公共坐标系。

例如下面的图中在模型坐标系定义的茶壶模型(来自World, View and Projection Transformation Matrices):


茶壶通过模型变换,转换到世界坐标系中(来自World, View and Projection Transformation Matrices):

模型变换包括:旋转、平移、缩放、错切等内容。

例如将物体从一个位置p=(x,y,z),移动到另一个位置p′=(x′,y′,z′)的过程,用矩阵表示为: 

应用多个模型变换时,注意变换执行的顺序影响变换的结果,一般按照缩放–》旋转—》平移的顺序执行;

其实这里的这个矩阵T代表这局部坐标系放在世界坐标系原点进行T变换,比如变换,平移,缩放。

视变换——从世界坐标系到相机坐标系

视变换是为了方便观察场景中物体而设立的坐标系,在这个坐标系中相机是个假想的概念,是为了便于计算而引入的。相机坐标系中的坐标,就是从相机的角度来解释世界坐标系中位置。相机和场景的示意图如下所示(来自World, View and Projection Transformation Matrices):


OpenGL中相机始终位于原点,指向-Z轴,而以相反的方式来调整场景中物体,从而达到相同的观察效果。

打个比方,把相机放入世界坐标系原点,朝向始终x轴,放一个立方体 在z轴的正上方。怎么才能看到这个立方体呢?两种方式

1. 立方体不动,让相机绕y轴逆时针旋转90度。看到物体

2.相机不动,让立方体绕着y轴顺时针旋转90度,立方体现在在x轴上了。看到物体

OpenGL中采用方式2的观点来解释视变换。

通过在世界坐标系中指定相机的位置,指向的目标位置,以及viewUp向量来构造一个相机坐标系,通过视变换矩阵将物体坐标由世界坐标系转换到相机坐标系。

单纯知道一个位置是没办法确定相机不动的。(相机可以旋转),所以,我们需要规定一个相机的位置和看的方向。

知道相机的位置和方向还不够,因为相机可以旋转,看到的物体还是不一样的。因此,我们还需要知道相机正视图的法量方向。只有这样才能确定相机不会动弹


GLK_INLINE GLKMatrix4 GLKMatrix4MakeLookAt(float eyeX, float eyeY, float eyeZ,

                                                  float centerX, float centerY, float centerZ,

                                                  float upX, float upY, float upZ)

{

    GLKVector3 ev = { eyeX, eyeY, eyeZ };

    GLKVector3 cv = { centerX, centerY, centerZ };

    GLKVector3 uv = { upX, upY, upZ };

    GLKVector3 n = GLKVector3Normalize(GLKVector3Add(ev, GLKVector3Negate(cv)));

    GLKVector3 u = GLKVector3Normalize(GLKVector3CrossProduct(uv, n));

    GLKVector3 v = GLKVector3CrossProduct(n, u);


    GLKMatrix4 m = { u.v[0], v.v[0], n.v[0], 0.0f,

                    u.v[1], v.v[1], n.v[1], 0.0f,

                    u.v[2], v.v[2], n.v[2], 0.0f,

                    GLKVector3DotProduct(GLKVector3Negate(u), ev),

                    GLKVector3DotProduct(GLKVector3Negate(v), ev),

                    GLKVector3DotProduct(GLKVector3Negate(n), ev),

                    1.0f };

    return m;

}

因此求视图的相机位置是有九个参数的,上面就是公式。

投影变换——从世界坐标系到裁剪坐标系

投影方式决定以何种方式成像,投影方式有很多种,OpenGL中主要使用两种方式,即透视投影(perspective projection)和正交投影( orthographic projection)。

1.正交投影是平行投影的一种特殊情形,正交投影的投影线垂直于观察平面。平行投影的投影线相互平行,投影的结果与原物体的大小相等,因此广泛地应用于工程制图等方面。 

2.透视投影的投影线相交于一点,因此投影的结果与原物体的实际大小并不一致,而是会近大远小。因此透视投影更接近于真实世界的投影方式。


示意图




上面的图中,红色和黄色球在视见体内,因而呈现在投影平面上,而绿色球在视见体外,没有在投影平面上成像。指定视见体通过(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble nearVal, GLdouble farVal)6个参数来指定。注意在相机坐标系下,相机指向-z轴,nearVal和farVal表示的剪裁平面分别为:近裁剪平面z=−nearVal,以及远裁剪平面z=−farVal。

怎么计算模型坐标系在视图坐标系的坐标呢?他们之间的唯一关系都是和世界坐标系想关联。世界坐标系其实就是个中间坐标系,方便这两个坐标系之间的相互转换。

其实很简单的,就是将相机和模型看做一个物体,把相机在世界坐标系的位置移动到世界坐标系原点,并且xyz和世界坐标系重叠,物体的世界坐标系就是相对于相机的坐标系。

假设M1 是世界坐标系原点, 相机相对世界坐标系的位置为M0, 那么将相机移动到坐标原点 的矩阵是T1,

M1=T1M0;  

物体在世界坐标系S1; 那么物体和相机作为一个整体移动T1, 那么物体的位置就是T1S1。

假设物体的模型坐标系是S0, 物体的模型坐标系到世界坐标系的转换矩阵是T2, 那么S1 = T2S0;

所以物体的模型坐标系相对于相机的坐标系的关系就是M1 = T1T2S0;

相机坐标系到投影坐标系的关系假设是 K1=T3M1;

因此投影坐标系的结果就是K1=T1T2T3S0;

之后的转换都是计算机内部计算了。水平有限不做介绍


参考文章

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343

推荐阅读更多精彩内容