首先我们在Unity中创建一个小球
然后通过"Create->Shader->Standard Surface Shader"创建一个表面着色器,并修改名字为Diffuse Bump
然后通过"Create->Material"创建一个材质,并修改名字为MaterialDiffuseBump,材质使用的shader指定为我们刚创建的Diffuse Bump
下面是Shader代码:
Shader "Custom/Diffuse Bump" {
//属性域
Properties {
//主纹理属性
_MainTex ("Texture", 2D) = "white" {}
//法线贴图纹理属性
_BumpMap ("Bumpmap", 2D) = "bump" {}
}
//Shader执行域
SubShader {
//标明渲染类型是不透明的物体
Tags { "RenderType" = "Opaque" }
//标明CG程序的开始
CGPROGRAM
//声明表面着色器函数
#pragma surface surf Lambert
//定义着色器函数输入的参数Input
struct Input {
//主纹理坐标值
float2 uv_MainTex;
//法线贴图坐标值
float2 uv_BumpMap;
};
//声明对主纹理图片的引用
sampler2D _MainTex;
//声明对法线贴图的引用
sampler2D _BumpMap;
//表面着色器函数
void surf (Input IN, inout SurfaceOutput o) {
//赋值颜色信息
o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
//赋值法线信息
o.Normal = UnpackNormal (tex2D (_BumpMap, IN.uv_BumpMap));
}
//标明CG程序的结束
ENDCG
}
}
首先我们来看看这段代码在unity的Inspector面板中我们都能看到什么:
我们看到了有两张纹理贴图的接口。
我们来看一下这段代码和我们之前的一节
Surface Shader中的代码不同的部分,相同的部分我们不做重复的讲解。
首先在属性域Properties多了一句代码:
_BumpMap ("Bumpmap", 2D) = "bump" {}
属性名字是_BumpMap ,类型是2D的,也就是表示2D纹理的,默认值是bump,也就是凹凸的。我们可以在unity的Inspector面板中看到这个属性就是第二张纹理贴图,也就是我们的法线贴图。
然后再SubShader中我们定义的结构体Input中多了一个变量uv_BumpMap,这个变量用来保存法线贴图中的坐标。
struct Input {
float2 uv_MainTex;
float2 uv_BumpMap;
};
然后我们声明了一个对法线贴图属性
_BumpMap的引用:
sampler2D _BumpMap;
最后我们在表面着色器函数surf中把传入点的法线信息赋值给
输出的像素法线信息。
我们看到这里出现了一个我们没见过了UnpackNormal,它表示:
代码分析完了,我们来看一下效果
我们把材质MaterialDiffuseBump赋值给我们创建的小球
我这里有一张板砖的贴图,和板砖的法线贴图
我们先只把板砖贴图赋值材质MaterialDiffuseBump对应的属性中
我们来看看小球的效果,我们在场景中创建一个Directional light光源
我们把板砖的法线贴图赋值给材质MaterialDiffuseBump
我们再来看一下小球的效果
虽然凹凸感变强了,但我们法线小球变暗了,这是因为法线贴图影响到了光照的计算,我们会在下一节中讲解怎么是小球的边缘亮起来。