Unity3d Shader光照模型

摘抄自《Unity3D ShaderLab开发实践详解》

光源对物体照明的分类

间接照明

在物体所处的环境中,我们可以把照射到物体上的光源简单地分为直接照明和间接照明。间接照明是光在物体间传播后,最终又对物体形成照明。

直接照明

如果不考虑光线在物体间的传播,也不考虑光线在物体内部的传播,则光线对物体直接照明。

光照模型

Lambert

对于粗糙物体表面的某一点,其亮度应该和入射光线与该点的垂直程度相关,也就是入射光线与此点法线的夹角相关。如果我们用L表示单位长度的入射光线,用C表示到达此点的光线的强度和颜色,用N表示此点的法线,那么物体表面此点的亮度Lum就可以用下面的公式来表示:

Lum = C * max(0, cos<L,N>)

<L,N> 表示的是方向矢量L和N之间的夹角,其cos也就是这两个方向矢量的占积,在实际计算时通过Cg的标准函数库dot(L, N)来完成。这个值对于背向光线的点来说为负,其实就是对其照明为0,因些使用标准函数库中的max0, value)来对结果进行一些控制。

这里写图片描述

inline fixed4 LightingLambert(SurfaceOutput s, fixed3 lightDir, fixed atten)
{
     fixed diff = max (0, dot( s.Normal, lightDir));
     fixed4 c;
     // 下面计算了物体表面的纹理颜色、光源颜色以及光源强度的影响
     c.rgb = s.Albedo * _LightColor0.rgb * (diff * atten * 2);
     c.a = s.Alpha;
     return c;
}

高光类

Phong最基础的,没有算法的
下面我们就来考虑一下上面提到的镜面高光问题,可以很直接地计算某一光线ray在某一法线为normal的点经反射后的光线。如果用R表示光线在此点的单位长反射方向向量,V表示视线的单位方向向量,那么高光部分Spec的计算方式表示为:

Spec = pow ( max (0, cos<R,V>), gloss)
<R,V>表示方向矢量I和N之间的夹角,gloss表示其表面的镜面光滑程度。
以dir = 表面光线 - 光照方向,与视线的点积计算,高光效果

这里写图片描述

inline fixed4 LightingPhong(SurfaceOutput s, fixed3 lightDir, half3 viewDir, fixed atten)
{
     float diff = dot(s.Normal, lightDir);
     float3 reflectionVector = normalize(2.0 * s.Normal * diff - lightDir);
     float spec = pow( max(0, dot(reflectionVector, viewDir)),  _SpecPower);
     float3 finalSpec = _SpecularColor.rgb * spec;

     fixed4 c;
     c.rgb = (s.Albedo * _LightColor0.rgb * diff) + (_LightColor0.rgb * finalSpec);
     c.a = 1.0;
     return c;
}

BlinPhong

通过视线方向和光线方向所形成的半角向量,而不是反射向量来计算光高效果。这种方法已经被证明比Phong在物理计算方面具有更高的精确度。

inline fixed4 LightingBlinPhong(SurfaceOutput s, fixed3 lightDir, half3 viewDir, fixed atten)
{
     float3 halfVector = normalize(lightDir + viewDir);
     float diff = max (0, dot(s.Normal, lightDir));
     float nh = max (0, dot(s.Normal, halfVector));
     float spec = pow(nh, _SpecPower) * _SpecularColor;

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

这里写图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值