Пример #1
0
        private static Material CreateFallbackMaterial(Material originalMaterial, VRC.Core.APIUser user)
        {
#if VRC_CLIENT
            Material fallbackMaterial;
            Color    trustCol    = user != null ? (Color)GetTrustLevelColor(user) : Color.white;
            string   displayName = user != null ? user.displayName : "localUser";

            if (originalMaterial == null || originalMaterial.shader == null)
            {
                fallbackMaterial      = VRC.Core.AssetManagement.CreateMatCap(trustCol * 0.8f + new Color(0.2f, 0.2f, 0.2f));
                fallbackMaterial.name = string.Format("MC_{0}_{1}", fallbackMaterial.shader.name, displayName);
            }
            else
            {
                var safeShader = VRC.Core.AssetManagement.GetSafeShader(originalMaterial.shader.name);
                if (safeShader == null)
                {
                    fallbackMaterial      = VRC.Core.AssetManagement.CreateSafeFallbackMaterial(originalMaterial, trustCol * 0.8f + new Color(0.2f, 0.2f, 0.2f));
                    fallbackMaterial.name = string.Format("FB_{0}_{1}_{2}", fallbackMaterial.shader.name, displayName, originalMaterial.name);
                }
                else
                {
                    //Debug.Log("<color=cyan>*** using safe internal fallback for shader:"+ safeShader.name + "</color>");
                    fallbackMaterial = new Material(safeShader);
                    if (safeShader.name == "Standard" || safeShader.name == "Standard (Specular setup)")
                    {
                        VRC.Core.AssetManagement.SetupBlendMode(fallbackMaterial);
                    }

                    fallbackMaterial.CopyPropertiesFromMaterial(originalMaterial);
                    fallbackMaterial.name = string.Format("INT_{0}_{1}_{2}", fallbackMaterial.shader.name, displayName, originalMaterial.name);
                }
            }

            return(fallbackMaterial);
#else
            // we are in sdk, this is not meaningful anyway
            return(new Material(Shader.Find("Standard")));
#endif
        }
Пример #2
0
        static Material CreateFallbackMaterial(Material mtl, VRC.Core.APIUser user)
        {
#if VRC_CLIENT
            Material newMtl;
            Color    trustCol = (Color)GetTrustLevelColor(user);

            if (mtl != null)
            {
                var safeShader = VRC.Core.AssetManagement.GetSafeShader(mtl.shader.name);
                if (safeShader == null)
                {
                    newMtl      = VRC.Core.AssetManagement.CreateSafeFallbackMaterial(mtl, trustCol * 0.8f + new Color(0.2f, 0.2f, 0.2f));
                    newMtl.name = "FB_" + mtl.shader.name;
                }
                else
                {
                    //Debug.Log("<color=cyan>*** using safe internal fallback for shader:"+ safeShader.name + "</color>");
                    newMtl = new Material(safeShader);
                    if (safeShader.name == "Standard" || safeShader.name == "Standard (Specular setup)")
                    {
                        VRC.Core.AssetManagement.SetupBlendMode(newMtl);
                    }
                    newMtl.CopyPropertiesFromMaterial(mtl);
                    newMtl.name = "INT_" + mtl.shader.name;
                }
            }
            else
            {
                newMtl      = VRC.Core.AssetManagement.CreateMatCap(trustCol * 0.8f + new Color(0.2f, 0.2f, 0.2f));
                newMtl.name = "FB?_";
            }

            return(newMtl);
#else
            // we are in sdk, this is not meaningful anyway
            return(new Material(Shader.Find("Standard")));
#endif
        }
Пример #3
0
        static Color32 GetTrustLevelColor(VRC.Core.APIUser user)
        {
#if VRC_CLIENT
            Color32 color = new Color32(255, 255, 255, 255);
            if (user == null)
            {
                return(color);
            }

            if (user == VRC.Core.APIUser.CurrentUser)
            {
                color = VRCInputManager.showSocialRank ? VRCPlayer.GetColorForSocialRank(user) : VRCPlayer.GetDefaultNameplateColor(user, user.hasVIPAccess);
            }
            else
            {
                color = VRCPlayer.ShouldShowSocialRank(user) ? VRCPlayer.GetColorForSocialRank(user) : VRCPlayer.GetDefaultNameplateColor(user, user.hasVIPAccess);
            }
            return(color);
#else
            // we are in sdk, this is not meaningful anyway
            return((Color32)Color.grey);
#endif
        }
Пример #4
0
 public static void RestoreShaders(VRC.Core.APIUser user, HashSet <Renderer> avatarRenderers, Dictionary <Material, Material> materialSwaps)
 {
     foreach (Renderer r in avatarRenderers)
     {
         Material[] materials = new Material[r.sharedMaterials.Length];
         for (int i = 0; i < r.sharedMaterials.Length; ++i)
         {
             if (r.sharedMaterials[i] == null)
             {
                 // create a temporary shader while loading
                 materials[i] = CreateFallbackMaterial(null, user);
             }
             else if (materialSwaps.ContainsKey(r.sharedMaterials[i]))
             {
                 materials[i] = materialSwaps[r.sharedMaterials[i]];
             }
             else
             {
                 materials[i] = r.sharedMaterials[i];
             }
         }
         r.sharedMaterials = materials;
     }
 }
