Standard Shader's Metalness sliders broken on custom GUI

Hi there.
I recently wanted to fiddle with the Standard Shader, and to do that I had to download it from unitys website… In order to directly alter the shader’s inspector properties, you have to remove the line at the end of the code:

After doing that, everything works fine, except for the Metalness.

On the regular Standard shader, when you don’t have an image assigned to the Metalness slot, you have both a Metalness and Smoothness sliders. When you insert an image on that slot, both sliders disappear, and those two parameters are then controlled by the Red channel (metalness) and Alpha (smoothness) channels of the image, if I’m not mistaken.

But simply removing that last line from the standard shader seems to break the shader so that it stops reading the Metalness Image Slot, and instead only considers the sliders, even if there’s an image on the slot (which wouldn’t happen on the regular inspector).

Is this a bug? Any way to “unbreak” the shader so that it stops reading the sliders if there is an image there, and if there is not only then it reads the sliders… as it is supposed to do?

How to reproduce:
-Download the builtin shaders from Download Archive
-Open the standard shader on any text/code editor and remove the line "CustomEditor “StandardShaderGUI”
-Create a new material, assign it to a new object, assign the shader to that material.
-Check the Metalness and Smoothness sliders, now put a Metalness Image on the image slot and see that it changes nothing, with or without image the result is the same, only the sliders works on changing anything, but in the regular shader the Image replaces the sliders (or makes them useless… that should be the correct behavior.

Also, it seems both Height Map and Height Intensity slider also become useless after you stop using the ‘stardardshaderGUI’…

It appears that if you change the shader of a material to the regular Standard, and then back to the altered Stardard, you can change if the image has priority over the sliders or vice versa, and also if the height map works or not. So it definitely seems like some code is interfering with the other or leaving something behind.

Regards
@UnityGuillaume

The custom editor is setting shader keywords to enable and disable the textures and blend mode based on the settings you use. If you remove the custom editor there’s no way to enable these keywords from the inspector.

Yes, exactly what @bgolus said.

If you open StandardShaderGUI, there is a function called “SetMaterialKeywords” with in it a bunch of call to SetKeyword (which in turn call EnableKeyword/DisableKeyword on the material) depending of whether or not the textures are null.

If you open Standard.shader, you will see a #pragma shader_feature KEYWORD (e.g. _METALLICGLOSSMAP) and then in UnityStandardInput.cginc there is #ifdef KEYWORD (e.g. line 138 for _METALLICGLOSSMAP)

If you’re familiar with define in C/C++/C#, you will understand what that do : it’s a simple logic structure (if/else if/else) that will include ONLY the line that satisfy the condition (here if _METALLICGLOSSMAP is defined, it will include the first line, if not the second) at compile time.

#pragma shader_feature KEYWORD is here to tell the shader compiler : there is 2 version of that shader : one with the keyword, and one without. The compiler will compile the two (with the keyword defined then not defined) and then your material will use the right shader depending on whether or not it define that keyword.

Hope that is clear enough, let me know if you have more questions.

Thanks guys…

@UnityGuillaume , yes it is clear, thanks for the explanation.
Unfortunatelly I have only superficial knowledge on coding, therefore I won’t be able to do what I was expecting.

Basically my goal was to insert an Outline pass inside of the standard PBR shader…I managed to create a PBR/Outline shader on Shaderforge, but I much prefer unity’s own standard PBR shader… It seems prettier to me.
So I first tried to do a copy paste of the pass on the Standard Shader, only to discover that the Outline Color and Outline Width parameters weren’t showing on the Inspector. Searching for a solution I stumbled upon your response on how to alter the inspector removing the CustomEditor line. So I did it, and doing so I managed to have a functional outlined PBR shader.
Here is the code:
Standard PBR Outline

The only problem is that by removing the CustomEditor I broke the rest of the code. Therefore I’m left with two options… Not having the Outline Color and Width parameters on the inspector, or having them on the inspector but with the rest of the shader partially broken.
If you guys can guide me on fixing the keywords for this shader I’d appreciate greaty.
But if not, it’s ok… I’ll move on, even though it seems like I’m close, and it would be good for the community to have a new outline shader that is not a Legacy one but a PBR one.

All I’d need to have is a snippet of that Define structure, for maybe only the Metallness, or Height, etc. and where in the code this section would go… the rest I could work my way through, copy/pasting, replacing and editing. :slight_smile:

Regards

So you have a couple of choices.

You can write your own custom editor. Copy the existing StandardShaderGUI.cs, rename it to StandardShaderOutlineGUI.cs and add the code required to include outline width and outline color.

You can inject the outline using command buffers. Sounds scarier than it is, and can be only a handful of lines of code, but it’s still coding.

Instead of modifying the full Standard shader you can make a Standard surface shader (one of the options when you do “new shader” from the project window) and add the outline pass to that shader. With a surface shader you won’t be able to toggle all of the options, but that might be fine if most of your shaders use the same set (ie: they’re all using a diffuse map and metal map, but not using the height map). You’ll have to modify that surface shader to make it take textures instead of ranges if that’s the case.