当前位置:   article > 正文

Unity Shader零基础入门4:纹理贴图与法线贴图_纹理贴图和法线贴图

纹理贴图和法线贴图

纹理贴图:让模型拥有色彩、花纹等。

法线贴图:为减少资源消耗,模型本身的细节是比较少的。法线贴图可以增加模型的细节,让模型的表面出现更多的细节、阴影等。法线贴图一般是在切线空间下的,以便适合不同模型。如果是在模型空间下的,则只能配合对应的模型使用。切线空间的法线贴图看起来主要是蓝色,而模型空间的看起来五颜六色。

uv坐标: 纹理坐标又称为uv坐标。u、v分别代表横轴、纵轴。贴图左下为原点,范围为0-1。比如贴图右上角为(1,1)。

贴图的平铺和偏移:

纹理贴图和法线贴图的属性:Tiling-平铺;Offset-平移;

Tiling能让贴图变为重复的多份。比如设置为x=1,y=2,则x方向不变,y方向变成重复平铺的两份,各占一半高度。如果要使用Tiling让贴图重复平铺,需要贴图文件的Wrap Mode设置为Repeat。

Offset自然是让贴图平移偏离原位置。

本文所需要的素材包下载:

链接:https://pan.baidu.com/s/1JOSWNaT9APrw25C8geYwhA
提取码:wwic

 下载后导入到工程中。之后用包内的预制体在场景中生成一个模型。

 然后我们新建一个材质并给模型替换上新材质。