Пример #5
0
 public static void ReplaceShadersRealtime(VRC.Core.APIUser user, HashSet <Renderer> avatarRenderers, ref Dictionary <Material, Material> materialSwaps)
 {
     ReplaceShaders(user, avatarRenderers, ref materialSwaps, false);
 }
 public static void ReplaceShadersRealtime(VRC.Core.APIUser user, IEnumerable <Renderer> avatarRenderers, FallbackMaterialCache fallbackMaterialCache, bool debug = false)
 {
     ReplaceShaders(user, avatarRenderers, fallbackMaterialCache, debug);
 }
 public static void SetupShaderReplace(VRC.Core.APIUser user, GameObject currentAvatar, HashSet <Renderer> avatarRenderers)
 {
     avatarRenderers.Clear();
     avatarRenderers.UnionWith(currentAvatar.GetComponentsInChildren <SkinnedMeshRenderer>(true));
     avatarRenderers.UnionWith(currentAvatar.GetComponentsInChildren <MeshRenderer>(true));
 }
Пример #8
0
        public static void ReplaceShaders(VRC.Core.APIUser user, List <Renderer> avatarRenderers, FallbackMaterialCache fallbackMaterialCache, bool debug = true)
        {
            foreach (Renderer avatarRenderer in avatarRenderers)
            {
                if (avatarRenderer == null)
                {
                    continue;
                }

                avatarRenderer.GetSharedMaterials(_replaceShadersWorkingList);
                bool materialNeedsReplacement = false;
                foreach (Material material in _replaceShadersWorkingList)
                {
                    // A fallback material exists and is being used.
                    if (fallbackMaterialCache.TryGetFallbackMaterial(material, out Material fallbackMaterial) && material == fallbackMaterial)
                    {
                        continue;
                    }

                    materialNeedsReplacement = true;
                    break;
                }

                if (!materialNeedsReplacement)
                {
                    return;
                }

                Material[] avatarRendererSharedMaterials = avatarRenderer.sharedMaterials;
                for (int i = 0; i < avatarRendererSharedMaterials.Length; ++i)
                {
                    Material currentMaterial = avatarRendererSharedMaterials[i];
                    if (currentMaterial == null)
                    {
                        continue;
                    }

                    if (fallbackMaterialCache.TryGetFallbackMaterial(currentMaterial, out Material fallbackMaterial))
                    {
                        if (debug)
                        {
                            Debug.Log($"<color=cyan>*** Using existing fallback: '{fallbackMaterial.shader.name}' </color>");
                        }
                    }
                    else
                    {
                        // The current material is not in our safe list so create a fallback.
                        fallbackMaterial = CreateFallbackMaterial(currentMaterial, user);

                        // Map the current material to the fallback and the fallback to itself.
                        fallbackMaterialCache.AddFallbackMaterial(currentMaterial, fallbackMaterial);
                        fallbackMaterialCache.AddFallbackMaterial(fallbackMaterial, fallbackMaterial);

                        if (debug)
                        {
                            Debug.Log($"<color=cyan>*** Creating new fallback: '{fallbackMaterial.shader.name}' </color>");
                        }
                    }

                    avatarRendererSharedMaterials[i] = fallbackMaterial;
                }

                avatarRenderer.sharedMaterials = avatarRendererSharedMaterials;
            }
        }
        public static void ReplaceShaders(VRC.Core.APIUser user, List <Renderer> avatarRenderers, FallbackMaterialCache fallbackMaterialCache, bool debug = false)
        {
            foreach (Renderer avatarRenderer in avatarRenderers)
            {
                if (avatarRenderer == null)
                {
                    continue;
                }

                avatarRenderer.GetSharedMaterials(_replaceShadersWorkingList);
                bool anyReplaced = false;
                for (int i = 0; i < _replaceShadersWorkingList.Count; ++i)
                {
                    Material currentMaterial = _replaceShadersWorkingList[i];
                    if (currentMaterial == null)
                    {
                        continue;
                    }

                    // Check if the material has a cached fallback material if not then create a new one.
                    if (!fallbackMaterialCache.TryGetFallbackMaterial(currentMaterial, out Material fallbackMaterial))
                    {
                        fallbackMaterial = CreateFallbackMaterial(currentMaterial, user);

                        // Map the current material to the fallback and the fallback to itself.
                        fallbackMaterialCache.AddFallbackMaterial(currentMaterial, fallbackMaterial);
                        fallbackMaterialCache.AddFallbackMaterial(fallbackMaterial, fallbackMaterial);

                        if (debug)
                        {
                            Debug.Log($"<color=cyan>*** Creating new fallback: '{fallbackMaterial.shader.name}' </color>");
                        }

                        if (fallbackMaterial == currentMaterial)
                        {
                            continue;
                        }

                        _replaceShadersWorkingList[i] = fallbackMaterial;
                        anyReplaced = true;
                        continue;
                    }

                    // If the material is the fallback then we don't need to change it.
                    if (currentMaterial == fallbackMaterial)
                    {
                        continue;
                    }

                    if (debug)
                    {
                        Debug.Log($"<color=cyan>*** Using existing fallback: '{fallbackMaterial.shader.name}' </color>");
                    }

                    _replaceShadersWorkingList[i] = fallbackMaterial;
                    anyReplaced = true;
                }

                if (anyReplaced)
                {
                    avatarRenderer.sharedMaterials = _replaceShadersWorkingList.ToArray();
                }
            }
        }