Unity3D ShaderLab 静态贴图光照模型

来源:互联网 发布:从化数据 编辑:程序博客网 时间:2024/04/29 21:42
其实在unity的光照模型中,我们可以把光照讯息烘培进入一个2D贴图,来实现着色器的光照效果。
    更多精彩请关注【狗刨学习网】

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

      
         

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

      

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

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

直接打开Shader脚本编辑:
1>roperties:
  1. <font face="新宋体" size="2">1 Properties {

  2. 3 _MainTint("Diffuse Color",Color) = (1,1,1,1)

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

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

  5. 9 }</font>
复制代码


2>SubShader:
  1. <font face="新宋体" size="2"> 1 CGPROGRAM

  2. 3 #pragma surface surf Unlit vertex:vert

  3. 5  

  4. 7 float4 _MainTint;

  5. 9 sampler2D _MainTex;
  6. 10 
  7. 11 sampler2D _NormalMap;
  8. 12 
  9. 13 struct Input {
  10. 14 
  11. 15 float2 uv_MainTex;
  12. 16 
  13. 17 float2 uv_NormalMap;
  14. 18 
  15. 19 float3 tan1;
  16. 20 
  17. 21 float3 tan2;
  18. 22 
  19. 23 };</font>
复制代码
//因为我们要使用单独的球体贴图来实现光照,所以我们无需使用Lambert光照函数,只需要申明自定义无光亮的光照函数;

3>光照函数
  1. <font face="新宋体" size="2"> 1 inline fixed4 LightingUnlit(SurfaceOutput s, fixed3 lightDir, fixed3 atten){

  2. 3 fixed4 c= fixed4(1,1,1,1);

  3. 5 c.rgb = c*s.Albedo;

  4. 7 c.a = s.Alpha;

  5. 9 return c;
  6. 10 
  7. 11 }</font>
复制代码
//我们只希望通过外部物体来产生阴影,因为该着色器不受光源的;

4>计算球面贴图
  1. <font face="新宋体" size="2"> 1 void vert(inout appdata_full v, out Input o){

  2. 3 UNITY_INITIALIZE_OUTPUT(Input, o);

  3. 5  

  4. 7 TANGENT_SPACE_ROTATION ;

  5. 9 o.tan1 = mul(rotation,UNITY_MATRIX_IT_MV[0].xyz);
  6. 10 
  7. 11 o.tan2 = mul(rotation,UNITY_MATRIX_IT_MV[1].xyz);
  8. 12 
  9. 13 }</font>
复制代码
//为了正确的检索到球面贴图,我们需要把正切旋转矩阵乘以当前模型的逆转模型视图;

5>完善surf
  1. <font face="新宋体" size="2">1 void surf (Input IN, inout SurfaceOutput o) {

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

  3. 5 o.Normal = normals;

  4. 7  

  5. 9 float2 litSphereUV;
  6. 10 
  7. 11 litSphereUV.x = dot(IN.tan1,o.Normal);
  8. 12 
  9. 13 litSphereUV.y = dot(IN.tan2,o.Normal);
  10. 14 
  11. 15  
  12. 16 
  13. 17 half4 c = tex2D (_MainTex, litSphereUV*0.5+0.5);
  14. 18 
  15. 19 o.Albedo = c.rgb*_MainTint;
  16. 20 
  17. 21 o.Alpha = c.a;
  18. 22 
  19. 23 }</font>
复制代码

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

      

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

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

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

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

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