现在保存并且编译这个Shader,创建新的material并使用这个shader,将石头的材质贴图和法线图分别拖放到Base和Bump里,再将其应用到石头模型上,应该就可以看到右侧图的效果了。
光照模型
在我们之前的看到的Shader中(其实也就上一节的基本diffuse和这里的normal mapping),都只使用了Lambert的光照模型(#pragma suce surf Lambert),这是一个很经典的漫反射模型,光强与入射光的方向和反射点处表面法向夹角的余弦成正比。关于Lambert和漫反射的一些详细的计算和推论,可以参看wiki(Lambert,漫反射)或者其他地方的介绍。一句话的简单解释就是一个点的反射光强是和该点的法线向量和入射光向量和强度和夹角有关系的,其结果就是这两个向量的点积。既然已经知道了光照计算的原理,我们先来看看如何实现一个自己的光照模型吧。
在刚才的Shader上进行如下修改。
·首先将原来的#pragma行改为这样
·然后在SubShader块中添加如下代码
inline float4 LightingCustomDiffuse (SuceOutput s, fixed3 lightDir, fixed atten) {
float difLight = max(0, dot (s.Normal, lightDir));
float4 col;
col.rgb = s.Albedo * _LightColor0.rgb * (difLight * atten * 2);
col.a = s.Alpha;
return col;
}
·最后保存,回到Unity。Shader将编译,如果一切正常,你将不会看到新的shader和之前的在材质表现上有任何不同。但是事实上我们现在的shader已经与Unity内建的diffuse光照模型撇清了关系,而在使用我们自己设定的光照模型了。
接下来添加的代码是计算光照的实现。shader中对于方法的名称有着比较严的约定,想要创建一个光照模型,首先要做的是按照规则声明一个光照计算的函数名字,即Lighting<Your Chosen Name>。对于我们的光照模型CustomDiffuse,其计算函数的名称自然就是LightingCustomDiffuse了。光照模型的计算是在surf方法的表面颜色之后,根据输入的光照条件来对原来的颜色在这种光照下的表现进行计算,最后输出新的颜色给渲染单元完成在屏幕的绘制。
也许你已经猜到了,我们之前用的Lambert光照模型是不是也有一个名字叫LightingLambert的光照计算函数呢?Bingo。在Unity的内建Shader中,有一个Lighting.cginc文件,里面就包含了LightingLambert的实现。也许你也注意到了,我们所实现的LightingCustomDiffuse的内容现在和Unity内建中的LightingLambert是完全一样的,这也就是使用新的shader的原来视觉上没有区别的原因,因为实现确实是完全一样的。
首先来看输入量,SuceOutput s这个就是经过表面计算函数surf处理后的输出,我们讲对其上的点根据光线进行处理,fixed3 lightDir是光线的方向,fixed atten表示光衰减的系数。在计算光照的代码中,我们先将输入的s的法线(在Normal mapping中的话这个已经是法线图中的对应量了)和输入光线进行点积(dot函数是CG中内置的数学函数,希望你还记得,可以参考这里)。点积的结果在-1至1之间,这个越大表示法线与光线间夹角越小,这个点也就应该越亮。之后使用max来将这个系数结果限制在0到1之间,是为了避免负数情况的存在而导致最终计算的颜色变为负数,输出一团黑,一般来说这是我们不愿意看到的。接下来我们将surf输出的颜色与光线的颜色_LightColor0.rgb(由Unity根据场景中的光源得到的,它在Lighting.cginc中有声明)进行乘积,然后再与刚才计算的光强系数和输入的衰减系数相乘,最后得到在这个光线下的颜色输出(关于difLight * atten * 2中为什么有个乘2,这是一个历史遗留问题,主要是为了进行一些光强补偿,可以参见这里的讨论))。
本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/jisuanjixue/article-48390-8.html
谁告诉你北洋没有一发炮弹击穿击穿主装甲