public static int GetRenderQueueFromCategory(RenderQueueCategory category, bool transparent, int offset, bool alphaClip)
        {
            switch (category)
            {
            case RenderQueueCategory.Background: return(PSXRenderQueue.ChangeType(transparent ? PSXRenderQueue.RenderQueueType.BackgroundTransparent : PSXRenderQueue.RenderQueueType.BackgroundOpaque, offset, alphaClip));

            case RenderQueueCategory.Main: return(PSXRenderQueue.ChangeType(transparent ? PSXRenderQueue.RenderQueueType.MainTransparent : PSXRenderQueue.RenderQueueType.MainOpaque, offset, alphaClip));

            case RenderQueueCategory.UIOverlay: return(PSXRenderQueue.ChangeType(transparent ? PSXRenderQueue.RenderQueueType.UIOverlayTransparent : PSXRenderQueue.RenderQueueType.UIOverlayOpaque, offset, alphaClip));

            default: throw new ArgumentException("category");
            }
        }
        public static void SetupMaterialBlendMode(Material material)
        {
            if (material == null)
            {
                throw new ArgumentNullException("material");
            }

            SurfaceType         surfaceType = (SurfaceType)material.GetFloat(PropertyIDs._Surface);
            RenderQueueCategory category    = (RenderQueueCategory)(int)material.GetFloat(PropertyIDs._RenderQueueCategory);
            bool transparent       = surfaceType == SurfaceType.Transparent;
            int  renderQueueOffset = 0; // TODO: Expose options for user to offset within the queue.
            bool alphaClip         = material.GetFloat(PropertyIDs._AlphaClip) == 1;

            material.renderQueue = GetRenderQueueFromCategory(category, transparent, renderQueueOffset, alphaClip);

            if (alphaClip)
            {
                material.EnableKeyword(Keywords._ALPHATEST_ON);
            }
            else
            {
                material.DisableKeyword(Keywords._ALPHATEST_ON);
            }


            if (surfaceType == SurfaceType.Opaque)
            {
                if (alphaClip)
                {
                    // TODO: Do I actually need to support these override tags? I'm not using them.
                    material.SetOverrideTag(Tags.RenderType, Tags.TransparentCutout);
                }
                else
                {
                    // TODO: Do I actually need to support these override tags? I'm not using them.
                    material.SetOverrideTag(Tags.RenderType, Tags.Opaque);
                }
                material.SetInt(PropertyIDs._BlendOp, (int)UnityEngine.Rendering.BlendOp.Add);
                material.SetInt(PropertyIDs._SrcBlend, (int)UnityEngine.Rendering.BlendMode.One);
                material.SetInt(PropertyIDs._DstBlend, (int)UnityEngine.Rendering.BlendMode.Zero);
                material.SetInt(PropertyIDs._ZWrite, 1);
                material.DisableKeyword(Keywords._ALPHAPREMULTIPLY_ON);
                // material.SetShaderPassEnabled("ShadowCaster", true);
            }
            else // SurfaceType == SurfaceType.Transparent
            {
                PSXMaterialUtils.BlendMode blendMode = (PSXMaterialUtils.BlendMode)material.GetFloat(PropertyIDs._Blend);

                // Specific Transparent Mode Settings
                switch (blendMode)
                {
                case PSXMaterialUtils.BlendMode.AlphaPostmultiply:
                    material.SetInt(PropertyIDs._BlendOp, (int)UnityEngine.Rendering.BlendOp.Add);
                    material.SetInt(PropertyIDs._SrcBlend, (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
                    material.SetInt(PropertyIDs._DstBlend, (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
                    material.DisableKeyword(Keywords._ALPHAPREMULTIPLY_ON);
                    break;

                case PSXMaterialUtils.BlendMode.AlphaPremultiply:
                    material.SetInt(PropertyIDs._BlendOp, (int)UnityEngine.Rendering.BlendOp.Add);
                    material.SetInt(PropertyIDs._SrcBlend, (int)UnityEngine.Rendering.BlendMode.One);
                    material.SetInt(PropertyIDs._DstBlend, (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
                    material.EnableKeyword(Keywords._ALPHAPREMULTIPLY_ON);
                    break;

                case PSXMaterialUtils.BlendMode.Additive:
                    material.SetInt(PropertyIDs._BlendOp, (int)UnityEngine.Rendering.BlendOp.Add);
                    material.SetInt(PropertyIDs._SrcBlend, (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
                    material.SetInt(PropertyIDs._DstBlend, (int)UnityEngine.Rendering.BlendMode.One);
                    material.DisableKeyword(Keywords._ALPHAPREMULTIPLY_ON);
                    break;

                case PSXMaterialUtils.BlendMode.Multiply:
                    material.SetInt(PropertyIDs._BlendOp, (int)UnityEngine.Rendering.BlendOp.Add);
                    material.SetInt(PropertyIDs._SrcBlend, (int)UnityEngine.Rendering.BlendMode.DstColor);
                    material.SetInt(PropertyIDs._DstBlend, (int)UnityEngine.Rendering.BlendMode.Zero);
                    material.DisableKeyword(Keywords._ALPHAPREMULTIPLY_ON);
                    material.EnableKeyword(Keywords._ALPHAMODULATE_ON);
                    break;

                case PSXMaterialUtils.BlendMode.Subtractive:
                    material.SetInt(PropertyIDs._BlendOp, (int)UnityEngine.Rendering.BlendOp.ReverseSubtract);
                    material.SetInt(PropertyIDs._SrcBlend, (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
                    material.SetInt(PropertyIDs._DstBlend, (int)UnityEngine.Rendering.BlendMode.One);
                    material.DisableKeyword(Keywords._ALPHAPREMULTIPLY_ON);
                    material.DisableKeyword(Keywords._ALPHAMODULATE_ON);
                    break;

                default:
                    Debug.Assert(false, "Error: Encountered unsupported blendmode: " + blendMode);
                    break;
                }

                // General Transparent Material Settings
                // TODO: Do I actually need to support these override tags? I'm not using them.
                material.SetOverrideTag(Tags.RenderType, Tags.Transparent);
                material.SetInt(PropertyIDs._ZWrite, 0);
            }
        }