untiy 3d ShaderLab_第4章_基本的光照模型
2016-04-29 17:31
183 查看
基本的光照模型
4.1光源对物体照明的分类
4.1.1间接照明
在物体所处的环境中,我们可以把照射到物体上的光源简单地分为直接照明和间接照明。间接照明是光在物体间传播后,最终又对物体形成照明。有用3d Max做效果图经验的同学一定会对诸如用VRay渲染器渲染出的效果图倍感惊讶,那是因为渲染器在漫长的几十分钟甚至几小时的时间内,通过光线跟踪较真实地计算了光源的直接照明和间接照明。但是,对于3D游戏来说,最大的特点是实时交互,玩家或者用户不可能等上半个小时让渲染器把场景渲染好了再做下一个动作,因此对这部分的照明进行实时计算在目前是不可能实现的。在实际应用中,这种照明一般是通过预先烘培得到的。关于Unity中烘培这部分的内容在本书第8章和第9章中有详细讲解。对于实时计算,间接照明一般作为一个常量。
4.1.2直接照明
如果不考虑光线在物体间的传播,也不考虑光线在物体内部的传播,则光线对物体直接照明。我们把照明的结果分为漫反射和镜面反射两种,其中镜面反射会形成强烈的高光。直接照明是实时渲染时的计算重点。
4.2 照明的计算方式:光照模型
4.2.1漫反射和Lambert
对于粗糙物体表面的某一点,其亮度应该和入射光线与该点的垂直程度相关,也就是入射光线与此点法线的夹角相关。如果我们用L表示单位长度的入射光线,用C表示到达此点的光线的强度和颜色,用N表示此点的法线,那么物体表面此点的亮度Lum就可以用下面的公式来表示:
如果计算到此为止,可以把按照这种方式对物体进行照明计算的模型叫做Lambert。在Unity的Surface Shader中,有两个内置的Lighting Model函数,叫LightLambert()和LightingLambertes_PrePass(),分别表示了Forward和Deferred渲染路径下的这种简单照明方式。这两个函数在Unity安装目录下的Editor/Data/CGIncludes/Lighting.cginc文件中。其中对应于Forward渲染路径的LightingLambert函数如下:
4.2.2镜面高光和Phong
世界很复杂,当然也因此而丰富多彩。
下面我们就来考虑一下上面提到的镜面高光问题,可以很直接地计算某一光线ray在某一法线为normal的点经反射后的光线,这个反射可以通过Cg标准函数库中的reflect(ray, normal)来完成。如果用R表示光线在此点的单位长反射方向向量,V表示视线的单位方向向量,那么高光部分Spec的计算方式表示为:
如图所示
4.2.3 半角向量和BlinnPhong
在上面的高光计算方式中,我们确确实实计算了一次入射光线的反射,然后考察此反射光线进入视野的程度。还有一种更简单、更易于调节的方法是使用入射光线和视线的中间平均值,即半角向量,然后使用此半角向量和法线计算出一个和视角相关的高光,此种高光计算方式即为BlinnPhong。
对于Unity的Surface Shader,Unity在Lighting.cginc 中提供了两个BlinnPhong的实现,分别对应于Forward和Deferred渲染路径。其中对应于Forward渲染路径的实现如下:
如图所示是BinnPhong文件夹下的场景所展示的一个例子。
4.1光源对物体照明的分类
4.1.1间接照明
在物体所处的环境中,我们可以把照射到物体上的光源简单地分为直接照明和间接照明。间接照明是光在物体间传播后,最终又对物体形成照明。有用3d Max做效果图经验的同学一定会对诸如用VRay渲染器渲染出的效果图倍感惊讶,那是因为渲染器在漫长的几十分钟甚至几小时的时间内,通过光线跟踪较真实地计算了光源的直接照明和间接照明。但是,对于3D游戏来说,最大的特点是实时交互,玩家或者用户不可能等上半个小时让渲染器把场景渲染好了再做下一个动作,因此对这部分的照明进行实时计算在目前是不可能实现的。在实际应用中,这种照明一般是通过预先烘培得到的。关于Unity中烘培这部分的内容在本书第8章和第9章中有详细讲解。对于实时计算,间接照明一般作为一个常量。
4.1.2直接照明
如果不考虑光线在物体间的传播,也不考虑光线在物体内部的传播,则光线对物体直接照明。我们把照明的结果分为漫反射和镜面反射两种,其中镜面反射会形成强烈的高光。直接照明是实时渲染时的计算重点。
4.2 照明的计算方式:光照模型
4.2.1漫反射和Lambert
对于粗糙物体表面的某一点,其亮度应该和入射光线与该点的垂直程度相关,也就是入射光线与此点法线的夹角相关。如果我们用L表示单位长度的入射光线,用C表示到达此点的光线的强度和颜色,用N表示此点的法线,那么物体表面此点的亮度Lum就可以用下面的公式来表示:
Lum = C * max(O,cos<L,N>)<L,N>表示的是方向矢量L和N之间的夹角,其cos值也就是这个两个方向矢量的点积,在实际计算时通过Cg的标准函数库dot(L,N)来完成。这个值对于背向光线的点来说为负,其实就是对其照明为0,因此使用标准函数库中的max(O,value)来对结果进行一些控制。
如果计算到此为止,可以把按照这种方式对物体进行照明计算的模型叫做Lambert。在Unity的Surface Shader中,有两个内置的Lighting Model函数,叫LightLambert()和LightingLambertes_PrePass(),分别表示了Forward和Deferred渲染路径下的这种简单照明方式。这两个函数在Unity安装目录下的Editor/Data/CGIncludes/Lighting.cginc文件中。其中对应于Forward渲染路径的LightingLambert函数如下:
inline fixed4 LightingLambert (Surface0utput 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; }如图所示就是一个Lambent照明的例子,该例子在Lambent文件夹下。
4.2.2镜面高光和Phong
世界很复杂,当然也因此而丰富多彩。
下面我们就来考虑一下上面提到的镜面高光问题,可以很直接地计算某一光线ray在某一法线为normal的点经反射后的光线,这个反射可以通过Cg标准函数库中的reflect(ray, normal)来完成。如果用R表示光线在此点的单位长反射方向向量,V表示视线的单位方向向量,那么高光部分Spec的计算方式表示为:
Spec = pow(max(O,cos<R,V>),gloss)<R,V>表示方向矢量I和N之间的夹角,gloss表示其表面的镜面光滑程度。再加上前面在Lambert部分提到的对漫反射的计算,就可以得到一个被渲染出高光的物体,
如图所示
4.2.3 半角向量和BlinnPhong
在上面的高光计算方式中,我们确确实实计算了一次入射光线的反射,然后考察此反射光线进入视野的程度。还有一种更简单、更易于调节的方法是使用入射光线和视线的中间平均值,即半角向量,然后使用此半角向量和法线计算出一个和视角相关的高光,此种高光计算方式即为BlinnPhong。
对于Unity的Surface Shader,Unity在Lighting.cginc 中提供了两个BlinnPhong的实现,分别对应于Forward和Deferred渲染路径。其中对应于Forward渲染路径的实现如下:
inline fixed4 LightingBlinnPhong (Surface0utput 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; }
如图所示是BinnPhong文件夹下的场景所展示的一个例子。
相关文章推荐
- UCOSIII同时等待多个内核对象(待更)
- Single Number I+II+III
- 形象一点,view和layer的坐标
- XML中<beans>中属性概述
- log4net 错误日志的使用
- python日志模块----logging
- atoi()函数自实现
- NYOJ 991 Registration system
- UCOSIII消息传递(消息队列)(待更)
- UCOSIII事件标志组(待更)
- 49. Group Anagrams 【M】【47】
- 机器学习常见算法分类汇总
- 给QT不规则窗口添加阴影
- maven(二)创建一个maven的web项目中解决Cannot change version of project facet Dynamic web module to 2.5
- The summary of Java
- 在已经安装cocoa pods的情况下,打开终端给指定工程配置第三方
- pktgen 基本使用
- activiti 设置变量(四)
- 知问前端——创建注册表单
- Vim插件:NERDtree(在Windows下)