材质:
- 决定物体在渲染过程中最终视觉呈现的关键因素之一,它通过一系列光学(投光物)和物理参数(反光度,反照率、金属度,折射率......)准确模拟现实世界中的材料特性,从而增强虚拟环境的逼真度和沉浸感。
cpp
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
首先看一下冯氏光照模型镜面反射的计算:
- 将(视线,反射光线)点乘,角度越小(0------90)cos越大,
- 通过max控制结果非负,当(>90)度,结果为负值,取0,【0------1】
- 通过pow,取反光度^幂,当反光度越高,函数的曲线会陡增的越明显
- 反光度越高,反射光的能力越强,散射得越少,高光点就会越小
注意:
- 物体反光度很高时,没有什么大影响,大多数观察方向与反射方向的pow结果都很小,只有一小部分很亮,大部分都是暗的,这种一个小圆圈点的断层几乎每什么影响
- 物体反光度很低时,高光 的范围会很大,当(视线,反射光线)(>90)度,结果为负值取0,会出现了很大的的断层(亮部--暗部)
- 对于漫反射angle为负数是正确的,(入射光线,法线)点乘,如果>90度,光线位于物体片段的下方,确实不会产生漫反射结果。
Blinn-Phong着色模型:(解决了断层问题)
- 对镜面光模型的处理上有一些不同,不再依赖于反射向量
半程向量:
-
即光线与视线夹角一半 方向上的一个单位向量,当半程向量与法线向量越接近时,镜面光分量就越大。
-
当视线正好与反射向量对齐时,半程向量就会与法线完美契合,当观察者视线越接近 于原本反射光线 的方向时,镜面高光就会越强
-
半程向量与表面法线之间的夹角都不会超过90度 :(除非光源在表面以下)
-
首先如果视线在表面下,我们看不到片段,所以不必关心它的最终结果,光源在表面以下会照射底面,而照射不到上面,所以视线和光线都应在表面上方。而法线距离半程的最大值,为视线和光线都为0 / 180 度时
计算半程:
cpp
vec3 halfwayDir = normalize(lightDir + viewDir);
spec = pow(max(dot(normal, halfwayDir), 0.0), 16.0);
-
向量相加(入射光线 + 视线 ) / |(入射光线 + 视线 )|正规化(只关心半程向量方向,不关系长度)
-
计算Blinn-Phong的镜面光:......只需要dot(半程,法线)......
-
半程向量与表面法线的夹角通常会小于观察与反射向量的夹角(意味着相同片段位置,dot结果更大,pow结果更大,高光散射范围广):
-
所以应将镜面反光度设置更高一点,让高光范围更集中