Unity-代码中动态设置Material参数
来源:互联网 发布:便宜的鼠标 知乎 编辑:程序博客网 时间:2024/05/29 09:53
我们知道在Unity中可以在代码中动态地改变Material监视面板中的参数,如改变数值大小或替换贴图。常用的API有:SetColor , SetFloat, SetInt, SetTexture.
然而今天在设置一个StandardShader的材质贴图的时候,发现设置了法线贴图但是场景中的物体并没有法线凹凸的效果,需要激活一下材质面板才行。经过反复检查以及查找资料,主要有以下两个问题:
// 贴图类型string[] TEXTURE_TYPE = { "_MetallicGlossMap", "_BumpMap", "_ParallaxMap", "_OcclusionMap", "_DetailMask", "_DetailAlbedoMap", "_DetailNormalMap"};// Material需要设置的关键字string[] TEXTURE_KEYWORD = { "_METALLICGLOSSMAP", "_NORMALMAP", "_PARALLAXMAP", "", "_DETAIL_MULX2", "_DETAIL_MULX2", "_DETAIL_MULX2" };
法线贴图导入进来需要设置类型为NormalMap
// 设置法线贴图的类型if (fileName == diffuseName + TEXTURE_TYPE[1]){ TextureImporter importer = (TextureImporter)AssetImporter.GetAtPath(filePath); importer.textureType = TextureImporterType.NormalMap; importer.SaveAndReimport();}
使用标准着色器(StandardShader)的Material要设置启用相应的关键字
// 在Material.SetTexture之前 开启相应的KeyWordmat.EnableKeyword(TEXTURE_KEYWORD[i]);
以下是我查文档自己理解的,不一定准确。
一个Material所使用的标准着色器在Unity中其实是多个着色器的集合。因为一个材质的着色器不可能涵盖所有的功能,比如GI、雾效、HDR等高耗能的效果,所以Unity把标准着色器分成了带有不同特殊功能的着色器变体(Shader Variant)。当把NormalMap分配给材质,就是激活了支持法线贴图的着色器变体;把视差贴图分配给材质,就是激活了支持视差贴图的着色器变体。所以,如果要把某个特殊的贴图赋给材质,就要开启材质相应的关键字,以激活支持相应功能的着色器变体。
需要专门开启的关键字有以下几个:
关键字 特性 _NORMALMAP 法线映射 _ALPHATEST_ON 用于CutOut渲染模式 _ALPHABLEND_ON 用于Fade渲染模式 _ALPHAPREMULTIPLY_ON 用于Transparent渲染模式 _EMISSION 设置自发光 _PARALLAXMAP 设置视差贴图 _DETAIL_MULX2 用于设置第二个贴图通道 _METALLICGLOSSMAP 在 Metallic工作流中设置金属度贴图 _SPECGLOSSMAP 在 Specular工作流中设置高光贴图
下面附上设置材质属性的部分代码:
/// <summary> /// 设置材质中shader的相关属性 ///<para name = "mat"> 需要设置的Material </para> ///<para name = "meshMat"> 要传入shader的数据集合 </para> ///<para name = "fbxName"> 模型的名字,在这里主要是为了得到材质贴图文件夹的位置 </para>/// </summary>void SetShader(Material mat, ShaderData data, string fbxName){ // 这里默认贴图资源中主贴图的名字就是材质名,其他贴图的名字是材质名+贴图类型 string diffuseName = mat.name; // textureFiles用于记录贴图文件夹中所有的图片文件,记录它们的贴图名和路径 Dictionary<string, string> textureFiles = new Dictionary<string, string>(); // texturePath是之前记录好的一个fbx模型对应的贴图文件夹的路径 string[] filesPath = Directory.GetFiles(texturePath[fbxName]); foreach (string filePath in filesPath) { // TEXTURE_EXT是预设的图片后缀名,用于标记图片格式(如.jpg,.png,.tif等) if (Array.IndexOf(TEXTURE_EXT, Path.GetExtension(filePath)) != -1) { string fileName = Path.GetFileNameWithoutExtension(filePath); if (fileName.IndexOf(diffuseName) == 0) { textureFiles[fileName] = filePath; Debug.Log(fileName + " , " + filePath); // 设置法线贴图的类型 if (fileName == diffuseName + TEXTURE_TYPE[1]) { TextureImporter importer = (TextureImporter)AssetImporter.GetAtPath(filePath); importer.textureType = TextureImporterType.NormalMap; importer.SaveAndReimport(); } } } } // 设置材质的主贴图,也就是Albedo贴图 if (textureFiles.ContainsKey(diffuseName)) { Debug.Log("MainTexture Exist"); mat.mainTexture = AssetDatabase.LoadAssetAtPath<Texture>(textureFiles[diffuseName]); } // 设置其他特殊类型的贴图 for (int i = 0; i < TEXTURE_TYPE.Length; ++i) { if (textureFiles.ContainsKey(diffuseName + TEXTURE_TYPE[i])) { Debug.Log(TEXTURE_TYPE[i] + " Exist "); if (TEXTURE_KEYWORD[i] != "") mat.EnableKeyword(TEXTURE_KEYWORD[i]); mat.SetTexture(TEXTURE_TYPE[i], AssetDatabase.LoadAssetAtPath<Texture>(textureFiles[diffuseName + TEXTURE_TYPE[i]])); } } mat.color = data.color; mat.SetFloat("_Metallic", data.metallic); mat.SetFloat("_Glossiness", data.glossiness); mat.SetColor("_EmissionColor", data.emissionColor);}
参考:https://docs.unity3d.com/Manual/MaterialsAccessingViaScript.html
阅读全文
1 0
- Unity-代码中动态设置Material参数
- unity 雷1 -- 代码动态切换material
- Unity中动态改变物体的Material(Shader)
- Unity Shader中有关设置Material的优化
- Unity动态创建带有Shader的Material
- 代码中动态设置权重
- unity中使用usafe代码的设置
- Unity中动态修改游戏中任意参数的框架
- 【Unity&NGUI】Widget的Pivot怎么用代码动态设置
- Android 代码中设置Color参数
- 如何在代码中动态设置java_library_path?
- Android apk代码中动态设置背景图片
- 动态在代码中设置权重
- ListView在代码中动态设置高度
- 在代码中动态设置selector
- 动态代码中设置控件相对位置
- Unity项目中使用Git管理代码的设置步骤
- hibernate动态设置参数
- apidoc写php接口文档
- demo2,网页换肤,总结
- C语言 类型转换
- CentOS7lamp环境搭建
- Maven坐标和资源库
- Unity-代码中动态设置Material参数
- 日记8/23
- linux下硬连接与软连接
- ConcurrentHashMap原理分析
- Hibernate快速入门+简单示例
- 信号量程序
- Java 操作Hbase 简单案例 (Kerberos已开启)
- POJ
- 链表中环的入口节点