AutodeskInteractiveMaterialImport.cs 15 KB

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