Unity3D ShaderLab 静态贴图光照模型

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

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

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

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

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

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

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

直接打开Shader脚本编辑:

1>Properties:

1 Properties {
2
3 _MainTint("Diffuse Color",Color) = (1,1,1,1)
4
5 _MainTex ("Base (RGB)", 2D) = "white" {}
6
7 _NormalMap("Normal Map",2D) = ""{}
8
9 }

2>SubShader:

 1 CGPROGRAM
 2
 3 #pragma surface surf Unlit vertex:vert
 4
 5
 6
 7 float4 _MainTint;
 8
 9 sampler2D _MainTex;
10
11 sampler2D _NormalMap;
12
13 struct Input {
14
15 float2 uv_MainTex;
16
17 float2 uv_NormalMap;
18
19 float3 tan1;
20
21 float3 tan2;
22
23 };

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

3>光照函数

 1 inline fixed4 LightingUnlit(SurfaceOutput s, fixed3 lightDir, fixed3 atten){
 2
 3 fixed4 c= fixed4(1,1,1,1);
 4
 5 c.rgb = c*s.Albedo;
 6
 7 c.a = s.Alpha;
 8
 9 return c;
10
11 }

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

4>计算球面贴图

 1 void vert(inout appdata_full v, out Input o){
 2
 3 UNITY_INITIALIZE_OUTPUT(Input, o);
 4
 5
 6
 7 TANGENT_SPACE_ROTATION ;
 8
 9 o.tan1 = mul(rotation,UNITY_MATRIX_IT_MV[0].xyz);
10
11 o.tan2 = mul(rotation,UNITY_MATRIX_IT_MV[1].xyz);
12
13 }

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

5>完善surf

 1 void surf (Input IN, inout SurfaceOutput o) {
 2
 3 float3 normals = UnpackNormal(tex2D(_NormalMap,IN.uv_NormalMap));
 4
 5 o.Normal = normals;
 6
 7
 8
 9 float2 litSphereUV;
10
11 litSphereUV.x = dot(IN.tan1,o.Normal);
12
13 litSphereUV.y = dot(IN.tan2,o.Normal);
14
15
16
17 half4 c = tex2D (_MainTex, litSphereUV*0.5+0.5);
18
19 o.Albedo = c.rgb*_MainTint;
20
21 o.Alpha = c.a;
22
23 }

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

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

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

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

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

 1 Shader "91YGame/LightStatic" {
 2     Properties {
 3         _MainTint("Diffuse Color",Color) = (1,1,1,1)
 4         _MainTex ("Base (RGB)", 2D) = "white" {}
 5         _NormalMap("Normal Map",2D) = ""{}
 6     }
 7     SubShader {
 8         Tags { "RenderType"="Opaque" }
 9         LOD 200
10
11         CGPROGRAM
12         #pragma surface surf Unlit vertex:vert
13
14         float4 _MainTint;
15         sampler2D _MainTex;
16         sampler2D _NormalMap;
17
18         struct Input {
19             float2 uv_MainTex;
20             float2 uv_NormalMap;
21             float3 tan1;
22             float3 tan2;
23         };
24
25
26
27         inline fixed4 LightingUnlit(SurfaceOutput s, fixed3 lightDir, fixed3 atten){
28             fixed4 c= fixed4(1,1,1,1);
29             c.rgb = c*s.Albedo;
30             c.a = s.Alpha;
31             return c;
32         }
33
34         void vert(inout appdata_full v, out Input o){
35             UNITY_INITIALIZE_OUTPUT(Input, o);
36
37             TANGENT_SPACE_ROTATION;
38             o.tan1 = mul(rotation,UNITY_MATRIX_IT_MV[0].xyz);
39             o.tan2 = mul(rotation,UNITY_MATRIX_IT_MV[1].xyz);
40         }
41
42         void surf (Input IN, inout SurfaceOutput o) {
43             float3 normals = UnpackNormal(tex2D(_NormalMap,IN.uv_NormalMap));
44             o.Normal = normals;
45
46             float2 litSphereUV;
47             litSphereUV.x = dot(IN.tan1,o.Normal);
48             litSphereUV.y = dot(IN.tan2,o.Normal);
49
50             half4 c = tex2D (_MainTex, litSphereUV*0.5+0.5);
51             o.Albedo = c.rgb*_MainTint;
52             o.Alpha = c.a;
53         }
54         ENDCG
55     }
56     FallBack "Diffuse"
57 }
时间: 2024-10-06 15:07:29

Unity3D ShaderLab 静态贴图光照模型的相关文章

Unity3D ShaderLab 使用贴图对模型的高光进行遮罩