之后创建一个Shader文件(Standard Surface Shader),并修改内容如下:

  1. Shader "Tutorial/04Texture"{
  2. Properties{
  3. //调整纹理贴图的颜色用
  4. _Color("Color",Color)=(1,1,1,1)
  5. //纹理贴图
  6. _MainTex("MainTex",2D)="white"{}
  7. //法线贴图。这里不能用"white"而要用"bump"表示没有法线贴图时默认使用模型本身的法线
  8. _NormalMap("NormalMap",2D)="bump"{}
  9. //控制使用法线贴图的法线的比例。如果为1则完全使用法线贴图。如果为0则完全使用模型本身的法线。
  10. //如果在0~1则法线贴图和模型法线按比例产生影响。如果大于1则会变得比完全使用法线贴图更加夸张。
  11. _BumpScale("BumpScale",Range(0,10))=1
  12. }
  13. SubShader{
  14. pass{
  15. Tags{
  16. "Lighting"="ForwardBase"
  17. }
  18. CGPROGRAM
  19. #include "Lighting.cginc"
  20. #pragma vertex vert
  21. #pragma fragment frag
  22. fixed4 _Color;
  23. //纹理贴图
  24. sampler2D _MainTex;
  25. //_MainTex_ST的前二维代表纹理贴图的平铺数,后二维代表纹理贴图的偏移数。
  26. //这个变量必须命名为纹理贴图变量名+"_ST"
  27. //ST表示scale 和 transition
  28. float4 _MainTex_ST;
  29. //法线贴图
  30. sampler2D _NormalMap;
  31. //法线贴图的平铺与偏移
  32. //与纹理贴图的情况类似,命名必须为法线贴图名+"_ST"
  33. float4 _NormalMap_ST;
  34. float _BumpScale;
  35. struct a2v{
  36. //模型空间下的顶点坐标
  37. float4 vertex:POSITION;
  38. //模型的法线
  39. //之后要用切线空间,切线空间是通过模型的法线和切线确定的。所以要获得法线和切线然后传输到片元函数。
  40. float3 normal:normal;
  41. //模型的切线
  42. //这里的方向不再用float3而用float4,因为需要第4维用来确定切线空间中坐标轴的方向
  43. float4 tangent:TANGENT;
  44. //通过语义:TEXCOORD 获得了uv坐标
  45. float2 texcoord:TEXCOORD;
  46. };
  47. struct v2f{
  48. //剪切空间下的顶点坐标
  49. float4 svPos:SV_POSITION;
  50. //存储切线空间下平行光的方向
  51. //用TEXCOORD、COLOR解释时,并不代表只能存储纹理坐标、颜色。这里存了方向。
  52. float3 lightDir:TEXCOORD0;
  53. //世界空间下的顶点坐标
  54. float4 worldVertex:TEXCOORD1;
  55. //存放uv坐标用,以便传递到片元函数中。xy存储纹理贴图坐标,zw存储法线贴图坐标。xyzw分别代表第1、2、3、4维。
  56. float4 uv:TEXCOORD3;
  57. };
  58. v2f vert(a2v v){
  59. v2f f;
  60. f.svPos=mul(UNITY_MATRIX_MVP,v.vertex);
  61. //v.texcoord即uv坐标在这里表示现在需要使用纹理/法线贴图的哪个位置
  62. //对现在需要使用纹理贴图的哪个位置的坐标进行缩放和平移
  63. //*_MainTex_ST.xy表示乘上平铺数,+_MainTex_ST.zw则表示加上偏移
  64. f.uv.xy=v.texcoord*_MainTex_ST.xy+_MainTex_ST.zw;
  65. //对法线贴图也进行类似操作
  66. f.uv.zw=v.texcoord*_NormalMap_ST.xy+_NormalMap_ST.zw;
  67. //调用一个宏得到一个矩阵rotation用来把模型空间下的方向转换到切线空间下。
  68. //用这个宏必须配合v、f、normal、tangent这几个固定的变量名才能正常使用。
  69. //如果没有用这几个变量名或用来表示其它内容就可能报错。
  70. TANGENT_SPACE_ROTATION;
  71. //rotation就是之前得到的矩阵,用来把模型空间下的方向转换到切线空间的下。
  72. //ObjSpaceLightDir(v.vertex)表示得到该顶点的模型空间下的光源方向
  73. f.lightDir= mul(rotation,ObjSpaceLightDir(v.vertex));
  74. return f;
  75. }
  76. //因为从法线贴图取得的法线方向在切线空间下,所以把所有跟法线方向有关的运算都放在切线空间下进行。
  77. fixed4 frag(v2f f):SV_TARGET{
  78. //读取法线贴图的颜色
  79. //tex2D(贴图,坐标)就表示读取该贴图的相应坐标的颜色
  80. fixed4 normalColor=tex2D(_NormalMap,f.uv.zw);
  81. //使用unity自带的方法通过法线贴图的颜色得到切线空间下的法线
  82. fixed3 tangentNormal=UnpackNormal(normalColor);
  83. //切线空间下的法线的z轴实际就是模型空间下模型的法线
  84. //_BumpScale为使用法线贴图的比例,只需要将从法线贴图得到的切线空间下的法线的xy乘这个系数而不用管z
  85. //当_BumpScale为0时该向量只剩z轴自然就成了模型空间下模型的法线。
  86. tangentNormal.xy=tangentNormal.xy*_BumpScale;
  87. tangentNormal=normalize(tangentNormal);
  88. //顶点函数中已经将光源方向转换到了切线空间
  89. fixed3 lightDir=normalize(f.lightDir);
  90. //获得纹理贴图上对应的颜色
  91. fixed4 texcolor= tex2D(_MainTex,f.uv.xy)*_Color;
  92. //将纹理贴图的颜色融入到漫反射颜色中。
  93. //同时法线也影响着该点的明暗,从而在一些区域形成阴影以增加细节。
  94. fixed3 diffuse=_LightColor0.rgb*texcolor.rgb*max(0,dot(tangentNormal,lightDir));
  95. //通过漫反射颜色和环境光叠加得到最终颜色。这里让环境光颜色也融合了纹理贴图颜色。
  96. fixed3 tempColor=diffuse+UNITY_LIGHTMODEL_AMBIENT.rgb*texcolor;
  97. return fixed4(tempColor,1);
  98. }
  99. ENDCG
  100. }
  101. }
  102. Fallback "Diffuss"
  103. }

为模型选择新写的shader后,在工程面板中添加纹理贴图和法线贴图。先在工程面板中设置一下图片的类型,纹理贴图需要是Texture,法线贴图是Normal map。

然后给模型的这个Shader添加纹理贴图和法线贴图:

 

 ​​之后可以调整BumpScale,当为0时完全未使用法线贴图,模型的细节就比较少。当为1时完全使用法线贴图,模型表面的细节增加了很多。当大于1时就比较夸张了。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/126921
推荐阅读
相关标签
  

闽ICP备14008679号