Unity shader 官网文档全方位学习(二)Lighting model及自定义Lighting model

来源:互联网 发布:中国云计算企业排名 编辑:程序博客网 时间:2024/06/10 04:17

原文地址  http://www.kankanews.com/ICkengine/archives/85875.shtml


上文咱们学了surface shader。这玩意在开始的时候啊,在定义哪个函数处理surface时用一定要指定Lighting model(即光照模型)的。自带的是Lambert和BlinnPhong.本文首先对这两个进行说明,后面讲解如何自定义光照模型及对官方实例的解析。http://docs.unity3d.com/Documentation/Components/SL-SurfaceShaderLighting.html

一、简单光反射模型

1.反射,其实就是光照到物体上,然后再由物体反射出去。这种过程就叫反射。

2.漫反射,物体表面可能是不光滑的,因此自然法线就不是均匀的,那么这种情况下,当几条平行光照向物体时,反射回来的光线就不再是平行的了,这种情况叫漫反射。

3.镜面反射:与漫反射对应,如果物体表面光滑,即法线均匀(不一定都平行,会有曲面的情况),则反射回来的也是均匀的,这种情况叫镜面反射。

4.环境光:光线照到指定物体的周围物体,这时指定物体上有光线反射到,这种光可称为环境光或泛光。

5.光照 = 反射光 + 镜面光 + 环境光 + 自发光。

对于简单光反射模型: 入射光 = 反射光 + 吸引光。而实际上来说还需要加上投射光与散射光。

二、Lambert和BlinnPhong

1.冯式反射模型:Phong reflection 是一种将漫反射与镜面反射进行关联在一些的反射方法。

2.Lambert:一种主要应用于漫反射的光照模型。

3.BlinnPhong: 一种主要应用于镜面反射的光照模型。

三、自定义光照模型

1.规则:定义一个函数,必须以 Lighting开头,可以写在shader文件里的任意位置或其他include的文件。
=>half4 LightingName (SurfaceOutput s, half3 lightDir, half atten);  这种是无viewDir,在上文中有说到viewDir就是返回给视角的方向,不用依赖此值,就类似于漫反射的效果。因为漫反射中出来的光线是由不规则的表面来决定。

=>half4 LightingName (SurfaceOutput s, half3 lightDir, half3 viewDir, half atten); 这个方法是相对于上面的,需要依赖于viewDir。

=>half4 LightingName_PrePass (SurfaceOutput s, half4 light); 这个方法是可选的,如果需要光照延时(deferred),就加上此方法,不写则全部采用快速光照(forward)

2.自定义解码光照

注意,如果使用了LightingName_PrePass,则光照解码的方法在此方法之前,因此是有了光照延时。具体会针对与SingleLightMapping、DualLightMapping和StandardLightMapping三种的方法,与LightMapping的定义函数类似,具体的这里不介绍,可参考官方文档:http://docs.unity3d.com/Documentation/Components/SL-SurfaceShaderLighting.html

三、实例学习

1.自定义一个简单的漫反射光照模型:

#pragma surface surf SimpleLambert  //1half4 LightingSimpleLambert (SurfaceOutput s, half3 lightDir, half atten) { //2    half NdotL = dot (s.Normal, lightDir);  //3    half4 c;   //4    c.rgb = s.Albedo * _LightColor0.rgb * (NdotL * atten * 2);  //5    c.a = s.Alpha; //6    return c; //7}

//1: 定义使用SimpleLambert做为光照模型

//2: 光照模型的定义。这里说说atten,根据atten的意思(衰减器),可以理解到,这个参数就是光照的衰减值。

//3:算一点积,光照方向与法线的点积,可理解为光照与法线的夹角。

//4:定义输出的颜色四元组。

//5:光照的颜色 = 物体反射颜色 * 原光的颜色* 经过折射的衰减颜色。_LightColor0是在Lighting.cginc 里定义的,我理解成反射光的颜色。另外还有一个_SpecColor,对应是镜面反射光的颜色。此处由于资料稀缺,全部个人的学习所得,如有错误,欢迎指出!

//6:设置光的透明与反射透明一致。

//7:返回。

效果:

2.Diffuse wrap

#pragma surface surf WrapLamberthalf4 LightingWrapLambert (SurfaceOutput s, half3 lightDir, half atten) {    half NdotL = dot (s.Normal, lightDir);    half diff = NdotL * 0.5 + 0.5;  //!    half4 c;    c.rgb = s.Albedo * _LightColor0.rgb * (diff * atten * 2);    c.a = s.Alpha;    return c;}

