TextureBlenderStandardMetallic.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System;
  5. namespace DigitalOpus.MB.Core
  6. {
  7. public class TextureBlenderStandardMetallic : TextureBlender
  8. {
  9. static Color NeutralNormalMap = new Color(.5f, .5f, 1f);
  10. private enum Prop{
  11. doColor,
  12. doMetallic,
  13. doEmission,
  14. doBump,
  15. doNone,
  16. }
  17. // This is used to cache the non texture property values. If all non-texutre property values are the same for a property for all source textures
  18. // then the source value will be re-used
  19. TextureBlenderMaterialPropertyCacheHelper sourceMaterialPropertyCache = new TextureBlenderMaterialPropertyCacheHelper();
  20. // These are cached values read in OnBeforeTintTexture and used when blending pixels.
  21. Color m_tintColor;
  22. float m_glossiness;
  23. float m_glossMapScale;
  24. float m_metallic;
  25. bool m_hasMetallicGlossMap;
  26. float m_bumpScale;
  27. bool m_shaderDoesEmission;
  28. Color m_emissionColor;
  29. // This just makes things more efficient so we arn't doing a string comparison for each pixel.
  30. Prop propertyToDo = Prop.doNone;
  31. // These are the property values that will be assigned to the result material if
  32. // generating an atlas for those properties.
  33. Color m_generatingTintedAtlasColor = Color.white;
  34. float m_generatingTintedAtlasMetallic = 0f;
  35. float m_generatingTintedAtlasGlossiness = 1f;
  36. float m_generatingTintedAtlasGlossMapScale = 1f;
  37. float m_generatingTintedAtlasBumpScale = 1f;
  38. Color m_generatingTintedAtlasEmission = Color.white;
  39. // These are the default property values that will be assigned to the result materials if
  40. // none of the source materials have a value for these properties.
  41. Color m_notGeneratingAtlasDefaultColor = Color.white;
  42. float m_notGeneratingAtlasDefaultMetallic = 0;
  43. float m_notGeneratingAtlasDefaultGlossiness = .5f;
  44. Color m_notGeneratingAtlasDefaultEmisionColor = Color.black;
  45. public bool DoesShaderNameMatch(string shaderName)
  46. {
  47. return shaderName.Equals("Standard");
  48. }
  49. public void OnBeforeTintTexture(Material sourceMat, string shaderTexturePropertyName)
  50. {
  51. if (shaderTexturePropertyName.Equals("_MainTex"))
  52. {
  53. propertyToDo = Prop.doColor;
  54. if (sourceMat.HasProperty("_Color"))
  55. {
  56. m_tintColor = sourceMat.GetColor("_Color");
  57. } else
  58. {
  59. m_tintColor = m_generatingTintedAtlasColor;
  60. }
  61. } else if (shaderTexturePropertyName.Equals("_MetallicGlossMap"))
  62. {
  63. propertyToDo = Prop.doMetallic;
  64. m_metallic = m_generatingTintedAtlasMetallic;
  65. if (sourceMat.GetTexture("_MetallicGlossMap") != null)
  66. {
  67. m_hasMetallicGlossMap = true;
  68. } else
  69. {
  70. m_hasMetallicGlossMap = false;
  71. }
  72. if (sourceMat.HasProperty("_Metallic"))
  73. {
  74. m_metallic = sourceMat.GetFloat("_Metallic");
  75. } else
  76. {
  77. m_metallic = 0f;
  78. }
  79. if (sourceMat.HasProperty("_GlossMapScale"))
  80. {
  81. m_glossMapScale = sourceMat.GetFloat("_GlossMapScale");
  82. } else
  83. {
  84. m_glossMapScale = 1f;
  85. }
  86. if (sourceMat.HasProperty("_Glossiness"))
  87. {
  88. m_glossiness = sourceMat.GetFloat("_Glossiness");
  89. } else
  90. {
  91. m_glossiness = 0f;
  92. }
  93. } else if (shaderTexturePropertyName.Equals("_BumpMap"))
  94. {
  95. propertyToDo = Prop.doBump;
  96. if (sourceMat.HasProperty(shaderTexturePropertyName))
  97. {
  98. if (sourceMat.HasProperty("_BumpScale"))
  99. m_bumpScale = sourceMat.GetFloat("_BumpScale");
  100. }
  101. else
  102. {
  103. m_bumpScale = m_generatingTintedAtlasBumpScale;
  104. }
  105. } else if (shaderTexturePropertyName.Equals("_EmissionMap"))
  106. {
  107. propertyToDo = Prop.doEmission;
  108. m_shaderDoesEmission = sourceMat.IsKeywordEnabled("_EMISSION");
  109. if (sourceMat.HasProperty("_EmissionColor")) {
  110. m_emissionColor = sourceMat.GetColor("_EmissionColor");
  111. } else
  112. {
  113. m_emissionColor = m_notGeneratingAtlasDefaultEmisionColor;
  114. }
  115. } else
  116. {
  117. propertyToDo = Prop.doNone;
  118. }
  119. }
  120. public Color OnBlendTexturePixel(string propertyToDoshaderPropertyName, Color pixelColor)
  121. {
  122. if (propertyToDo == Prop.doColor)
  123. {
  124. return new Color(pixelColor.r * m_tintColor.r, pixelColor.g * m_tintColor.g, pixelColor.b * m_tintColor.b, pixelColor.a * m_tintColor.a);
  125. }
  126. else if (propertyToDo == Prop.doMetallic)
  127. {
  128. if (m_hasMetallicGlossMap)
  129. {
  130. return pixelColor = new Color(pixelColor.r, pixelColor.g, pixelColor.b, pixelColor.a * m_glossMapScale);
  131. }
  132. else
  133. {
  134. return new Color(m_metallic, 0, 0, m_glossiness);
  135. }
  136. }
  137. else if (propertyToDo == Prop.doBump)
  138. {
  139. return Color.Lerp(NeutralNormalMap, pixelColor, m_bumpScale);
  140. }
  141. else if (propertyToDo == Prop.doEmission)
  142. {
  143. if (m_shaderDoesEmission)
  144. {
  145. return new Color(pixelColor.r * m_emissionColor.r, pixelColor.g * m_emissionColor.g, pixelColor.b * m_emissionColor.b, pixelColor.a * m_emissionColor.a);
  146. }
  147. else
  148. {
  149. return Color.black;
  150. }
  151. }
  152. return pixelColor;
  153. }
  154. public bool NonTexturePropertiesAreEqual(Material a, Material b)
  155. {
  156. if (!TextureBlenderFallback._compareColor(a, b, m_notGeneratingAtlasDefaultColor, "_Color"))
  157. {
  158. return false;
  159. }
  160. if (!TextureBlenderFallback._compareFloat(a, b, m_notGeneratingAtlasDefaultGlossiness, "_Glossiness"))
  161. {
  162. return false;
  163. }
  164. bool aHasMetallicTex = a.HasProperty("_MetallicGlossMap") && a.GetTexture("_MetallicGlossMap") != null;
  165. bool bHasMetallicTex = b.HasProperty("_MetallicGlossMap") && b.GetTexture("_MetallicGlossMap") != null;
  166. if (aHasMetallicTex && bHasMetallicTex)
  167. {
  168. if (!TextureBlenderFallback._compareFloat(a, b, m_notGeneratingAtlasDefaultMetallic, "_GlossMapScale"))
  169. {
  170. return false;
  171. }
  172. } else if (!aHasMetallicTex && !bHasMetallicTex)
  173. {
  174. if (!TextureBlenderFallback._compareFloat(a, b, m_notGeneratingAtlasDefaultMetallic, "_Metallic"))
  175. {
  176. return false;
  177. }
  178. } else
  179. {
  180. return false;
  181. }
  182. if (a.IsKeywordEnabled("_EMISSION") != b.IsKeywordEnabled("_EMISSION"))
  183. {
  184. return false;
  185. }
  186. if (a.IsKeywordEnabled("_EMISSION"))
  187. {
  188. if (!TextureBlenderFallback._compareColor(a, b, m_notGeneratingAtlasDefaultEmisionColor, "_EmissionColor"))
  189. {
  190. return false;
  191. }
  192. }
  193. return true;
  194. }
  195. public void SetNonTexturePropertyValuesOnResultMaterial(Material resultMaterial)
  196. {
  197. if (resultMaterial.GetTexture("_MainTex") != null)
  198. {
  199. resultMaterial.SetColor("_Color", m_generatingTintedAtlasColor);
  200. } else {
  201. resultMaterial.SetColor("_Color", (Color) sourceMaterialPropertyCache.GetValueIfAllSourceAreTheSameOrDefault("_Color", m_notGeneratingAtlasDefaultColor));
  202. }
  203. if (resultMaterial.GetTexture("_MetallicGlossMap") != null)
  204. {
  205. resultMaterial.SetFloat("_Metallic", m_generatingTintedAtlasMetallic);
  206. resultMaterial.SetFloat("_GlossMapScale", m_generatingTintedAtlasGlossMapScale);
  207. resultMaterial.SetFloat("_Glossiness", m_generatingTintedAtlasGlossiness);
  208. } else
  209. {
  210. resultMaterial.SetFloat("_Metallic", (float) sourceMaterialPropertyCache.GetValueIfAllSourceAreTheSameOrDefault("_Metallic", m_notGeneratingAtlasDefaultMetallic));
  211. resultMaterial.SetFloat("_Glossiness", (float) sourceMaterialPropertyCache.GetValueIfAllSourceAreTheSameOrDefault("_Glossiness", m_notGeneratingAtlasDefaultGlossiness));
  212. }
  213. if (resultMaterial.GetTexture("_BumpMap") != null)
  214. {
  215. resultMaterial.SetFloat("_BumpScale", m_generatingTintedAtlasBumpScale);
  216. }
  217. if (resultMaterial.GetTexture("_EmissionMap") != null)
  218. {
  219. resultMaterial.EnableKeyword("_EMISSION");
  220. resultMaterial.SetColor("_EmissionColor", m_generatingTintedAtlasEmission);
  221. }
  222. else {
  223. resultMaterial.DisableKeyword("_EMISSION");
  224. resultMaterial.SetColor("_EmissionColor", (Color) sourceMaterialPropertyCache.GetValueIfAllSourceAreTheSameOrDefault("_EmissionColor", m_notGeneratingAtlasDefaultEmisionColor));
  225. }
  226. }
  227. public Color GetColorIfNoTexture(Material mat, ShaderTextureProperty texPropertyName)
  228. {
  229. if (texPropertyName.name.Equals("_BumpMap"))
  230. {
  231. return new Color(.5f, .5f, 1f);
  232. }
  233. else if (texPropertyName.name.Equals("_MainTex"))
  234. {
  235. if (mat != null && mat.HasProperty("_Color"))
  236. {
  237. try
  238. { //need try because can't garantee _Color is a color
  239. Color c = mat.GetColor("_Color");
  240. sourceMaterialPropertyCache.CacheMaterialProperty(mat, "_Color", c);
  241. }
  242. catch (Exception) { }
  243. return Color.white;
  244. }
  245. }
  246. else if (texPropertyName.name.Equals("_MetallicGlossMap"))
  247. {
  248. if (mat != null && mat.HasProperty("_Metallic"))
  249. {
  250. try
  251. { //need try because can't garantee _Metallic is a float
  252. float v = mat.GetFloat("_Metallic");
  253. Color c = new Color(v, v, v);
  254. if (mat.HasProperty("_Glossiness"))
  255. {
  256. try
  257. {
  258. c.a = mat.GetFloat("_Glossiness");
  259. }
  260. catch (Exception) { }
  261. }
  262. sourceMaterialPropertyCache.CacheMaterialProperty(mat, "_Metallic", v);
  263. sourceMaterialPropertyCache.CacheMaterialProperty(mat, "_Glossiness", c.a);
  264. }
  265. catch (Exception) { }
  266. return new Color(0f, 0f, 0f, .5f);
  267. } else
  268. {
  269. return new Color(0f,0f,0f,.5f);
  270. }
  271. }
  272. else if (texPropertyName.name.Equals("_ParallaxMap"))
  273. {
  274. return new Color(0f, 0f, 0f, 0f);
  275. }
  276. else if (texPropertyName.name.Equals("_OcclusionMap"))
  277. {
  278. return new Color(1f, 1f, 1f, 1f);
  279. }
  280. else if (texPropertyName.name.Equals("_EmissionMap"))
  281. {
  282. if (mat != null)
  283. {
  284. if (mat.IsKeywordEnabled("_EMISSION"))
  285. {
  286. if (mat.HasProperty("_EmissionColor"))
  287. {
  288. try
  289. {
  290. Color c = mat.GetColor("_EmissionColor");
  291. sourceMaterialPropertyCache.CacheMaterialProperty(mat, "_EmissionColor", c);
  292. }
  293. catch (Exception) { }
  294. }
  295. else
  296. {
  297. return Color.black;
  298. }
  299. } else
  300. {
  301. return Color.black;
  302. }
  303. }
  304. }
  305. else if (texPropertyName.name.Equals("_DetailMask"))
  306. {
  307. return new Color(0f, 0f, 0f, 0f);
  308. }
  309. return new Color(1f, 1f, 1f, 0f);
  310. }
  311. }
  312. }