AutodeskInteractiveMaterialImport.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. using UnityEngine;
  2. using UnityEditor.AssetImporters;
  3. using UnityEngine.Rendering;
  4. using UnityEngine.Rendering.Universal;
  5. namespace UnityEditor.Rendering.Universal
  6. {
  7. class AutodeskInteractiveMaterialImport : AssetPostprocessor
  8. {
  9. static readonly uint k_Version = 1;
  10. static readonly int k_Order = 3;
  11. public override uint GetVersion()
  12. {
  13. return k_Version;
  14. }
  15. public override int GetPostprocessOrder()
  16. {
  17. return k_Order;
  18. }
  19. public void OnPreprocessMaterialDescription(MaterialDescription description, Material material, AnimationClip[] clips)
  20. {
  21. var pipelineAsset = GraphicsSettings.currentRenderPipeline;
  22. if (!pipelineAsset || pipelineAsset.GetType() != typeof(UniversalRenderPipelineAsset))
  23. return;
  24. if (IsAutodeskInteractiveMaterial(description))
  25. {
  26. float floatProperty;
  27. Vector4 vectorProperty;
  28. TexturePropertyDescription textureProperty;
  29. bool isMasked = description.TryGetProperty("mask_threshold",out floatProperty);
  30. bool isTransparent = description.TryGetProperty("opacity",out floatProperty);
  31. Shader shader;
  32. if (isMasked)
  33. shader = GraphicsSettings.currentRenderPipeline.autodeskInteractiveMaskedShader;
  34. else if (isTransparent)
  35. shader = GraphicsSettings.currentRenderPipeline.autodeskInteractiveTransparentShader;
  36. else
  37. shader = GraphicsSettings.currentRenderPipeline.autodeskInteractiveShader;
  38. if (shader == null)
  39. return;
  40. material.shader = shader;
  41. foreach (var clip in clips)
  42. {
  43. clip.ClearCurves();
  44. }
  45. if (description.TryGetProperty("base_color", out vectorProperty))
  46. material.SetColor("_Color", vectorProperty);
  47. if (description.TryGetProperty("emissive", out vectorProperty))
  48. material.SetColor("_EmissionColor", vectorProperty);
  49. if (description.TryGetProperty("roughness", out floatProperty))
  50. material.SetFloat("_Roughness", floatProperty);
  51. if (description.TryGetProperty("metallic", out floatProperty))
  52. material.SetFloat("_Metallic", floatProperty);
  53. if (description.TryGetProperty("uvTransform", out vectorProperty))
  54. {
  55. material.SetVector("_UvOffset", new Vector4(vectorProperty.x, vectorProperty.y, .0f, .0f));
  56. material.SetVector("_UvTiling", new Vector4(vectorProperty.w, vectorProperty.z, .0f, .0f));
  57. }
  58. if (description.TryGetProperty("TEX_color_map", out textureProperty))
  59. {
  60. material.SetTexture("_MainTex", textureProperty.texture);
  61. material.SetFloat("_UseColorMap", 1.0f);
  62. }
  63. else
  64. {
  65. material.SetFloat("_UseColorMap", 0.0f);
  66. }
  67. if (description.TryGetProperty("TEX_normal_map", out textureProperty))
  68. {
  69. material.SetTexture("_BumpMap", textureProperty.texture);
  70. material.SetFloat("_UseNormalMap", 1.0f);
  71. }
  72. else
  73. {
  74. material.SetFloat("_UseNormalMap", 0.0f);
  75. }
  76. if (description.TryGetProperty("TEX_roughness_map", out textureProperty))
  77. {
  78. material.SetTexture("RoughnessMap", textureProperty.texture);
  79. material.SetFloat("_UseRoughnessMap", 1.0f);
  80. }
  81. else
  82. {
  83. material.SetFloat("_UseRoughnessMap", 0.0f);
  84. }
  85. if (description.TryGetProperty("TEX_metallic_map", out textureProperty))
  86. {
  87. material.SetTexture("_MetallicMap", textureProperty.texture);
  88. material.SetFloat("_UseMetallicMap", 1.0f);
  89. }
  90. else
  91. {
  92. material.SetFloat("_UseMetallicMap", 0.0f);
  93. }
  94. if (description.TryGetProperty("TEX_emissive_map", out textureProperty))
  95. {
  96. material.SetTexture("_EmissionMap", textureProperty.texture);
  97. material.SetFloat("_UseEmissiveMap", 1.0f);
  98. }
  99. else
  100. {
  101. material.SetFloat("_UseEmissiveMap", 0.0f);
  102. }
  103. if (description.TryGetProperty("hasTransparencyTexture", out floatProperty))
  104. material.SetFloat("_UseOpacityMap", floatProperty);
  105. if (description.TryGetProperty("transparencyMaskThreshold", out floatProperty))
  106. material.SetFloat("_OpacityThreshold", floatProperty);
  107. if (description.TryGetProperty("TEX_ao_map", out textureProperty))
  108. {
  109. var tex = AssetDatabase.LoadAssetAtPath<Texture>(textureProperty.relativePath);
  110. material.SetTexture("AoMap", tex);
  111. material.SetFloat("UseAoMap", 1.0f);
  112. }
  113. else
  114. {
  115. material.SetFloat("UseAoMap", 0.0f);
  116. }
  117. RemapColorCurves(description, clips, "base_color", "_Color");
  118. RemapCurve(description, clips, "mask_threshold", "_Cutoff");
  119. RemapCurve(description, clips, "metallic", "_Metallic");
  120. RemapCurve(description, clips, "roughness", "_Glossiness");
  121. for (int i = 0; i < clips.Length; i++)
  122. {
  123. if (description.HasAnimationCurveInClip(clips[i].name, "uv_scale.x") || description.HasAnimationCurveInClip(clips[i].name, "uv_scale.y"))
  124. {
  125. AnimationCurve curve;
  126. if (description.TryGetAnimationCurve(clips[i].name, "uv_scale.x", out curve))
  127. clips[i].SetCurve("", typeof(Material), "_UvTiling.x", curve);
  128. else
  129. clips[i].SetCurve("", typeof(Material), "_UvTiling.x", AnimationCurve.Constant(0.0f, 1.0f, 1.0f));
  130. if (description.TryGetAnimationCurve(clips[i].name, "uv_scale.y", out curve))
  131. clips[i].SetCurve("", typeof(Material), "_UvTiling.y", curve);
  132. else
  133. clips[i].SetCurve("", typeof(Material), "_UvTiling.y", AnimationCurve.Constant(0.0f, 1.0f, 1.0f));
  134. }
  135. if (description.HasAnimationCurveInClip(clips[i].name, "uv_offset.x") || description.HasAnimationCurveInClip(clips[i].name, "uv_offset.y"))
  136. {
  137. AnimationCurve curve;
  138. if (description.TryGetAnimationCurve(clips[i].name, "uv_offset.x", out curve))
  139. clips[i].SetCurve("", typeof(Material), "_UvOffset.x", curve);
  140. else
  141. clips[i].SetCurve("", typeof(Material), "_UvOffset.x", AnimationCurve.Constant(0.0f, 1.0f, 0.0f));
  142. if (description.TryGetAnimationCurve(clips[i].name, "uv_offset.y", out curve))
  143. {
  144. ConvertKeys(curve, ConvertFloatNegate);
  145. clips[i].SetCurve("", typeof(Material), "_UvOffset.y", curve);
  146. }
  147. else
  148. clips[i].SetCurve("", typeof(Material), "_UvOffset.y", AnimationCurve.Constant(0.0f, 1.0f, 0.0f));
  149. }
  150. }
  151. if (description.HasAnimationCurve("emissive_intensity"))
  152. {
  153. Vector4 emissiveColor;
  154. description.TryGetProperty("emissive", out emissiveColor);
  155. for (int i = 0; i < clips.Length; i++)
  156. {
  157. AnimationCurve curve;
  158. description.TryGetAnimationCurve(clips[i].name, "emissive_intensity", out curve);
  159. // remap emissive intensity to emission color
  160. clips[i].SetCurve("", typeof(Material), "_EmissionColor.r", curve);
  161. clips[i].SetCurve("", typeof(Material), "_EmissionColor.g", curve);
  162. clips[i].SetCurve("", typeof(Material), "_EmissionColor.b", curve);
  163. }
  164. }
  165. else if (description.TryGetProperty("emissive", out vectorProperty))
  166. {
  167. if (vectorProperty.x > 0.0f || vectorProperty.y > 0.0f || vectorProperty.z > 0.0f)
  168. {
  169. material.globalIlluminationFlags |= MaterialGlobalIlluminationFlags.RealtimeEmissive;
  170. material.EnableKeyword("_EMISSION");
  171. }
  172. if (description.TryGetProperty("emissive_intensity", out floatProperty))
  173. {
  174. vectorProperty *= floatProperty;
  175. }
  176. material.SetColor("_EmissionColor", vectorProperty);
  177. if (description.HasAnimationCurve("emissive.x"))
  178. {
  179. if (description.HasAnimationCurve("emissive_intensity"))
  180. {
  181. // combine color and intensity.
  182. for (int i = 0; i < clips.Length; i++)
  183. {
  184. AnimationCurve curve;
  185. AnimationCurve intensityCurve;
  186. description.TryGetAnimationCurve(clips[i].name, "emissive_intensity", out intensityCurve);
  187. description.TryGetAnimationCurve(clips[i].name, "emissive.x", out curve);
  188. MultiplyCurves(curve, intensityCurve);
  189. clips[i].SetCurve("", typeof(Material), "_EmissionColor.r", curve);
  190. description.TryGetAnimationCurve(clips[i].name, "emissive.y", out curve);
  191. MultiplyCurves(curve, intensityCurve);
  192. clips[i].SetCurve("", typeof(Material), "_EmissionColor.g", curve);
  193. description.TryGetAnimationCurve(clips[i].name, "emissive.z", out curve);
  194. MultiplyCurves(curve, intensityCurve);
  195. clips[i].SetCurve("", typeof(Material), "_EmissionColor.b", curve);
  196. }
  197. }
  198. else
  199. {
  200. RemapColorCurves(description, clips, "emissive", "_EmissionColor");
  201. }
  202. }
  203. else if (description.HasAnimationCurve("emissive_intensity"))
  204. {
  205. Vector4 emissiveColor;
  206. description.TryGetProperty("emissive", out emissiveColor);
  207. for (int i = 0; i < clips.Length; i++)
  208. {
  209. AnimationCurve curve;
  210. description.TryGetAnimationCurve(clips[i].name, "emissive_intensity", out curve);
  211. // remap emissive intensity to emission color
  212. AnimationCurve curveR = new AnimationCurve();
  213. ConvertAndCopyKeys(curveR, curve, value => ConvertFloatMultiply(emissiveColor.x, value));
  214. clips[i].SetCurve("", typeof(Material), "_EmissionColor.r", curveR);
  215. AnimationCurve curveG = new AnimationCurve();
  216. ConvertAndCopyKeys(curveG, curve, value => ConvertFloatMultiply(emissiveColor.y, value));
  217. clips[i].SetCurve("", typeof(Material), "_EmissionColor.g", curveG);
  218. AnimationCurve curveB = new AnimationCurve();
  219. ConvertAndCopyKeys(curveB, curve, value => ConvertFloatMultiply(emissiveColor.z, value));
  220. clips[i].SetCurve("", typeof(Material), "_EmissionColor.b", curveB);
  221. }
  222. }
  223. }
  224. }
  225. }
  226. static bool IsAutodeskInteractiveMaterial(MaterialDescription description)
  227. {
  228. return description.TryGetProperty("renderAPI", out string stringValue) && stringValue == "SFX_PBS_SHADER";
  229. }
  230. static void ConvertKeys(AnimationCurve curve, System.Func<float, float> convertionDelegate)
  231. {
  232. Keyframe[] keyframes = curve.keys;
  233. for (int i = 0; i < keyframes.Length; i++)
  234. {
  235. keyframes[i].value = convertionDelegate(keyframes[i].value);
  236. }
  237. curve.keys = keyframes;
  238. }
  239. static void ConvertAndCopyKeys(AnimationCurve curveDest, AnimationCurve curveSource, System.Func<float, float> convertionDelegate)
  240. {
  241. for (int i = 0; i < curveSource.keys.Length; i++)
  242. {
  243. var sourceKey = curveSource.keys[i];
  244. curveDest.AddKey(new Keyframe(sourceKey.time, convertionDelegate(sourceKey.value), sourceKey.inTangent, sourceKey.outTangent, sourceKey.inWeight, sourceKey.outWeight));
  245. }
  246. }
  247. static float ConvertFloatNegate(float value)
  248. {
  249. return -value;
  250. }
  251. static float ConvertFloatMultiply(float value, float multiplier)
  252. {
  253. return value * multiplier;
  254. }
  255. static void MultiplyCurves(AnimationCurve curve, AnimationCurve curveMultiplier)
  256. {
  257. Keyframe[] keyframes = curve.keys;
  258. for (int i = 0; i < keyframes.Length; i++)
  259. {
  260. keyframes[i].value *= curveMultiplier.Evaluate(keyframes[i].time);
  261. }
  262. curve.keys = keyframes;
  263. }
  264. static void RemapCurve(MaterialDescription description, AnimationClip[] clips, string originalPropertyName, string newPropertyName)
  265. {
  266. AnimationCurve curve;
  267. for (int i = 0; i < clips.Length; i++)
  268. {
  269. if (description.TryGetAnimationCurve(clips[i].name, originalPropertyName, out curve))
  270. {
  271. clips[i].SetCurve("", typeof(Material), newPropertyName, curve);
  272. }
  273. }
  274. }
  275. static void RemapColorCurves(MaterialDescription description, AnimationClip[] clips, string originalPropertyName, string newPropertyName)
  276. {
  277. AnimationCurve curve;
  278. for (int i = 0; i < clips.Length; i++)
  279. {
  280. if (description.TryGetAnimationCurve(clips[i].name, originalPropertyName + ".x", out curve))
  281. {
  282. clips[i].SetCurve("", typeof(Material), newPropertyName + ".r", curve);
  283. }
  284. if (description.TryGetAnimationCurve(clips[i].name, originalPropertyName + ".y", out curve))
  285. {
  286. clips[i].SetCurve("", typeof(Material), newPropertyName + ".g", curve);
  287. }
  288. if (description.TryGetAnimationCurve(clips[i].name, originalPropertyName + ".z", out curve))
  289. {
  290. clips[i].SetCurve("", typeof(Material), newPropertyName + ".b", curve);
  291. }
  292. }
  293. }
  294. }
  295. }