/// <summary> /// Scan a texture looking for transparent pixels and trying to guess the correct blend mode needed. /// </summary> /// <param name="texture">input rexture (it must be set to readable)</param> /// <param name="mode">blend mode set to FADE or CUTOUT if transparent pixels are found.</param> /// <returns>Return true if transparent pixels were found.</returns> public static bool ScanTransparentPixels(Texture2D texture, ref MtlBlendMode mode) { bool texCanBeTransparent = texture != null && (texture.format == TextureFormat.ARGB32 || texture.format == TextureFormat.RGBA32 || texture.format == TextureFormat.DXT5 || texture.format == TextureFormat.ARGB4444 || texture.format == TextureFormat.BGRA32 || texture.format == TextureFormat.DXT5Crunched //|| texture.format == ... (all alpha formats) ); if (texCanBeTransparent) { bool stop = false; int pixelScanFrequency = 1; for (int x = 0; x < texture.width && !stop; x += pixelScanFrequency) { for (int y = 0; y < texture.height && !stop; y += pixelScanFrequency) { float a = texture.GetPixel(x, y).a; DetectMtlBlendFadeOrCutout(a, ref mode, ref stop); if (stop) { return(mode == MtlBlendMode.FADE || mode == MtlBlendMode.CUTOUT); } } } } return(mode == MtlBlendMode.FADE || mode == MtlBlendMode.CUTOUT); }
/// <summary> /// Set up a Material for the given mode. /// </summary> /// <remarks>Here is replicated what is done when choosing a blend mode from Inspector.</remarks> /// <param name="mtl">material to be changed</param> /// <param name="mode">mode to be set</param> public static void SetupMaterialWithBlendMode(Material mtl, MtlBlendMode mode) { switch (mode) { case MtlBlendMode.OPAQUE: mtl.SetOverrideTag("RenderType", "Opaque"); mtl.SetFloat("_Mode", 0); mtl.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); mtl.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); mtl.SetInt("_ZWrite", 1); mtl.DisableKeyword("_ALPHATEST_ON"); mtl.DisableKeyword("_ALPHABLEND_ON"); mtl.DisableKeyword("_ALPHAPREMULTIPLY_ON"); mtl.renderQueue = -1; break; case MtlBlendMode.CUTOUT: mtl.SetOverrideTag("RenderType", "TransparentCutout"); mtl.SetFloat("_Mode", 1); mtl.SetFloat("_Mode", 1); mtl.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); mtl.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); mtl.SetInt("_ZWrite", 1); mtl.EnableKeyword("_ALPHATEST_ON"); mtl.DisableKeyword("_ALPHABLEND_ON"); mtl.DisableKeyword("_ALPHAPREMULTIPLY_ON"); mtl.renderQueue = 2450; break; case MtlBlendMode.FADE: mtl.SetOverrideTag("RenderType", "Transparent"); mtl.SetFloat("_Mode", 2); mtl.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha); mtl.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); mtl.SetInt("_ZWrite", 0); mtl.DisableKeyword("_ALPHATEST_ON"); mtl.EnableKeyword("_ALPHABLEND_ON"); mtl.DisableKeyword("_ALPHAPREMULTIPLY_ON"); mtl.renderQueue = 3000; break; case MtlBlendMode.TRANSPARENT: mtl.SetOverrideTag("RenderType", "Transparent"); mtl.SetFloat("_Mode", 3); mtl.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); mtl.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); mtl.SetInt("_ZWrite", 0); mtl.DisableKeyword("_ALPHATEST_ON"); mtl.DisableKeyword("_ALPHABLEND_ON"); mtl.EnableKeyword("_ALPHAPREMULTIPLY_ON"); mtl.renderQueue = 3000; break; } }
/// <summary> /// Detect if the blend mode must be set to FADE or CUTOUT /// according to the given alpha value and the current value of mode. /// </summary> /// <param name="alpha">input alpha value</param> /// <param name="mode">blend mode set to FADE or CUTOUT</param> /// <param name="noDoubt">flag set to true if the mode is finally detected (it can be used to break from a scan loop)</param> public static void DetectMtlBlendFadeOrCutout(float alpha, ref MtlBlendMode mode, ref bool noDoubt) { if (noDoubt) { return; } if (alpha < 1.0f) { //mode = MtlBlendMode.TRANSPARENT; if (alpha == 0.0f) { // assume there is a "cutout texture" mode = MtlBlendMode.CUTOUT; } // else 0<alpha<1 else if (mode != MtlBlendMode.FADE) { // assume there is a "fade texture" mode = MtlBlendMode.FADE; noDoubt = true; } } }