您的位置:首页 > 其它

实现BlinnPhong 光照的原理

2016-01-25 00:47 246 查看
引言:
在Shader中实现BlinnPhong光照时,会用到一些代码,这些代码令人费解,下面是BlinnPhong 在Unity里内置的函数:

在文件Lighting.cginc里面

windows系统下位于:

…Unity\Editor\Data\CGIncludes\

这个是实现BlinnPhong 的函数

inline fixed4 LightingBlinnPhong (SurfaceOutput s, fixed3 lightDir, half3 viewDir, fixed atten)
{
half3 h = normalize (lightDir + viewDir);

fixed diff = max (0, dot (s.Normal, lightDir));

float nh = max (0, dot (s.Normal, h));

float spec = pow (nh, s.Specular*128.0) * s.Gloss;

fixed4 c;
c.rgb = (s.Albedo * _LightColor0.rgb * diff + _LightColor0.rgb * _SpecColor.rgb * spec) * (atten * 2);
c.a = s.Alpha + _LightColor0.a * _SpecColor.a * spec * atten;
return c;
}


忽然给了这么一段代码,学过CG 的人也会感到一些迷惑,下面我们从图形学的角度来看这些代码的含义.

我们先来了解一下光照的计算。

光照是由发射光,环境光,漫反射光以及镜面高光组成的,这四个部分先单独运算,然后再累积起来组成最终的效果。

一 发射光:

openGL 中物体材质设置发射颜色来模拟发射光的

发射颜色 = 物体发射材质颜色

二 漫反射:

漫反射颜色 = 光源的漫反射光颜色x物体的漫反射材质颜色x diff

其中漫反射因子diff是光线与定点法线向量的点积:
diff = max(0,dot(N,L))

PS: dot() 为两个向量之间的的cos值.很直观的展示的漫反射的规律.在正对着入射光线时光照最强,在大于等于90度时候,没有反射的效果.

三 环境光:
环境颜色 = 光源的环境光颜色 x 物体的环境材质颜色

四 镜面反射:
镜面反射颜色 = 光源的镜面光颜色x物体的镜面材质颜色 x spec
spec =power(max(0,dot(s.Normal, h)),shininess)
这里的shininess是128
h = normalize (lightDir + viewDir)
h向量是视线向量viewDir 与光线向量lightDir的半向量,几何意义就是视线与光线夹角的平分线.

这里的normalize()函数用于获取lightDir + viewDir 坐标转化为单位向量,且方向不变.

光照的终极公式:
光照颜色 = 反射颜色 +全局环境颜色 +(环境颜色 + 漫反射颜色 +镜面反射颜色) x 聚光灯效果 x 衰弱因子

这里给的物体是不发光的,没有反射颜色这的部分.
half3 h = normalize (lightDir + viewDir);	//h向量是视线向量viewDir 与光线向量lightDir的半向量,几何意义就是视线与光线夹角的平分线.

fixed diff = max (0, dot (s.Normal, lightDir));	//漫反射因子diff是光线与定点法线向量的点积,大于等于90度,没有反射的效果.

float nh = max (0, dot (s.Normal, h))	//nh 是h向量与定点法线向量的点积

float spec = pow (nh, s.Specular*128.0) * s.Gloss; //得到nh 向量进行s.Specular*128.0 次乘方计算

fixed4 c;
// 光照颜色 = 反射颜色 +全局环境颜色 +(环境颜色 + 漫反射颜色 +镜面反射颜色) x 聚光灯效果 x 衰弱因子

c.rgb = (s.Albedo * _LightColor0.rgb * diff + _LightColor0.rgb * _SpecColor.rgb * spec) * (atten * 2);//漫反射 + 镜面反射
c.a = s.Alpha + _LightColor0.a * _SpecColor.a * spec * atten;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: