Unity3D ShaderLab 静态贴图光照模型

Unity3D ShaderLab 静态贴图光照模型

其实在unity的光照模型中,我们可以把光照讯息烘培进入一个2D贴图,来实现着色器的光照效果。

下面是在unity中关闭灯光和打开灯光的对比效果。所以这类着色器的缺点就是不会随着光源变化效果。

Unity3D ShaderLab 静态贴图光照模型

Unity3D ShaderLab 静态贴图光照模型

接下来,我们开始创建,首先通过软件MaCrea来制作我们的2D光照贴图,MaCrea软件

Unity3D ShaderLab 静态贴图光照模型

通过该软件可以快速制作一个完整的发光球体平面图。

软件地址:http://pan.baidu.com/s/1bnD7wkv

软件视频教学地址:http://pan.baidu.com/s/1c0rQDva

完成静态光照贴图的制作后。在unity中创建Shader,Material。

直接打开Shader脚本编辑:

1>Properties:

 Properties {

 _MainTint("Diffuse Color",Color) = (,,,)

 _MainTex ("Base (RGB)", 2D) = "white" {}

 _NormalMap("Normal Map",2D) = ""{}

 }

2>SubShader:

 CGPROGRAM

 #pragma surface surf Unlit vertex:vert

 float4 _MainTint;

 sampler2D _MainTex;

 sampler2D _NormalMap;

 struct Input {

 float2 uv_MainTex;

 float2 uv_NormalMap;

 float3 tan1;

 float3 tan2;

 };

//因为我们要使用单独的球体贴图来实现光照,所以我们无需使用Lambert光照函数,只需要申明自定义无光亮的光照函数;

3>光照函数

 inline fixed4 LightingUnlit(SurfaceOutput s, fixed3 lightDir, fixed3 atten){

 fixed4 c= fixed4(,,,);

 c.rgb = c*s.Albedo;

 c.a = s.Alpha;

 return c;

 }

//我们只希望通过外部物体来产生阴影,因为该着色器不受光源的;

4>计算球面贴图

 void vert(inout appdata_full v, out Input o){

 UNITY_INITIALIZE_OUTPUT(Input, o);

 TANGENT_SPACE_ROTATION ;

 o.tan1 = mul(rotation,UNITY_MATRIX_IT_MV[].xyz);

 o.tan2 = mul(rotation,UNITY_MATRIX_IT_MV[].xyz);

 }

//为了正确的检索到球面贴图,我们需要把正切旋转矩阵乘以当前模型的逆转模型视图;

5>完善surf

 void surf (Input IN, inout SurfaceOutput o) {

 float3 normals = UnpackNormal(tex2D(_NormalMap,IN.uv_NormalMap));

 o.Normal = normals;

 float2 litSphereUV;

 litSphereUV.x = dot(IN.tan1,o.Normal);

 litSphereUV.y = dot(IN.tan2,o.Normal);

 half4 c = tex2D (_MainTex, litSphereUV*0.5+0.5);

 o.Albedo = c.rgb*_MainTint;

 o.Alpha = c.a;

 }

通过以上的步骤,我们完成这个静态的光照模型。返回unity中简单设置后,就可以看出效果了。

Unity3D ShaderLab 静态贴图光照模型

在上面的过程中,最主要的是vert函数,因为在这个函数里,我们把旋转切向量和逆转模型视图矩阵相乘,在赋值给o.tan1和o.tan2。

这个计算就是把向量弯曲到何时的位置来检索球面的贴图。而逆转模型视图则是我们利用unity内置的值。

通过上面的检索传递后,我们简单的将IN.tan1和IN.tan2的值作为球面贴图纹理检索的uv值,

我们可以直接使用input结构体中的值,因为我们也在vert函数中将这些值传递进去了。

 Shader "91YGame/LightStatic" {
Properties {
_MainTint("Diffuse Color",Color) = (,,,)
_MainTex ("Base (RGB)", 2D) = "white" {}
_NormalMap("Normal Map",2D) = ""{}
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD CGPROGRAM
#pragma surface surf Unlit vertex:vert float4 _MainTint;
sampler2D _MainTex;
sampler2D _NormalMap; struct Input {
float2 uv_MainTex;
float2 uv_NormalMap;
float3 tan1;
float3 tan2;
}; inline fixed4 LightingUnlit(SurfaceOutput s, fixed3 lightDir, fixed3 atten){
fixed4 c= fixed4(,,,);
c.rgb = c*s.Albedo;
c.a = s.Alpha;
return c;
} void vert(inout appdata_full v, out Input o){
UNITY_INITIALIZE_OUTPUT(Input, o); TANGENT_SPACE_ROTATION;
o.tan1 = mul(rotation,UNITY_MATRIX_IT_MV[].xyz);
o.tan2 = mul(rotation,UNITY_MATRIX_IT_MV[].xyz);
} void surf (Input IN, inout SurfaceOutput o) {
float3 normals = UnpackNormal(tex2D(_NormalMap,IN.uv_NormalMap));
o.Normal = normals; float2 litSphereUV;
litSphereUV.x = dot(IN.tan1,o.Normal);
litSphereUV.y = dot(IN.tan2,o.Normal); half4 c = tex2D (_MainTex, litSphereUV*0.5+0.5);
o.Albedo = c.rgb*_MainTint;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}
上一篇:Unity3D ShaderLab 漫反射卷积光照模型


下一篇:Unity3D ShaderLab Half Lambert光照模型