openGL 第八篇:坐标系统一 =》基础知识点

坐标系统(Coordinate Systems

知识点:

  • 局部空间(Local Space): 一个物体的初始空间。所有的坐标都是相对于物体的原点的。
  • 世界空间(World Space): 所有的坐标都相对于全局原点。
  • 观察空间(View Space): 所有的坐标都是从摄像机的视角观察的。
  • 裁剪空间(Clip Space): 所有的坐标都是从摄像机视角观察的,但是该空间应用了投影。这个空间应该是一个顶点坐标最终的空间,作为顶点着色器的输出。OpenGL负责处理剩下的事情(裁剪/透视除法)。
  • 屏幕空间(Screen Space): 所有的坐标都由屏幕视角来观察。坐标的范围是从0到屏幕的宽/高。

第一:概念

坐标转换过程: 局部坐标  =》 世界坐标=》观察坐标=》裁剪坐标=》屏幕坐标

coordinate_systems

1)透视除法(perspective division)

        将位置向量x、y、z分量分别除以向量的齐次w分量将4D裁剪空间坐标变换为3D标准化设备坐标。

2)标准化设备坐标:

        范围【-1,1】,裁剪空间坐标之后,经过透视除法,在裁剪空间中的坐标取值范围将会全部在【-1,1】之间。

3)视口变换:

        将裁剪空间坐标转换成屏幕坐标的过程,称之为视口变换。作用是将标准化设备坐标即(-1,1)中的坐标 变换到 由 glViewport 函数定义的坐标范围内。

第二:坐标系的转换

局部坐标转换成世界坐标由 模型矩阵(model Matirx) 实现。=》转换到世界空间

世界坐标转换成观察坐标由 观察矩阵(view Matrix)实现。=》转换到观察空间

观察坐标转换成裁剪坐标投影矩阵(projection Matrix)实现。=》转换到裁剪空间

第三:投影矩阵  有两种

1)正射投影

orthographic projection frustum

1,特点:

        由宽、高、近平面(near plane)、远平面(far plane)组成。任何不在近平面与远平面之间的坐标都会被裁剪掉即不会显示在屏幕上。

 2,使用

glm::ortho(0.0f, 800.0f, 0.0f, 600.0f, 0.1f, 100.0f);

第一、第二参数:左右坐标。

第三、第四个参数:底部和顶部参数

第五个参数:摄像机到近平面的距离

第六个参数:摄像机到远平面的距离

2)透视投影(可借助unity、cocos3D中的camera来增强理解)

perspective_frustum

 1,特点

      由视角(fov)、宽高比、近平面(near plane)、远平面(far plane)组成。任何不在近平面与远平面之间的坐标都会裁剪掉即不会显示在屏幕上。

2,使用

glm::mat4 proj = glm::perspective(glm::radians(45.0f), (float)width/(float)height, 0.1f, 100.0f);

第一个参数:视角  =》视角越大,近平面到摄像机越近,甚至在摄像机背后

第二个参数:宽高比

第三个参数:摄像机到近平面的距离

第四个参数:摄像机到远平面的距离

3)总结归纳

        投影矩阵是把观察空间坐标转换成裁剪空间坐标,完成之后,再通过透视除法(perspective division)即将位置向量x、y、z分量分别除以向量的齐次w分量将4D裁剪空间坐标变换为3D标准化设备坐标。然后将得到的裁剪空间坐标转换成屏幕坐标中,再进行光栅化,拆分成片段。

        裁剪空间坐标转换成屏幕坐标的过程 我们称之为  视口变换

        视口变换:将标准化设备坐标即(-1,1)中的坐标 变换到 由 glViewport 函数定义的坐标范围内。

总结转换过程:

最总组合在一起:顶点坐标 x  模型矩阵 x 观察矩阵 x 投影矩阵  =  裁剪坐标。最后openGL会自动进行 透视除法和裁剪,转成屏幕坐标,并被变换成片段。

第四:应用

/*******  模型矩阵  **********/
/*
 模型矩阵创建, 绕着x轴旋转 45°  =》 结果  坐标转换成世界坐标
 */
