材质&&漫反射,光照贴图
- 使用struct为材质建立结构体,以便方便管理
- 漫反射贴图是物体的颜色值(纹理)(通过 UV 坐标映射到渲染物体的表面),材质是物体的属性(物体对光的交互)
- glm::rotate(lightPos, glm::radians(0.1f), glm::vec3(0.0f, 1.0f, 0.0f)) 表示旋转的对象、旋转的角度和旋转的轴。
- /\/\/\/\/\//\/\/\/\/\/\/\/\//\/\///\/\/\/\//\/\/\/\//\//\/\/\/\/\\/
- 向量转化:
- 访问向量的前几个分量:xyzw,rgba,stpq(.)符号访问
- 增添分量:vecx( vecx,……,……)
- /\/\/\/\/\//\/\/\/\/\/\/\/\//\/\///\/\/\/\//\/\/\/\//\//\/\/\/\/\\/
- 光照贴图:由黑白颜色组成 * 镜面反射光,颜色黑到白(0.0——1.0),所以贴图颜色值越接近白色,镜面反射越强
- 光照贴图作用:根据贴图决定,镜面光对物体的每个部分的影响
投光物
- 我们可以根据物体的材质,计算光对物体的影响,但是光也有自己的模型(平行光,点光,聚光)
- 比如点光根据半径范围,强度逐渐衰减,那么根据物体与点光源的距离,需要获得新的光照强度,再计算光对物体的影响
- 比如聚光,会有方向以及切光角,在聚光范围内才会有光强度,并且如果执行了边缘软化,也会有光强度的影响
- 平行光不会向周围发射,光线平行,意味着不同位置的物体,接受的光线角度是一致的
- /\/\/\/\/\//\/\/\/\/\/\/\/\//\/\///\/\/\/\//\/\/\/\//\//\/\/\/\/\\/
- 点光源:之前模拟的就是点光源,这次增加了衰减,更真实的渲染效果
- 衰减:光线传播距离的增长逐渐削减光的强度
- d为片段到光的距离,距离越远d越大,一次项越大,作为分母,衰减值越小
- 二次项随着d的增加,变化幅度越快,作为分母,衰减值越小
- 衰减 = 1.0f /(1(控制分母>1,让强度值保持在0——1之间,让光强度只会减少不会增加)+一次项(线性)+二次项(距离越远,衰减速度越慢))
- 一次项:1/10 = 0.1;1/20= 0.05;1/30=0.03
- 二次项:1/100 = 0.01;1/400 = 0.0025;1/900=0.0011
- 由此可见,衰减速度都会越来越慢,并且二次项,对速度影响更大
- 通过一次二次项系数,调整衰减函数,从而影响光源的半径(点光源),
- 衰减值分别乘以环境光、漫反射和镜面光颜色
// attenuation
float distance = length(lightPos - v_Position);
float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance));
- /\/\/\/\/\//\/\/\/\/\/\/\/\//\/\///\/\/\/\//\/\/\/\//\//\/\/\/\/\\/
- 聚光:只朝一个特定方向而不是所有方向照射光线,只有在聚光方向的特定半径内的物体才会被照亮
- 光的位置,SpotDir聚光的方向,LightDir光线方向,
Phi
𝜙聚光半径的切光角,Theta
𝜃光线方向和聚光方向的夹角 - 计算LightDir向量和SpotDir向量之间的点积,角度越大,光强度越小。
- 向量的标准化:向量每个分量 / 向量长度(标量),最后向量长度变为1,方向不变
- 将要被点乘的向量归一化,指关心方向,所以点乘结果和向量长度无关,只和方向有关
- /\/\/\/\/\//\/\/\/\/\/\/\/\//\/\///\/\/\/\//\/\/\/\//\//\/\/\/\/\\/
- 以摄像机作为手电筒,相机前方为聚光方向
- 如何判断当前的片段是否在聚光内呢?
- 从聚光起始点(摄像机位置)到片段的向量(光线),计算与聚光方向的dot点乘,然后判断点乘的cos角度,是否在切光角内部,
- 因为切光角是角度,为了节约一点性能开销,需要把切光角glm::cos()转为cos,而不是将点积结果的反余弦
- 这里theta 差值 > light.cutOff进行光照计算:是因为角度都转化为了cos,一个0度的角度表示的是1.0的余弦值,而一个90度的角度表示的是0.0的余弦值。从而角度越大,cos越小,所以应该>cos角度才行。
- 最后如果在聚光内,执行光照计算,否则只有纹理颜色值+一点环境光(让场景在聚光之外时不至于完全黑暗)
- 我们现在就有了两个光源,手电筒,和点光源
- /\/\/\/\/\//\/\/\/\/\/\/\/\//\/\///\/\/\/\//\/\/\/\//\//\/\/\/\/\\/
- 边缘软化:新建外圆锥,原切光角为内圆锥,光从内圆锥逐渐减暗,直到外圆锥的边界
- 计算:( (当前角度cos - 外光切cos) / (内光切 cos- 外光切cos) )
- 注意,角度越大cos越小,设内外光切不变,内 - 外 = 正值
- 角度>在内外光切之间,分子为正数,差值 < 内外光切差值,聚光强度 <1
- 角度>外光切时,分子为负数,聚光强度 < 0
- 角度<内光切时,分子为正数,差值 > 内外光切差值,聚光强度 >1
- 不再需要
if-else,因为在切光角范围外,聚光强度为负,
是为了光照避免为负数,需要
clamp()约束到0——1之间