LearnOpenGL - Coordinate Systems
openGL中使用右手坐标系(大拇指指向正x轴方向,食指指向正y轴方向,中指指向正z轴方向)
每个顶点的x,y,z坐标都应该在-1.0到1.0之间,超出这个坐标范围的顶点都将不可见
将坐标变换为标准化设备坐标,接着再转化为屏幕坐标的过程通常是分步进行的
-
局部空间(Local Space,或者称为物体空间(Object Space))
-
世界空间(World Space)
-
观察空间(View Space,或者称为视觉空间(Eye Space))
-
裁剪空间(Clip Space)
-
屏幕空间(Screen Space)
这就是一个顶点在最终被转化为片段之前需要经历的所有不同状态。
模型矩阵是一种变换矩阵,它能通过对物体进行位移、缩放、旋转来将它置于它本应该在的位置或朝向。
观察矩阵(或者说叫做场景移动矩阵?因为本质是对物体做移动)将世界坐标变换到观察空间
将摄像机向后移动,和将整个场景向前移动是一样的,即摄像机往Z的正向移动10,相当于场景(物体)往Z的负方向移动10,即
view = glm::translate(view, glm::vec3(-10.0f, -10.0f, -10.0f));
//实际场景中的x往左移动10,y往下移动10,Z往里面移动10
//或者摄像机x往右移动10,y往上移动10,Z往外面移动10
投影矩阵包括正交投影和透视投影
正交投影近处和远处的物体大小是一样的
要创建一个正射投影矩阵,我们可以使用GLM的内置函数glm::ortho
:
glm::ortho(0.0f, 800.0f, 0.0f, 600.0f, 0.1f, 100.0f);
前两个参数指定了平截头体的左右坐标,第三和第四参数指定了平截头体的底部和顶部。
通过这四个参数我们定义了*面和远平面的大小,然后第五和第六个参数则定义了*面和远平面的距离。
这个投影矩阵会将处于这些x,y,z值范围内的坐标变换为标准化设备坐标。
透视投影(离你越远的东西看起来更小)
透视的效果在我们看一条无限长的高速公路或铁路时尤其明显,正如下面图片显示的那样:
透视投影矩阵 修改了每个顶点坐标的w值,从而使得离观察者越远的顶点坐标w分量越大。被变换到裁剪空间的坐标都会在-w到w的范围之间(任何大于这个范围的坐标都会被裁剪掉)。
当你把透视矩阵的 *near* 值设置太大时(如10.0f),OpenGL会将靠近摄像机的坐标(在0.0f和10.0f之间)都裁剪掉,这会导致一个你在游戏中很熟悉的视觉效果:在太过靠近一个物体的时候你的视线会直接穿过去。
注意矩阵运算的顺序是相反的(记住我们需要从右往左阅读矩阵的乘法)。最后的顶点应该被赋值到顶点着色器中的gl_Position,OpenGL将会自动进行透视除法和裁剪。
OpenGL存储它的所有深度信息于一个Z缓冲(Z-buffer)中,也被称为深度缓冲,
深度值存储在每个片段里面(作为片段的z值),当片段想要输出它的颜色时,
OpenGL会将它的深度值和z缓冲进行比较,如果当前的片段在其它片段之后,它将会被丢弃,否则将会覆盖。
这个过程称为深度测试(Depth Testing),它是由OpenGL自动完成的。
glEnable(GL_DEPTH_TEST);//开启深度测试
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //每一帧都要清除-颜色缓冲和深度缓冲
以下是绘制10个立方体的效果图