glsl入门--Apple的学习笔记

要做出变换效果,其实就是玩数据,而数据的来源及数据的一些变量都依赖glsl,所以需要先系统的学习下。其实glsl一开始是配合opengl专属的。
为了看明白glsl,首先要学习语法,网上很多。然后就是理解这些变量的作用及使用的阶段。我先进行了第一轮基础学习

1.为什么要光栅化?

图形管线的输入是图元顶点,输出的则是像素(pixel),这个步骤其中还有个中间产物叫做片段(fragment),一个片段相应一个像素,但片段比像素多了用于计算的属性,比如:深度值和法向量。通过片段能够计算出终于将要生成像素的颜色值,我们把输入顶点计算片段的过程叫作光栅化。为什么要光栅化?由于要生成用以计算终于颜色的片段。

2.光栅化发生在哪一步?

数据渲染流程.png

光栅化函数也须要输入和输出,从上图来看函数的输入就是组成图元的顶点结构,输出的就是片段结构
既然光栅化是在顶点处理程序以后发生的步骤,那么输入的顶点结构是经过顶点处理以后的,也就是进行过mvp变换,乘以透视矩阵之后的顶点,注意:这步还没有做透视除法,光栅化插值发生在裁剪空间,绝不是标准化空间,所以顶点位置是四维齐次坐标不是三维坐标!

3.着色器(Shader)作用?

画画的时候我们经常有这么一个过程:先打线稿,再上色。着色器就是用来做这个工作的。
通常着色器分两种:
1顶点着色器(vertex shader)这个是告诉电脑如何打线稿的——如何处理顶点、法线等的数据的小程序。
2片面着色器(fragment shader)这个是告诉电脑如何上色的——如何处理光、阴影、遮挡、环境等等对物体表面的影响,最终生成一副图像的小程序。
采用了这两种着色器小程序 的 数据传输处理计算的渲染过程,称之为 可编程管线。

4. 法向量有什么用?

法向量主要影响光照

  1. 光照类型包括:环境光(Ambient light),方向光(Directional light),点光(Point light),聚光(Spot light)。
    2)根据把光线在物体表面发射的方式分为两类:漫反射(Diffuse reflection),镜面反射(Specular reflection)。
    法向量:
    我们用法线向量来表示平面朝向,在具体实现中,每个点都会有一个法线向量。所谓法线向量就是垂直于平面的一个三维向量。


    法向量.png

    图中展示了两种法线向量的表示方法,左边是每个多边形的每个点有一个法线向量,右边是每个点有一个法线向量,共享点的法线向量是这个点在所有平面上的法线向量之和。法线向量应该总是被规范化成单位向量。本文的例子中使用的是左边的方式。
    需要注意的是,法线向量只代表方向,不代表位置信息,所以法向向量尽量用归一化的数据。如下图


    法向量2.png

    先分析顶点着色器程序:
    shader代码分析.png

    第二行代码 光照强度 = 法向量 * 反向归化后的光源向量 。从数学公式来说,光照强度就是法向量与反向归化后的光源向量的点积。
    得到光照强度之后,第三行代码 vec4(_lightColor * lightStrength + _lightDiffuse, 1),光照强度*环境光色值,这时其实已经具备光照效果,加上漫反射_lightDiffuse是防止没有光照强度的地方会完全变黑,那如实际情况不相符。漫反射还有很多内容可以扩充,譬如根据纹理的材质进行漫反射的光强度计算,添加自己的色值等等。

5. 深度值有什么用?

简单理解就是通过深度测试然后在后面的图像被遮挡,这样看起来的3D图形就是真实的。有了距离那么还可以处理隐形。
1)一般情况下,计算机在渲染图像的过程中会同时产生一张深度图,这是一张只有一个通道的图像,代表了物体距离摄像机的距离。越亮的地方代表离摄像机的距离越近,越暗的地方代表离摄像机的距离越远。有了这张图,在渲染物体时,先把即将输出的像素的深度值(深度图中这个像素的颜色)与当前深度缓冲区(当前深度图)中的像素颜色进行比较,如果这里已经有一个比要渲染的像素还要离摄像机近的像素存在,就抛弃掉将要渲染的像素;反之就覆盖掉原来的。这就是被称为“深度测试”(depth test)的操作。
2)有了这张深度图,我们其实不仅能处理遮挡,还能够渲染阴影,阴影就是从光源的位置看来,各个物体之间的遮挡关系;被遮挡的地方涂上阴影,没被遮挡的地方该咋样咋样。也就是说,我们需要让摄像机的位置朝向等与光源一致,然后渲染一张图像,取出它的深度图(事实上,我们只需要深度数据,所以我们可以只渲染深度来节约开销)。然后把摄像机移回原来的位置,再进行渲染。在渲染时,对渲染的每个像素,找到它在光源处那张深度图中的位置,并计算出它离光源的距离;然后把光源深度图中的数据和它离光源的距离数据比较,就可以判断出它是不是应该被涂上阴影了。

6. obj模型文件

在3d图形处理中,一个模型(model)通常由一个或者多个Mesh(网格)组成,一个Mesh是可绘制的独立实体。例如复杂的人物模型,可以分别划分为头部,四肢,服饰,武器等各个部分来建模,这些Mesh组合在一起最终形成人物模型。
Mesh由顶点、边、面Faces组成的,它包含绘制所需的数据,例如顶点位置、纹理坐标、法向量,材质属性等内容,它是OpenGL用来绘制的最小实体。Mesh的概念示意如下图所示


mesh.png

对这个文本格式做一个简要说明:
以#开始的行为注释行 usemtl和mtllib表示的材质相关数据,解析材质数据稍微繁琐,本节我们只是为了说明加载模型的原理,不做讨论。 o 引入一个新的object v 表示顶点位置 vt 表示顶点纹理坐标 vn 表示顶点法向量 f 表示一个面,面使用1/2/8这样格式,表示顶点位置/纹理坐标/法向量的索引,这里索引的是前面用v,vt,vn定义的数据 注意这里Obj的索引是从1开始的,而不是0

参考文档
https://www.cnblogs.com/kex1n/p/3941680.html
https://www.cnblogs.com/betairy-linkzeldagg/p/5445613.html
https://blog.csdn.net/shareus/article/details/80007236
https://www.2cto.com/kf/201607/525593.html

你可能感兴趣的:(glsl入门--Apple的学习笔记)