• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by NeatWolf · Nov 22, 2019 at 10:47 AM · shadersspecularreplaceshader-replacementreplacement

How do I globally (per project) replace/edit the builtin Standard PBR (Metallic/Specular) shaders with custom ones?

Hi there!

I would like to make just a few little changes to the builtin shaders and... my game is almost ready for launch. So there are tons of scenes and materials already using the default PBR Metallic/Specular Shaders.

I also have other materials/shaders as well, and they have to stay that way.

I'd like to replace:

  • builtin Standard PBR -> custom Standard PBR

  • builtin Standard PBR (Specular) -> custom Standard PBR (specular)

I'm targeting mobile, OpenGL ES 3.0, gamma color space, forward rendering, Subtractive mode lightmaps.

I found some info about replacement shaders, but I guess it's not exactly what I'd love to obtain.

Is it even technically possible?

I'd like to avoid replacing over 100 of materials manually, unless you can suggest a tool to let me make such switch trivial (back and forth from builtin/custom)

I'm also open to other solutions which would allow to do basically the same.

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
1

Answer by xibanya · Dec 24, 2019 at 04:25 AM

as far as I can tell, you can't update the builtin Standard shader, but you CAN update the builtin CGincludes in C:\Program Files\wherever your editor install is\Editor\Data\CGIncludes (that isn't per-project though, it's everything on that editor version.) If your shaders use the same properties as the standard shader, you could update the CGincludes referenced by the Standard shader (eg, "UnityStandardCoreForward.cginc" to do your thing instead, but tbh I can't recommend doing something like this so close to shipping because it would probably initially break the hell out of all your other surface shaders (and possibly some of your frag shaders too!)

As far as mass-changing shaders on materials, here's my route (simplified for space and readability). I have an Editor Utilities class where I keep editor API helper methods, and in that class I put

 public static List<Material> GetMaterials()
     {
         var matFiles = GetFiles(GetSelectedPathOrFallback()).Where(s => s.Contains(".mat"));
 
         List<Material> toReturn = new List<Material>();
         foreach (string str in matFiles)
         {
             Material mat = (Material)AssetDatabase.LoadAssetAtPath(str, typeof(Material));
             if (mat != null && !toReturn.Contains(mat)) toReturn.Add(mat);
         }
         return toReturn;
     }

which returns a list of all materials in the currently selected directory in Assets. (if none is selected, it'll run the search of ALL your assets.)

this uses a great utility method that I didn't write,

 //https://gist.github.com/kimsama/ff69cca140468f92d755
 public static string GetSelectedPathOrFallback()
 {
     string path = "Assets";
 
     foreach (UnityObject obj in Selection.GetFiltered(typeof(UnityObject), SelectionMode.Assets))
     {
         path = AssetDatabase.GetAssetPath(obj);
         if (!string.IsNullOrEmpty(path) && File.Exists(path))
         {
             path = Path.GetDirectoryName(path);
             break;
         }
     }
     return path;
 }

Then have an editor window that creates a dictionary of the shaders you want to replace and the shaders you want to replace them with and use that to replace all the materials in the current directory. to avoid having half the answer be taken up by EditorGUI code, I'll show a hardcoded dictionary, but ideally you'd actually get the shaders from object fields.

 using UnityEngine;
 using UnityEditor;
 using System.Collections.Generic;
 using System;
 using System.Linq;
 public class ShaderStandardizer : EditorWindow
 {
 private Dictionary<Shader, Shader> toReplace = new Dictionary<Shader, Shader>();
         private bool initialized;
         [MenuItem("Tools/MyTools/Shader Replacer")]
         private static void OpenWindow()
         {
             GetWindow<ShaderStandardizer>().Show();
         }
         void InitializeDictionary()
         {
             if (!initialized)
             {
                 toReplace.Add(Shader.Find("Standard"), Shader.Find("MyStudio/Category/ShaderName"));
                 toReplace.Add(Shader.Find("Standard (Specular setup)"), Shader.Find("MyStudio/Category/OtherShaderName"));
                 toReplace.Add(Shader.Find("Legacy Shaders/Bumped Specular"), Shader.Find("MyStudio/OtherCategory/ShaderName"));
                 initialized = true;
             }
         }
         protected override void OnGUI()
         {
             InitializeDictionary();
             if (GUILayout.Button("Replace"))
             {
                 string path = MyEditorUtils.GetSelectedPathOrFallback();
                 if (path != "Assets" || EditorUtility.DisplayDialog(
                     "Search from root?",
                     "Searching all assets from root can potentially lock Unity. Proceed?",
                     "OK", "Cancel"))
                 {
                     List<Material> materials = MyEditorUtils.GetMaterials().FindAll(m => toReplace.Keys.Contains(m.shader));
                     string title = string.Format("Update {0} materials?", materials.Count);
                     string message = string.Format("This operation will update {0} materials in {1} and subfolders. Proceed?", materials.Count, path);
                     string report = "UPDATED";
                     if (EditorUtility.DisplayDialog(title, message, "OK", "Cancel"))
                     {
                         foreach (Material material in materials)
                         {
                             report += string.Format("\n{0} from {1} to {2}", AssetDatabase.GetAssetPath(material), material.shader.name, materials[material.shader].name);
                             material.shader = materials[material.shader];
                         }
                     }
                     //use System.IO to write the report to a text file or something
                 }
             }
         }
         protected void OnDisable()
         {
             Resources.UnloadUnusedAssets();
         }
 }

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.



Follow this Question

Answers Answers and Comments

126 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Why are Cubemaps and Specular highlights not equally blurry at the same Roughness / Glossyness value with standard pbr shader? 0 Answers

Tree Nature Shader 0 Answers

Five colors gradient on sprite 1 Answer

SOLVED - String replace % with " in C# 1 Answer

For a glass shader: How to "Fallback" completely 100% transparent that works in all device or that it do not render at all? 0 Answers

  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges