TextureBlenderStandardSpecular.cs 13 KB

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