开启辅助访问
 找回密码
 注册帐号

扫一扫,访问微社区

教程分享

关注:577

当前位置:游戏蛮牛 技术专区 教程分享

查看: 748|回复: 5

[自学总结] 【Unity Shaders】之SurfaceShader(四)用纹理改善漫反射

[复制链接]  [移动端链接]
5熟悉之中
939/1000
排名
3170
昨日变化
3

188

主题

224

帖子

939

积分

Rank: 5Rank: 5

UID
128653
好友
0
蛮牛币
2017
威望
0
注册时间
2015-11-12
在线时间
124 小时
最后登录
2017-2-21
发表于 2016-8-18 10:41:02 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?注册帐号

x

上篇做的HalfLambert的效果是这样的:

1.png

我们看到,亮部到暗部没有自然的过渡,暗部直接涂成深灰。就像初学者画的素描,直接将暗部涂黑,没有变化。

这是因为这种光照计算太简单了,现实生活中,暗部因为漫反射的存在不会像画面上那么暗。但如果要引入光照计算的话,那太复杂了,我们可以用纹理来改善它。

因为我们需要一张纹理贴图,先在Properties里声明纹理:

[C#] 纯文本查看 复制代码
_RampTex ("Ramp Texture", 2D) = "white"{}


然后再CGPROGRAM里声明一个同名变量:

sampler2D _RampTex;

最后只要稍微改改HalfLambert光照模型:

[C#] 纯文本查看 复制代码
// add this line
float3 ramp = tex2D(_RampTex, float2(hLambert,hLambert)).rgb;
......
// modify this line
col.rgb = s.Albedo * _LightColor0.rgb * ramp;


将修改后的材质赋予小球,贴上这张贴图:

2.png

看看效果:

3.png

光影效果是不是真实了许多?

这是因为我们将这张贴图根据反射光强映射到小球上,改变了小球反射的颜色。

现在我们来做一个实验,跟着我来:

修改这句:

[C#] 纯文本查看 复制代码
// float hLambert = 0.5 * difLight + 0.5;
float hLambert = difLight;


也就是不要使用半兰伯特光照。看看结果:

4.png

变成了这样子。再继续修改这句:

[C#] 纯文本查看 复制代码
float hLambert = 0.9 * difLight;


映射在球上的贴图移动了一点点对不对?

然后继续修改,把0.9改为0.8,观察效果,把0.8改为0.7,观察效果,把0.7改为0.6,观察效果……

我们看到,贴图一点点地往上移,你们发现了什么吗?在我们把数值一点点改小的过程中,小球光照最亮的点的值由1慢慢变小,对应地,最亮的点由白色渐渐变成了蓝灰色,当把数值调为0.1的时候,变成了橙黄色。而那张贴图,最左侧是黄色,中间是蓝灰色,右侧是蓝白色,如果用坐标表示纹理的话,最左侧应该是0,中间是0.5,右侧是1.所以纹理的映射关系你清楚了吗?当小球最亮点的值是0.5的时候,它映射的就是贴图中央的部分,也就呈现蓝灰色。所以你们应该清楚这张贴图是如何映射在小球身上从而改善光影效果的了吧。经过半兰伯特光照的改善,原来光照为0的地方变成了0.5,所以映射的是纹理的中间部分,呈渐变的蓝灰色,原来光照为-1的地方变成了0,映射的是纹理左侧的橙色部分,如果你仔细观察,可以看到在小球接近地面的地方颜色有些泛黄,也就是纹理左侧的颜色。

学过素描的人知道,明暗交界线的地方是最暗的,背光面因为反光的原因,会亮一点,这样画出来的阴影就不会一片死黑,而是通透,接近真实。看下图:

5.png

所以贴图的中部颜色最深,是暗灰,模拟的是明暗交界处的颜色(也就是原先光照为0的地方经过改善变成了0.5),右侧的渐变模拟的是亮部的颜色,左侧的渐变模拟的是暗部因为反光而变亮一些的颜色。

这样的效果还是不能使我们满意,阴影的效果还是不够柔和。

假的BRDF

BRDF是bidirectional reflectance distribution function的简写,意思是双向反射分布函数。

之前我们都只考虑了入射光的方向,这样我们只能得到一个线性的结果。实际上,一个表面上的一点,由于观察方向不同,看到的效果是不同的。因为不同的角度,光线反射进眼里的强弱不同,颜色也不同。所以我们要引进一个新的变量,viewDir,它是人眼看向物体的方向。也就是说对于表面上某个点的颜色的计算,我们要考虑两个方向,光照方向和观察方向。可以简单地理解为入射光在不透明的物体表面同时反射到观察方向和出射光两个方向。

好了,直接上代码,不一句句地修改了:

[C#] 纯文本查看 复制代码
inline float4 LightingHalfLambert (SurfaceOutput s, fixed3 lightDir, half3 viewDir, fixed atten){
    float difLight = dot (s.Normal, lightDir);
    float rimLight = dot (s.Normal, viewDir);
    float dif_hLambert = 0.5 * difLight + 0.5;
    float rim_hLambert = 0.5 * rimLight + 0.5;
    float3 ramp = tex2D(_RampTex, float2(dif_hLambert, rim_hLambert)).rgb;

    float4 col;
    col.rgb = s.Albedo * _LightColor0.rgb * ramp;
    col.a = s.Albedo;
    return col;
}


在光照模型函数里我们新增了一个变量half3 viewDir,它就是观察方向,在函数里面,我们定义了一个新的变量float rimLight,同样对它与法线方向点积,然后用HalfLambert优化,最后将dif_hLambert和rim_hLambert作为uv坐标传入tex2D函数。

将新的材质赋予小球,贴上这张贴图:

6.png

我们来看看效果:

7.png

你们可以将Slider的数值调大一点,然后给球一个颜色,看看效果,再和原先的材质比较一下。

8.png

看看对比,左边是上一个只考虑光照方向的材质,右边是BRDF材质。左边很简单地区分了亮面和暗面,好像直接画了条圆弧区分了明暗交界线,而右侧的明暗过渡更为柔和和富于变化。
我们先来分析一下纹理的映射关系:

纹理的左下角坐标是(0,0),右上角坐标是(1,1),左上角坐标是(0,1),右下角坐标是(1,0)。

左下角对应着光照最弱且离人视线最远的地方,也就是小球接近地面的那个区域,对应纹理的黑色;右上角对应着光照最强且离人视线最近的地方,就是大概在小球高光附近的区域,对应纹理颜色最白的地方;左上角对应着光照最弱但离人视线最近的地方,也就是没上色的效果图里有点泛红的区域;右下角对应着光照最强但离人视线最远的地方,也就是小球靠近光源的边缘区域,我们看到没上色的图里它有些泛蓝。

实际上,图的右上角到左下角对应的就是光照方向,左上角到右下角对应的就是观察方向:

9.png

观察方向和平面法向量点积的结果如图:

10.png

意思就是说,离人视线越近的地方越亮,越远的地方越暗。

这和素描关系也是一样的,只考虑光照方向画出来的阴影就像上一个shader那样,不够立体,这是因为只考虑光照方向的体积,同时考虑的视线方向,小球才会更有立体感。

之所以用小球来演示shader是因为小球更容易看出光影的关系,素描第一课都是画球嘛。

其实shader和画画确实是一样的,只不过一个是用笔在纸上画出想要的结果,一个是用代码“画出”想要的结果~

附:代码

游客,如果您要查看本帖隐藏内容请回复

回复

使用道具 举报

3偶尔光临
222/300
排名
15939
昨日变化
12

0

主题

23

帖子

222

积分

Rank: 3Rank: 3Rank: 3

UID
156804
好友
0
蛮牛币
186
威望
0
注册时间
2016-7-14
在线时间
181 小时
最后登录
2017-2-16
发表于 2016-8-18 15:13:54 | 显示全部楼层
谢谢分享

回复

使用道具 举报

5熟悉之中
837/1000
排名
1942
昨日变化
8

2

主题

84

帖子

837

积分

Rank: 5Rank: 5

UID
119306
好友
1
蛮牛币
1682
威望
0
注册时间
2015-8-23
在线时间
259 小时
最后登录
2017-2-21
发表于 2016-8-31 14:38:53 | 显示全部楼层
谢谢分享

回复

使用道具 举报

6蛮牛粉丝
1227/1500
排名
1237
昨日变化
1

0

主题

201

帖子

1227

积分

Rank: 6Rank: 6Rank: 6

UID
130905
好友
0
蛮牛币
3042
威望
0
注册时间
2015-12-4
在线时间
362 小时
最后登录
2017-2-20
发表于 2016-10-15 15:37:58 | 显示全部楼层
谢谢分享

回复

使用道具 举报

排名
32558
昨日变化
29

0

主题

5

帖子

16

积分

Rank: 1

UID
177092
好友
0
蛮牛币
5
威望
0
注册时间
2016-10-20
在线时间
7 小时
最后登录
2016-12-18
发表于 2016-10-21 14:20:59 | 显示全部楼层
非常好的的资源  感谢楼主
[发帖际遇]: lifei526362 乐于助人,奖励 1 蛮牛币. 幸运榜 / 衰神榜

回复 支持 反对

使用道具 举报

排名
15939
昨日变化
12

0

主题

32

帖子

91

积分

Rank: 2Rank: 2

UID
18066
好友
0
蛮牛币
142
威望
0
注册时间
2014-3-18
在线时间
39 小时
最后登录
2017-2-21
发表于 2016-12-21 10:39:00 | 显示全部楼层
学习了 谢谢分享

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册帐号

本版积分规则

快速回复 返回顶部 返回列表