记录记录...
漫反射(Diffuse reflection)
(资料图片仅供参考)
高光(Specular highlights)
间接/环境光照(Ambient lighting)
L是光源的向量,N是法线向量,I是光源强度。
漫反射diffuse = I * cosθ
余弦定理 cosθ = L · N / (|L|*|N|)
由于L,N长度都为1, 消去|L|*|N|得
diffuse = L · N * I
排除负数,得到最终公式
diffuse =max(0, L · N) * I
核心代码
效果
逐顶点漫反射 完整代码
参考: https://zhuanlan.zhihu.com/p/110326132
逐像素光照同理, 略
函数解释
UnityObjectToWorldNormal 模型空间法线向量->世界空间向量
UnityObjectToClipPos 顶点坐标 模型空间->齐次裁切空间
添加环境光照
此时, 物体的背面是完全暗的,需要添加环境光照.
在原有基础上加上ambient 则能有基础亮度
I是光源信息,r是反射方向,viewDir是视角方向,gloss是光滑度。
高光反射 specular = I * max(0, r · viewDir)^gloss
反射方向 r=2(n*L)n ― L
或是使用Unity的函数 r = reflect(-L,n)
视角向量 viewDir = UnityWorldSpaceViewDir(i.worldPos)
顶点世界坐标 worldPos = mul(unity_ObjectToWorld,v.vertex).xyz;
核心代码
函数介绍
reflect(-worldLightDir,worldNormal); 反射方向
UnityWorldSpaceViewDir相机方向
saturate相当于max加clamp(0,1)
unity_ObjectToWorld坐标变换矩阵, 用于局部转世界坐标
效果
理解公式specular = I * max(0, r · viewDir)^gloss (默认gloss>1)
r · viewDir是向量的点乘, 向量都是经过归一化处理的
所以得到r· v = |r|*|v|*cosθ = cosθ ,
相当于, 反射角与视角向量夹角越小, cosθ越大, 亮度越大
反之, 夹角>90°, 则结果负数, max后为0 , 就看不到高光
gloss相当于衰减系数, 系数越大, 光圈越小
逐像素高光反射 完整代码