前文所说,贴图多UV,直接命名对应贴图就可以。
模型的多套UV,则需要在3DMAX里编辑。
这篇文章主要解决两个问题:
- 如何正确使用多模型UV? 从3DMAX导出,到shader使用
- 如何优化模型导出的内存占用?
1.模型导出会有几套UV?
如果在3d模型中只做了一套uv,将模型导入unity的时候,在导入设置中勾选Generate Lightmap UVs, unity会自动为我们生成用于光照贴图的uv1,和用于动态光照的uv2
比如Unity自带的物体box,sphere就自带两套uv
第一套是正常的,比如方块可以每个面是同一个uv,
但是第二套需要烘焙光照信息,所以默认是全展开,纹理看出来要小些。
也有一些材质会用到四套UV,比如Unity的speedtree。
2.模型多UV有什么作用
做很多效果时,使用多UV可以避免使用多材质,或者多贴图,性能更好。
其实额外的UV可以替代很多mask贴图实现的效果。
3. 如何自己在模型中添加第二套UV
3DMax和maya等软件都能对模型加多套uv
注意模型在fbx里可以保留多套uv,但是obj里只能保留默认的第一套
另外unity里现在貌似支持最多四套
开始在3DMAX里制作两套UV
![8b44645c6f0f37c3d44927d0f69b3094.png](https://i-blog.csdnimg.cn/blog_migrate/667c2796fcf88bf6df10dbad5dc8bca3.jpeg)
![05bfb1da1b69805349f26b96f98d0176.png](https://i-blog.csdnimg.cn/blog_migrate/49d9d82e0cf9d7f999cd803ed027ca93.jpeg)
![c6efe8690d82f80fe8867532ddbfce8b.png](https://i-blog.csdnimg.cn/blog_migrate/b68dbbfcbf8f58383fcc6470e11ac22d.jpeg)
这是我们刚才操作过的茶壶,现在它多出了个MAP2,也就是我们的第二套UV。
我们使用下面的Shader在Unity里测试:
Shader "UV/multiTextureUV" {
Properties{
_MainTex("Texture", 2D) = "white" { }
}
SubShader{
Pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#pragma target 3.0
sampler2D _MainTex; uniform float4 _MainTex_ST;
struct appdata {
float4 vertex : POSITION;
// 多套uv的语义声明
float2 texUV0 : TEXCOORD0;
float2 texUV1 : TEXCOORD1;
float2 uv3 : TEXCOORD2;
float2 uv4 : TEXCOORD3;
float2 uv5 : TEXCOORD4;
};
struct v2f {
float4 pos : SV_POSITION;
float2 uv_MainTex : TEXCOORD0;
float2 uv2_Tex_002 : TEXCOORD1;
};
//顶点函数
v2f vert(appdata input)
{
v2f o;
o.pos = UnityObjectToClipPos(input.vertex);
o.uv_MainTex = input.texUV0;
o.uv2_Tex_002 = input.texUV1;
return o;
}
fixed4 frag(v2f i) : SV_Target
{
fixed2 main_uv = i.uv_MainTex;
fixed2 _Tex_2_uv = i.uv2_Tex_002;
//在这里替换测试
//如果没有多套uv 后面的值还是会返回uv0
//return tex2D(_MainTex, _Tex_2_uv);
return tex2D(_MainTex, main_uv);
}
ENDCG
}
}
}
![04db3f6f19b831ab40a8edc40db77f49.png](https://i-blog.csdnimg.cn/blog_migrate/a890a01629f224b571fbaf756ab289a9.jpeg)
![db986abfcd62b49349e2687446bb8073.png](https://i-blog.csdnimg.cn/blog_migrate/b30a0d1a3578ba4b9712de0b9b2b11d2.jpeg)
结果如上,我们实现了 不同模型UV的采样。
当然这个是会影响烘焙光照的。 因为Unity默认使用第二套UV作为lightmap的采样UV。
如果我们导入的模型使用了第二套UV,Unity就不会自动给模型加入第二套UV了。
4.解决unity导入模型内存占用
4. 1删除color
经过验证,在3DMAX里,制作一个模型导出,一般情况,美术人员没有手动修改,只会多出一个color,然而我们大多数情况不需要,可以删除。
如果想去掉color通道的话直接去掉alpha通道就行。
我们把刚才茶壶的color通道删除,惊喜的发现,模型变小了,并且它占用Unity的内存也会变小。
![12064c159517566d8b07121d1d63eaad.png](https://i-blog.csdnimg.cn/blog_migrate/f17d75961bc6069b33c77a76b2474ded.jpeg)
4. 2删除多层UV通道
某些时候,因为美术的一些意外操作,会引入多个我们不需要的UV通道。
由于unity的光照贴图会自动占用uv2通道,如果你的项目中又使用的是动态加载光照贴图的方式的话,最好不要在导入模型的时候把UV2设置为null,如果你这样做了有可能会导致光照贴图显示不出来的问题。
如果物体不需要烘培,你自己也不使用uv2,则可以删除该通道。
方法一:
在max中进行设置把没有必要的通道全部clear掉,具体的操作请看下面的截图:
![f6e1e89ade4d5b5237a4fb4fbcb63dcb.png](https://i-blog.csdnimg.cn/blog_migrate/2f87cdb61614ff40310f91f1915e048f.jpeg)
方法二:
程序这边进行处理,做一个工具,对每个导入到unity中的模型代码中清除相应的通道,具体的代码如下
public class ClearModelUV:AssetPostprocessor
{
void OnPostprocessModel(GameObject rImaportModel)
{
this.ClearMeshUVAndColorChannel(rImaportModel);
}
private void ClearMeshUVAndColorChannel(GameObject rImportModel)
{
List<Vector2> rNewUV = null;
List<Color32> rNewColor = null;
var rFilters= rImportModel.GetComponentsInChildren<MeshFilter>();
for (int filter_index = 0; filter_index < rFilters.Length; filter_index++)
{
rFilters[filter_index].sharedMesh.SetColors(rNewColor);
rFilters[filter_index].sharedMesh.SetUVs(1, rNewUV);
rFilters[filter_index].sharedMesh.SetUVs(2, rNewUV);
rFilters[filter_index].sharedMesh.SetUVs(3, rNewUV);
}
}
}
引用链接:
unity中多套uv set理解和应用blog.csdn.net![f51e6ad5d8380ec3ae6b2410114fedd4.png](https://i-blog.csdnimg.cn/blog_migrate/67167593c3334421ea3a37b728b22eb8.png)
另特别感谢 “华狮虎 ”帮助我在3DMAX里制作UV通道和验证效果。