- 小光,小光,小光,小光!
- 本文所总结视频为或许是小光从油管搬运到B站的视频:传送门
- 本文主旨补充Unity客户端编程Shader知识点。
- 我创建了一个游戏制作交流群:637959304 进群密码:(CSGO的拆包密码)欢迎各位大佬一起学习交流,不限于任何平台(U3D、UE、COCO2dx、GamesMaker等),以及欢迎编程,美术,音乐等游戏相关的任何人员一起进群学习交流。
- 个人博客网址:https://www.sugarcanesama.com/archives/1153,如文章转载中出现例如传送门失效等纰漏,建议直接访问原博客网址。
- 如有不对之处,欢迎指正。
目录
高级光照
法线贴图
- 计算步骤:
1、采样法线贴图并转换成向量,让顶点着色器传递法线、副法线和切线向量
2、将采样得到的法向信息从切线空间转换到世界空间 - 法线贴图(normal mapping)的一个像素不代表颜色,而是代表一个法向量(左图)。在RGB通道中,RGB分别代表XYZ三个向量分量。(右图)
- 法线映射。就是用一张图片中定义的法线替代模型上定义的法线
- 切线空间法向量:在一般的图像中,0到255的红色值,对应了X轴向的-90度到90度而绿色对应Y轴,蓝色对应Z轴。三轴合一即为法向量。
- 向量转换:切线空间法向量->物体空间->世界坐标系。转换完成后才可以计算光照向量的影响。
- 数据结构
基本光照模型
- 环境光(Ambient Lighting):环境光不宜设置过高,否则会遮盖漫反射和高光的效果。
- 漫反射(Diffuse Lighting):从光源发射的有向光
- 高光(Specular Lighting):光线发生镜面反射后的反射光线
- 上述三种光照合在一起成为Blinn光照模型。
- 环境光
- 漫反射光
- 预处理:1、把向量转换到同个向量空间中 2、每一个向量都已经单位化(方便计算夹角)
- 高光
- 镜面性(Specularity):借助光线来源与摄像机位置模拟光线在表面上发射的近似效果。
- 计算步骤:
1、引入观察者坐标到像素着色器中
2、再顶点着色器中计算出观察向量
3、计算出一个折中向量(该向量直接应用于光照会导致高光覆盖范围过大,如下图所示)
4、引用光泽度(gloss)变量控制高光范围=>pow(NdotH,gloss); NdotH自乘次数越多,光照范围越收束。
高级光照
光照衰减(Ligt Attenuation)
- 光照原理物体,照射到物体上的光线就越少。光照衰减只会影响漫反射和高光。
- 光照衰减公式:
1、线性光照衰减(Linear Light Decay):光源与物体的距离和物体亮度成反比(取距离倒数)
2、改进版:成平方反比。(更接近于真实光照)缺点是衰减速率过快,需要反复调试参数。
方向光(Directional Light)
- 方向光只影响光照方向,无论光源物体相对距离如何,亮度不会进行改变(例如阳光),因此方向光也没有光照衰减。
聚光灯
- 聚光灯:同时考虑光源的坐标和光源的方向。
全局光照
- 全局光照包含两部分:环境光遮蔽(Ambient Occlusion),分散卷积立方贴图(Diffusely Convolved Cubemaps)
- 需要以不重叠且坐标合法的方式展开UV
- 制作环境光贴图步骤请参考原视频2.8部分,制作完成后用环境光代替漫反射贴图即可。
- 环境立方贴图(Cube Mapping):计算从环境四处发射来的光线
- 制作环境立方贴图:对应视频2.10部分
- 方式:1、基于真实环境光线的立方贴图 2、基于虚拟环境的立方贴图
- 方式1步骤:1、制作光照探针图(HDR图像,高亮度会显示暗部细节,反之显示更多亮部细节)2、将探针图转换为经纬图 3、经纬图转换为分散卷积图(每个像素不仅携带自己方向上的颜色信息,还要计算180度球体范围内的所有像素信息然后进行平均运算,即每一个像素都代表了半球范围内的所有信息) 4、把分散卷积图转换为立方环境贴图(十字形)
探针图
经纬图
分散卷积图
立方环境贴图
- 方式2步骤:在软件(3DS max等)中用摄像机截取六个方向的图片,然后重复方式1的步骤
光照模型
- 光照模型:一套数学公式,基于我们选定的参数来决定每个像素的渲染颜色
- Phong光照模型(高光):基于Blinn模型的简化版。区别为,Phong计算高光的方式与Blinn模型不同。Blinn模型中不计算高光的折中向量,而直接计算反射结果,以此来代替HDR贴图的高消耗。
- Phong模型高光效果:适合塑料表面,光照比较紧凑
光泽度=4
光泽度=0.01
- Blinn模型高光效果:适合金属表面
- Cook/Torrence光照模型(高光):为模拟金属表面(拉丝金属、铝制品)而设计,应对计算不光滑表面
- 菲涅尔效应:传送门
不光滑表面光线示意图
其中一些光照不会反射出去
- 数据结构
高光滑度
高光滑度
中等光滑度
低光滑度
- Oren-Nayer光照模型(漫反射):可以替换Blinn模型的漫反射光照计算部分。适用于皮肤,衣服,黏土等表面,来模拟粗糙表面。
- 缺点:计算耗时长。
粗糙度为0时等价于Blinn模型
中等粗糙度
高粗糙度
- 数据结构
float orenNayar(float3 N,float3 V,float NdotL,float NdotV,float Roughness1)
{
//根据传入三个向量,将光照摊平在表面上
float theta_r = acos(NdotV);
float theta_i = acos(NdotL);
float cos_phi_diff = saturate(dot(normalize(V - N * NdotV),normalize(L - N * NdotL)));
float alpha = max(theta_i,theta_r);
float beta = min(theta_i,theta_r);
float A = 1.0 - 0.5 * Roughness1 / (Roughness1 + 0.33);
float B = 0.45 * Roughness1 / (Roughness1 + 0.09);
return saturate(NdotL) * (A + B * sin(alpha) * tan(beta));
}
float4 f(v2f In,uniform float4 lightColor) : COLOR
{
float4 Diffuse = orenNayar(N,L,NdotL,NdotV,Roughness1) * ColorTexture * DiffuseColor;
return (Diffuse + Ambient) * lightColor;
}