Unity3D ShaderLab 使用贴图对模型的高光进行遮罩 前面研究了高光效果的实现,再说说现很多游戏用到的高光贴图技术,因为它可以让3D美工更容易控制最终的视觉效果. 这也就为我们提供了另外的方式,我们可以在同一个着色器上实现垫型表面和光亮表面,也可以使用贴图来控制镜面高光的范围或者高光强度, 以实现一个表面是广泛的镜面高光而另一面确是细小的高光. 新建一个shader,一个材质球.老规矩双击shader脚本,在编辑器中编写代码吧. 1.Properties: Properties {

Unity3D ShaderLab法线贴图

Unity3D ShaderLab法线贴图 说到法线贴图,应该算是我们最常使用的一种增强视觉效果的贴图.将法线贴图的各个像素点座位模型的法线,这样我们的光照可以模拟出高分辨率的效果, 同时也保持较低的多边形数.法线贴图通常存储在一个普通的rgb图片,他的rgb分量分别对应了曲面法线的xyz坐标. 在Unity中,会通过UnpackNormals()函数来使用法线贴图,这使得在表面着色范围内为我们的着色器添加使用法线的过程变得更容易. 首先,创建一个shader和材质球.我们开始修改shader代

Unity3D ShaderLab 立方体图的菲涅尔反射

Unity3D ShaderLab 立方体图的菲涅尔反射 菲涅尔反射是反射类型中比较常见的一种类型,当我们的视线正对物体表面,那么反射量会明显增加, 我们几乎可以在任何支持反射类型的物体表面看到这种情况,我们接下来就来实现这种反射效果过. 还是先创建Shader和 Material,沿用上一节的立方体图.代码变动较少,直接看下面的完成代码: code start -------------------------------------------------------------------

Unity3D ShaderLab 简单的立方体图反射

Unity3D ShaderLab 简单的立方体图反射 反射是着色器模拟现实环境的一个关键因素,它能使我们的着色器渲染效果更加具备视觉冲击,因为他利用了我们周围的环境, 让着色器反射外界的场景信息并将他们反射到材质表面来模拟外部环境,所以我们会使用立方图[CubeMap]的6张纹理来模拟环境的色彩情况. 首先,创建Shader,创建材质球,准备立方图,双击Shader,进入代码编辑器. 从Properties 到CGPROGRAM,再到surf,本次功能较为简单,先看代码. code start

Unity3D ShaderLab 立方体图的反射遮罩

Unity3D ShaderLab 立方体图的反射遮罩 上一篇,简单的介绍了立方体图的反射,那么我们能不能使用一张问题对其进行指定遮罩呢?这样美工可以更好的控制图像的效果. 我们接着使用上一篇的shader代码,新建一个材质球,本次修改也是数行代码而已,所以 直接看完成代码. code start -------------------------------------------------------------------- Shader "91YGame/CubeMask" 

Unity3D ShaderLab立方体图的法线渲染

Unity3D ShaderLab立方体图的法线渲染 某些情况下,我们希望立方体图的材质球上产生法线效果,来更多的表现细节,比如菱形花纹的玻璃,冰块的表面. 在帧数的协调下,我们可以通过input结构体的另一个内置参数来传递我们的法线贴图.下面 我们就一步步实现. 首先,新建Shader,在新建材质球,准备立方体图,法线贴图.双击shader进入脚本编辑. 本次的代码修改依然是和之前的立方体图的反射遮罩差不多,所以就直接看完成的代码吧. code start ------------------

Unity3D ShaderLab 使用渐变纹理着色

Unity3D ShaderLab 使用渐变纹理着色 在我们编写着色器的过程中,还可以通过渐变纹理来控制漫反射的光照颜色.这种做法同样在VALVE的军团要塞2中及其流行. 前期,请准备一个渐变色的图片.再把我们之前的Hlf Lambert的代码稍加修改. 1:Properties添加GUI上的图片纹理属性>_RampTex ("Ramp Texture", 2D) = "" 2:在SubShader中申明图片纹理>sampler2D _RampTex;

Unity3D ShaderLab 各向异性高光

Unity3D ShaderLab 各向异性高光 各向异性时一种模拟物体表面沟槽方向性的高光反射类型,它会修改或延伸垂直方向上的高光.当我们想模拟金属拉丝高光的时候,它非常适合.下面就一步一步实现. 首先创建Shader,再创建材质球.然后双击Shader 打开编辑器. 1:修改Properties Properties { //添加属性; _MainTint("Diffuse Tint",Color)=(1,1,1,1) _MainTex ("Base (RGB)"

Unity3D ShaderLab 透明裁剪着色器

Unity3D ShaderLab 透明裁剪着色器 上一篇,我们介绍了使用Alpha实现透明的手法,其实Unity为我们的#pragma提供了另一种参数,是我们能做出更高效 简单的透明效果,也就是裁剪透明. 这种透明使用一个值来简单的控制某些特定的像素无需渲染到屏幕上,所以我们也可以通过他实现一个要么完全透明或完全不透的着色器. 我们即将利用灰度的值来控制材质的透明度. 准备工作还是新建Shader Material,一张灰度变化图.同样是分分钟完成的代码,请看完成: Shader "91YGa