MaterialChecks.cs 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. /******************************************************************************
  2. * Spine Runtimes License Agreement
  3. * Last updated January 1, 2020. Replaces all prior versions.
  4. *
  5. * Copyright (c) 2013-2020, Esoteric Software LLC
  6. *
  7. * Integration of the Spine Runtimes into software or otherwise creating
  8. * derivative works of the Spine Runtimes is permitted under the terms and
  9. * conditions of Section 2 of the Spine Editor License Agreement:
  10. * http://esotericsoftware.com/spine-editor-license
  11. *
  12. * Otherwise, it is permitted to integrate the Spine Runtimes into software
  13. * or otherwise create derivative works of the Spine Runtimes (collectively,
  14. * "Products"), provided that each user of the Products must obtain their own
  15. * Spine Editor license and redistribution of the Products in any form must
  16. * include this license and copyright notice.
  17. *
  18. * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
  19. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  20. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  21. * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
  22. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  23. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
  24. * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
  25. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  26. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  27. * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28. *****************************************************************************/
  29. using System.Collections.Generic;
  30. using UnityEngine;
  31. #if UNITY_EDITOR
  32. namespace Spine.Unity {
  33. /// <summary>Utility class providing methods to check material settings for incorrect combinations.</summary>
  34. public class MaterialChecks {
  35. static readonly int STRAIGHT_ALPHA_PARAM_ID = Shader.PropertyToID("_StraightAlphaInput");
  36. static readonly string ALPHAPREMULTIPLY_ON_KEYWORD = "_ALPHAPREMULTIPLY_ON";
  37. static readonly string STRAIGHT_ALPHA_KEYWORD = "_STRAIGHT_ALPHA_INPUT";
  38. public static readonly string kPMANotSupportedLinearMessage =
  39. "Warning: Premultiply-alpha atlas textures not supported in Linear color space!\n\nPlease\n"
  40. + "a) re-export atlas as straight alpha texture with 'premultiply alpha' unchecked\n"
  41. + " (if you have already done this, please set the 'Straight Alpha Texture' Material parameter to 'true') or\n"
  42. + "b) switch to Gamma color space via\nProject Settings - Player - Other Settings - Color Space.\n";
  43. public static readonly string kZSpacingRequiredMessage =
  44. "Warning: Z Spacing required on selected shader! Otherwise you will receive incorrect results.\n\nPlease\n"
  45. + "1) make sure at least minimal 'Z Spacing' is set at the SkeletonRenderer/SkeletonAnimation component under 'Advanced' and\n"
  46. + "2) ensure that the skeleton has overlapping parts on different Z depth. You can adjust this in Spine via draw order.\n";
  47. public static readonly string kZSpacingRecommendedMessage =
  48. "Warning: Z Spacing recommended on selected shader configuration!\n\nPlease\n"
  49. + "1) make sure at least minimal 'Z Spacing' is set at the SkeletonRenderer/SkeletonAnimation component under 'Advanced' and\n"
  50. + "2) ensure that the skeleton has overlapping parts on different Z depth. You can adjust this in Spine via draw order.\n";
  51. public static bool IsMaterialSetupProblematic (SkeletonRenderer renderer, ref string errorMessage) {
  52. var materials = renderer.GetComponent<Renderer>().sharedMaterials;
  53. bool isProblematic = false;
  54. foreach (var mat in materials) {
  55. if (mat == null) continue;
  56. isProblematic |= IsMaterialSetupProblematic(mat, ref errorMessage);
  57. if (renderer.zSpacing == 0) {
  58. isProblematic |= IsZSpacingRequired(mat, ref errorMessage);
  59. }
  60. }
  61. return isProblematic;
  62. }
  63. public static bool IsMaterialSetupProblematic(Material material, ref string errorMessage) {
  64. return !IsColorSpaceSupported(material, ref errorMessage);
  65. }
  66. public static bool IsZSpacingRequired(Material material, ref string errorMessage) {
  67. bool hasForwardAddPass = material.FindPass("FORWARD_DELTA") >= 0;
  68. if (hasForwardAddPass) {
  69. errorMessage += kZSpacingRequiredMessage;
  70. return true;
  71. }
  72. bool zWrite = material.HasProperty("_ZWrite") && material.GetFloat("_ZWrite") > 0.0f;
  73. if (zWrite) {
  74. errorMessage += kZSpacingRecommendedMessage;
  75. return true;
  76. }
  77. return false;
  78. }
  79. public static bool IsColorSpaceSupported (Material material, ref string errorMessage) {
  80. if (QualitySettings.activeColorSpace == ColorSpace.Linear) {
  81. if (IsPMAMaterial(material)) {
  82. errorMessage += kPMANotSupportedLinearMessage;
  83. return false;
  84. }
  85. }
  86. return true;
  87. }
  88. public static bool UsesSpineShader (Material material) {
  89. return material.shader.name.Contains("Spine/");
  90. }
  91. public static bool IsTextureSetupProblematic (Material material, ColorSpace colorSpace,
  92. bool sRGBTexture, bool mipmapEnabled, bool alphaIsTransparency,
  93. string texturePath, string materialPath,
  94. ref string errorMessage) {
  95. if (material == null || !UsesSpineShader(material)) {
  96. return false;
  97. }
  98. bool isProblematic = false;
  99. if (IsPMAMaterial(material)) {
  100. // 'sRGBTexture = true' generates incorrectly weighted mipmaps at PMA textures,
  101. // causing white borders due to undesired custom weighting.
  102. if (sRGBTexture && mipmapEnabled && colorSpace == ColorSpace.Gamma) {
  103. errorMessage += string.Format("`{0}` : Problematic Texture Settings found: When enabling `Generate Mip Maps` in Gamma color space, it is recommended to disable `sRGB (Color Texture)` on `Premultiply alpha` textures. Otherwise you will receive white border artifacts on an atlas exported with default `Premultiply alpha` settings.\n(You can disable this warning in `Edit - Preferences - Spine`)\n", texturePath);
  104. isProblematic = true;
  105. }
  106. if (alphaIsTransparency) {
  107. string materialName = System.IO.Path.GetFileName(materialPath);
  108. errorMessage += string.Format("`{0}` and material `{1}` : Problematic Texture / Material Settings found: It is recommended to disable `Alpha Is Transparency` on `Premultiply alpha` textures.\nAssuming `Premultiply alpha` texture because `Straight Alpha Texture` is disabled at material). (You can disable this warning in `Edit - Preferences - Spine`)\n", texturePath, materialName);
  109. isProblematic = true;
  110. }
  111. }
  112. else { // straight alpha texture
  113. if (!alphaIsTransparency) {
  114. string materialName = System.IO.Path.GetFileName(materialPath);
  115. errorMessage += string.Format("`{0}` and material `{1}` : Incorrect Texture / Material Settings found: It is strongly recommended to enable `Alpha Is Transparency` on `Straight alpha` textures.\nAssuming `Straight alpha` texture because `Straight Alpha Texture` is enabled at material). (You can disable this warning in `Edit - Preferences - Spine`)\n", texturePath, materialName);
  116. isProblematic = true;
  117. }
  118. }
  119. return isProblematic;
  120. }
  121. public static void EnablePMAAtMaterial (Material material, bool enablePMA) {
  122. if (material.HasProperty(STRAIGHT_ALPHA_PARAM_ID)) {
  123. material.SetInt(STRAIGHT_ALPHA_PARAM_ID, enablePMA ? 0 : 1);
  124. if (enablePMA)
  125. material.DisableKeyword(STRAIGHT_ALPHA_KEYWORD);
  126. else
  127. material.EnableKeyword(STRAIGHT_ALPHA_KEYWORD);
  128. }
  129. else {
  130. if (enablePMA)
  131. material.EnableKeyword(ALPHAPREMULTIPLY_ON_KEYWORD);
  132. else
  133. material.DisableKeyword(ALPHAPREMULTIPLY_ON_KEYWORD);
  134. }
  135. }
  136. static bool IsPMAMaterial (Material material) {
  137. return (material.HasProperty(STRAIGHT_ALPHA_PARAM_ID) && material.GetInt(STRAIGHT_ALPHA_PARAM_ID) == 0) ||
  138. material.IsKeywordEnabled(ALPHAPREMULTIPLY_ON_KEYWORD);
  139. }
  140. }
  141. }
  142. #endif // UNITY_EDITOR