演示
冯氏光照
- 光照原理:
- 对于向量相乘默认为点乘,如果*lightColor(1.0f, 1.0f, 1.0f);白光,值不变
- 物体的颜色显示原理:不被物体吸收的光反射,也就是由白光分解后的一部分,因此,需要有光才会有物体颜色,并且光会影响物体颜色。
- 原理:模拟光,实际就是计算物体的片段 / 顶点的颜色值
- 对于物体颜色:可以在顶点数据传入,也可以在fragment glsl传入uniform
- /\/\/\/\/\//\/\/\/\/\/\/\/\//\/\///\/\/\/\//\/\/\/\//\//\/\/\/\/\\/
- 光照模型:
- 冯氏光照模型(Phong Lighting Model):环境(Ambient)(环境色)、漫反射(Diffuse)(正对着光源,它就会越亮),镜面(Specular)(亮点)
- 目标:模拟出基本冯氏光照
- /\/\/\/\/\//\/\/\/\/\/\/\/\//\/\///\/\/\/\//\/\/\/\//\//\/\/\/\/\\/
- 向量:
- 理解向量:想象3D空间xyz,有坐标原点0,0,0,物体的vec3坐标终点实际是物体的xyz坐标,与原点相连成矢量(有方向的长度线段)
- 向量与向量+-,以点模拟:实际是改变原坐标点xyz,分别+-3个标量后,在世界空间的位置,
- 而以向量模拟+-:将新的的向量放在物体向量的终点,得到原始起点到(未反转 / 反转 后)终点坐标。
- 对于-法:向量模拟:如果不改变新的向量位置,两个向量起点都放在世界中心,那么,可以获得两个向量的终点(坐标点)的向量
- 具体方向:向量起点 = 两向量中的被减数,向量终点 = 两向量中的减数
- /\/\/\/\/\//\/\/\/\/\/\/\/\//\/\///\/\/\/\//\/\/\/\//\//\/\/\/\/\\/
- 漫反射:
- 法向量(Normal Vector):垂直于片段表面的一个向量
- 漫反射:当光强度不变,入射向量,基于物体法向量,夹角越大,强度越小
- 点乘:恰好符合漫反射原理,夹角越接近90,cos越接近0,夹角越接近0,cos越接近1
- vertex glsl 接受所有顶点数据,需要传输到fragment glsl中,通过计算的法向量,获得当前片段获取的颜色值
- /\/\/\/\/\//\/\/\/\/\/\/\/\//\/\///\/\/\/\//\/\/\/\//\//\/\/\/\/\\/
- 在顶点数据传入normal,类型为vec3
- 如何计算顶点漫反射颜色?获取顶点法向量,由(光位置向量 - 顶点位置向量)获取光向量,两者点乘,返回float标量。
- /\/\/\/\/\//\/\/\/\/\/\/\/\//\/\///\/\/\/\//\/\/\/\//\//\/\/\/\/\\/
- 法线矩阵:
- 这里会发生一个很奇怪的现象,当物体旋转时,光会跟着物体的正面
- 原因:
- 对于计算漫反射是:光向量传入的是物体的v_Position = a_Position;顶点数据,当在vertex glsl中通过matrix改变物体的顶点,输出的是gl_Position,并没有改变传入的v_Position。
- 另外计算float diff点乘时,传入的为v_Normal,也是顶点数据,并不会随着物体旋转发生改变
- 所以对于每个顶点来说,计算的最后漫反射结果都是固定的
- 解决:正确更新新的位置(模型矩阵:物体的位置、旋转和缩放)和法线位置
- 位置:*modleMatrix变换到世界空间坐标
v_Position = vec3(model * vec4(a_Position, 1.0));
v_Normal = mat3(transpose(inverse(model))) * a_Normal;
- /\/\/\/\/\//\/\/\/\/\/\/\/\//\/\///\/\/\/\//\/\/\/\//\//\/\/\/\/\\/
- 其他:
- 假设改变摄像机:editcamera本身不是物体,没有自身缩放,只有在世界中的位置和旋转
- 理解平行光:
- 想象两个立方体,在不同的位置,普通光源在一个点,分别向两个立方体发射光线,而平行光不会改变角度
- /\/\/\/\/\//\/\/\/\/\/\/\/\//\/\///\/\/\/\//\/\/\/\//\//\/\/\/\/\\/
- 理解矩阵:
- 单位矩阵:mat4(1.0f),将其*任何的 vec4(vec3(我们要变换的坐标),1.0f) = vec4
- 再比如简单的glm::scale:我们本身的mat4(经过变换的)* vec3(要变换的倍数)
- 顺序非常重要:否则计算结果有偏差
model = glm::scale//缩放
model = glm::rotate//旋转
model = glm::translate//位移
- /\/\/\/\/\//\/\/\/\/\/\/\/\//\/\///\/\/\/\//\/\/\/\//\//\/\/\/\/\\/
- 镜面:
- 漫反射取决于光线和物体表面法线的角度
- 镜面取决于观察方向,和反射光线的点乘
- /\/\/\/\/\//\/\/\/\/\/\/\/\//\/\///\/\/\/\//\/\/\/\//\//\/\/\/\/\\/
- 镜面:法向量,reflectDir反射光向量,相机方向向量,镜面强度(Specular Intensity)
法线矩阵(逆转置)
- 需要把法向量也转换为世界空间坐标,法向量只是一个方向向量(矢量),不能表达空间中的特定位置,属于vec3,并没有w分量,所以位移不应该影响。
- 简单mat3(*modle)矩阵后,旋转影响法线方向,缩放影响法线大小 || 方向(不等比时)
- 原理:mat3*vec3,vec3同时*某个标量,方向一致,*不相等的标量,方向改变
- 根据矩阵相乘的规则:A*B,需要A的列数 == B的行数,因为向量B只有3个分量,因此要*3.3的模型矩阵
- 法线矩阵(Normal Matrix):模型矩阵左上角3x3部分的逆矩阵的转置矩阵,
- /\/\/\/\/\//\/\/\/\/\/\/\/\//\/\///\/\/\/\//\/\/\/\//\//\/\/\/\/\\/
- 为什么用法线矩阵?缩放是均匀的,法线的方向将保持不变,长度会受影响,但很容易通过单位化修复,当不等比缩放,法线将不再垂直于平面,法线矩阵移除对法向量错误缩放的影响
- 法向量:inverse逆矩阵(经过
model
变换后的信息,映射回原始的、未变换的空间),transpose()转置(确保矩阵与向量乘法的结果是一个列向量),mat3强制转换为3×3矩阵 - 理解逆矩阵:modle * 原始vec = 新vec。现在变回原始vec,= 新vec / modle,但是矩阵没有除法,所以 * 1/modle,也就是逆矩阵