平移变换
齐次坐标中,第四个分量为1,表示坐标点;第四个分量为0,表示向量;
源码详解
|
|
定义4维矩阵;
用此handle来获取shader中的“世界”平移变换矩阵一致变量的引用;
设置物体在x轴上-1到1之间来回滑动;
使用glUniform*函数将数据加载到shader一致变量中,第一个参数是一致变量的位置(在shader编译后使用glGetUniformLocation()获取);第二个参数是要更新的矩阵的个数;第三个参数指行优先还是列优先;第四个参数表示内存中矩阵的起始地址;
OpenGL是列主序的,故使用GLM记录矩阵时,由于GLM使用列主序,因此需要设置为GL_FALSE;
定义了一个4x4的矩阵一致变量;由于顶点缓冲区中三角形的顶点位置是一些3维的向量,故需要在顶点着色器中添加第四个分量;
旋转变换
绕z轴逆时针旋转矩阵计算:
绕y轴逆时针旋转矩阵计算:
绕x轴逆时针旋转矩阵计算:
复合变换
这里借助GLM库对矩阵进行存储;
需要的GLM的大多数功能都可以在下面三个头文件中找到;
将单位矩阵和位移向量传递给glm::translate函数来构造平移矩阵;
将物体沿每个轴缩放到0.5倍,再沿z轴旋转90度,GLM希望它的角度是弧度制的,故使用glm::radians将角度转化为弧度;由于将矩阵传递给了GLM的每一个函数,GLM会自动将矩阵相乘,返回结果是一个包括了多个变换的变换矩阵。
插值
光栅器在三角形的三个顶点之间进行插值,并执行片段着色器遍历三角形的每一个像素。片段着色器会返回光栅器存在颜色缓存中用于显示的像素颜色值。如果片段着色器没有显式请求顶点着色器春过来的其他变量,则一般的驱动优化会丢弃顶点着色器中的无关变量。若片段着色器使用到了该变量,则光栅器会在光栅化阶段对其进行插值,并且每一次片段着色器的调用都会提供一个匹配特定位置的插值后的值。
通常境况下依赖插值的两个变量是三角形的法向量和纹理坐标。顶点的法向量通常计算包含该顶点的所有三角形法向量的平均值获得,若物体不平坦则每个三角形的三个顶点的法向量会各不相同,则可以通过插值来计算每个像素的法向量。
源码解析
|
|
在各渲染管线之间进行传递的参数必须在shader中使用out保留字来全局的进行声明定义;
在图形管线中颜色值通常使用一个在[0,1]范围内的浮点数来表示;
在顶点着手其中的output输出颜色变量对应的另一边是片段着色器 的输入的颜色变量。该变量经过光栅器的插值,故每一个被执行的片段着色器可能都会是不同的颜色;
索引绘制
|
|
为索引缓冲创建缓冲对象的handle;
定义了坐标点及索引数组;
顶点缓冲使用GL_ARRAY_BUFFER参数表示缓冲类型;索引缓冲使用GL_ELEMENT_ARRAY_BUFFER;
除了绑定顶点缓冲还需要在绘制之前绑定索引缓冲;
索引绘制使用函数glDrawElements(),第一个参数表示待渲染的图元类型;第二个参数表示索引缓冲中用于产生图元的索引个数;第三个参数表示每个索引值的数据类型,若索引范围很小应选择小的数据类型来节省空间;最后一个参数表示从索引缓冲区起始位置到第一个需要扫描的索引值的偏移byte数,当使用同一个索引缓冲来保存多个物体的索引时使用;
坐标系统
- 局部空间
指物体所在的坐标空间,模型的所有顶点都在局部空间中; - 世界空间
指物体相对于世界的坐标;由模型矩阵(Model Matrix)将物体坐标由局部变换到世界空间;模型矩阵包含平移、缩放、旋转。 - 观察空间
指从摄像机的视角观察到的空间,通常由一系列的位移和旋转的组合将特定对象变换到摄像机前面;这类组合变换通常存储在一个观察矩阵(View Matrix)中; - 裁剪空间
将特定范围之外的点都裁剪掉,通过投影矩阵(Projection Matrix)将指定范围上的坐标转换为标准设备坐标的范围(-1.0, 1.0),所有在范围外的坐标不会被映射到(-1.0, 1.0)的范围之间,故被裁剪。
由投影矩阵创建的观察箱(Viewing Box)被称为平截头体(Frustum),出现在平截头体范围内的坐标都会最终出现在用户的屏幕上。
一旦所有顶点被变换到裁剪空间,将会执行透视除法将位置向量的x、y、z分量分别除以向量的齐次w分量,该步骤将会在每一个顶点着色器运行的最后被自动执行;
投影矩阵分为两种:
- 正射投影矩阵:类似于立方体的平截头箱,但没有考虑透视,获得的结果不真实;
- 透视投影矩阵:将给定的平截头体范围映射到裁剪空间,并修改每个顶点坐标的w值,从而使离观察者越远的顶点坐标w分量越大。被变换到裁剪空间的坐标都会在-w到w的范围之间,最后使用透视除法将所有可见坐标归一化到-1.0到1.0之间。1glm mat4 proj = glm::perspective(glm::radians(45.0f), (float)width/(float)height, 0.1f, 100.0f);
glm::perspective创建了一个定义了可是空间的平截头体;第一个参数定义了视野fov的值,并设置了观察空间的大小;第二个参数设置了宽高比;第三和第四个参数设置了平截头体的近和远平面;