glm::mat4 model         = glm::mat4(1.0f);
model = glm::rotate(model, glm::radians(0.0f), glm::vec3(1.0f, 0.0f, .0f));
unsigned int modelLoc = glGetUniformLocation(ourShader.ID, "model");
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));

/******   观察矩阵   *******/
/**
 观察矩阵,观察物沿着z轴后移 -3  相当于摄像机退 -3 =》结果  观察者视野(摄像机视野)中
 */
glm::mat4 view          = glm::mat4(1.0f);
view  = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f));
unsigned int viewLoc  = glGetUniformLocation(ourShader.ID, "view");
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, &view[0][0]);
/******   投影矩阵    ******/
glm::mat4 projection    = glm::mat4(1.0f);
//投影矩阵 =》 裁剪掉不要的事物  结果  裁剪裁剪空间 真正呈现再屏幕上的事物
//第一个参数  视角   (视角太小 物体很小,视角太大物体越大直至再摄像头背面)
//第二参数 窗口的宽高比   第三个参数 近平面到摄像机的距离  第四个参数远平面到摄像头的距离
projection = glm::perspective(glm::radians(45.0f), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
ourShader.setMatrix4("projection",projection);

第五:注意事项

1)模型矩阵、观察矩阵、透视矩阵 所操作的都是顶点位置坐标数据

2)上述组合是从右向左读取,需先进行模型转换、再进行观察空间转换、最后进行透视转换

第六:个人总结归纳

1)转换理解

       顶点数据中的坐标都是相对于物体的坐标(局部空间坐标),根据特定需求我们需要先转换成世界坐标。然后因为屏幕像眼睛(摄像机)一样观察到的紧紧是世界中的一部分,这时为了方便操作和运算我们需要将其转换成观察空间坐标中,同时我们屏幕仅能展示世界的一部分,这时我们需要去掉在可见范围外的坐标,即裁剪掉不要的坐标,可通过投影矩阵实现。进而得到裁剪后的坐标,称之为裁剪空间坐标。最后openGL会自动进行 透视除法操作,把每个位置向量的x、y、z分量进行除以w分量,也就是将4D坐标分量转换成3D的标准坐标,此时数值的范围全部在【-1,1】中。最后得到坐标会映射到屏幕坐标(此时的屏幕坐标是根据glViewport中设定的参数)中,再进行光栅化,被变换成片段。

        需要注意的是正射投影其实也进行了透视除法,只是w分量等于1。

(文章:顶点着色器的输出要求所有的顶点都在裁剪空间内,这正是我们刚才使用变换矩阵所做的。OpenGL然后对裁剪坐标执行透视除法从而将它们变换到标准化设备坐标。OpenGL会使用glViewPort内部的参数来将标准化设备坐标映射到屏幕坐标,每个坐标都关联了一个屏幕上的点(在我们的例子中是一个800x600的屏幕)。这个过程称为视口变换)

2)新的想法

        每个纹理对应的映射位置坐标范围,gl_position 是可以通过matrix 进行改变的,从而可以实现缩放、位移、旋转等。

        而纹理的过滤,环绕等,是相对于纹理坐标而言的、、、、

3)个人疑问

        Q1)为什么要将物体的坐标经过多次坐标系的转换?为何不直接转换?多次转换是不是有点多余?

        A:将物体的坐标进行多次过渡转换,是因为在这些特定的坐标系中,有些操作或者运算会更加的方便和容易。

        Q2)为什么除以w分量就能把大空间的坐标直接转换到屏幕坐标中呢?这个是否与多级渐远有关联呢?因为多级渐远处理的就是少量片段显示大纹理。

        Q3)glViewPort 设置的参数  是否会与 ortho(正射投影)  有冲突呢?

        Q4)操作后发现,顶点坐标即位置坐标 的操作,与纹理坐标的操作 有什么区别呢?在这里操作的是位置坐标。可以进行缩放、位移、旋转等。 对纹理坐标的操作是否也可以实现缩放、位移、旋转? 它们又有什么区别呢?

        Q5)cocos中节点的大小、位置、旋转角度、锚点、颜色、透明度等信息  与 openGL 这里的那些信息有关,对应着那些操作呢?

上一篇:openGL 第七篇 :变换 (Transformations)

下一篇:openGL 第九篇:坐标系统二 =》 应用纹理旋转

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值