此1不同的只是//! 处,这里算得一个diff,目的是将原得出的点积单位从[-1,1]转换成[0,1]之间。

这样做的用法,在各方问人,加上自己思想,想到的是将所有的坐标转成正值,这样,在其接受到光源反射的所有地方都会有光,这样使得光照的范围扩大了不少。

3.Toon Ramp

#pragma surface surf Rampsampler2D _Ramp;half4 LightingRamp (SurfaceOutput s, half3 lightDir, half atten) {    half NdotL = dot (s.Normal, lightDir);    half diff = NdotL * 0.5 + 0.5;    half3 ramp = tex2D (_Ramp, float2(diff)).rgb;  //1    half4 c;    c.rgb = s.Albedo * _LightColor0.rgb * ramp * (atten * 2);    c.a = s.Alpha;    return c;}

这里对比于2,把本来是固定的diff,再加上一个材质。

//1中,直接将diff强转成float2的坐标系,向_Ramp的材质中查找出相应的rgb。最终也以此rgb值及其他光照值得出光照的rgb值。这种效果可以考虑来做光晕。这里我用一张具体的图,以float2(diff)为uv找的效果会有点奇怪。不过现象可以反映出来。

效果:

4.Simple Specular

#pragma surface surf SimpleSpecularhalf4 LightingSimpleSpecular (SurfaceOutput s, half3 lightDir, half3 viewDir, half atten) {     half3 h = normalize (lightDir + viewDir);     half diff = max (0, dot (s.Normal, lightDir));     float nh = max (0, dot (s.Normal, h));     float spec = pow (nh, 48.0);     half4 c;     c.rgb = (s.Albedo * _LightColor0.rgb * diff + _LightColor0.rgb * spec) * (atten * 2);     c.a = s.Alpha;     return c;}

这个例子是自定义一个镜面反射的例子。c.rgb 的组成可拆成一个漫反射和一个镜面反射的组合。

c.rgb = (s.Albedo * _LightColor0.rgb * diff * (atten * 2)) + (_LightColor0.rgb * spec * (atten * 2));   

前半段就是漫反射,不讲了。后面半段区别用到了镜面反射值。而这个值来自于:

float nh = max (0, dot (s.Normal, normalize (lightDir + viewDir)));

首先,光的方向和视角方向都是决定镜面反射的重要因素,不能没lightDir,否则镜面反射则只跟视角来了,那样是不现实的。因此此处需要让两个方向的向量之和与表面法线进行点积。这个nh范围是在大于0的。由于两个单位向量点积,因此得出的值则是 0到1之间。

后面取pow是为了放小nh的值,其值越小,则镜面反射就越小。

上效果:



0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 米饭卡在喉咙里了怎么办 喉咙里卡了米饭怎么办 孕妇吃了坏鹅蛋怎么办 1岁大宝宝长短腿怎么办 行测中的判断推理怎么办 塑料盖子玻璃罐头瓶子打不开怎么办 猪肉烫火锅吃怎么办料 自制腊肠放干了怎么办 孕妇吃了4块腊肉怎么办 衣服沾了火锅味怎么办 皮包上有火锅味怎么办 芝士年糕裂开了怎么办 制作牛肉酱咸了怎么办 腌牛肉太咸了怎么办 八宝粥的拉环断了怎么办 八宝粥易拉罐拉环断了怎么办 吃完辣的胃难受怎么办 天天呆在家很烦怎么办 吃多了荔枝上火怎么办 猛犸牙牌子裂了怎么办 玩游戏电脑卡了怎么办 电脑打开卡在选项界面怎么办? 红警突然卡死怎么办 柯基不吃狗粮怎么办 貔貅嘴巴磕破了怎么办 开光貔貅牙磕了怎么办 玉貔貅鼻子碎了怎么办 开光的貔貅摔坏了怎么办 貔貅摔坏了耳朵怎么办? 貔貅摔坏了一点点怎么办 天猫删评价扣4分怎么办 暴风影音下载电视剧下载不了怎么办 fm2017引援电脑买了怎么办 退休时医保不够二十年怎么办 和的面迟迟不发怎么办 做面条的面发了怎么办 发不起来的面团怎么办 如果婚后买房离婚后财产怎么办 空腹体检前喝水了怎么办 莆田市风俗婴儿死了怎么办后事 上司给你换不好岗位怎么办