< Summary

Class:UnityEditor.PbrShaderGUI
Assembly:UnityGLTFEditorAssembly
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/UnityGLTF/Scripts/Editor/PbrShaderGUI.cs
Covered lines:0
Uncovered lines:146
Coverable lines:146
Total lines:295
Line coverage:0% (0 of 146)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
Styles()0%2100%
PbrShaderGUI()0%2100%
FindProperties(...)0%30500%
OnGUI(...)0%6200%
ShaderPropertiesGUI(...)0%56700%
DetermineWorkflow(...)0%30500%
BlendModePopup()0%6200%
DoAlbedoArea(...)0%6200%
DoEmissionArea(...)0%20400%
DoSpecularMetallicArea()0%1321100%
SetupMaterialWithBlendMode(...)0%20400%
SetMaterialKeywords(...)0%12300%
MaterialChanged(...)0%2100%
SetKeyword(...)0%6200%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/UnityGLTF/Scripts/Editor/PbrShaderGUI.cs

#LineLine coverage
 1// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
 2
 3using System;
 4using UnityEngine;
 5
 6namespace UnityEditor
 7{
 8    internal class PbrShaderGUI : ShaderGUI
 9    {
 10        private enum WorkflowMode
 11        {
 12            SpecularGlossiness,
 13            MetallicRoughness,
 14            Unlit
 15        }
 16
 17        public enum BlendMode
 18        {
 19            Opaque,
 20            Mask,
 21            Blend
 22        }
 23
 24        private static class Styles
 25        {
 026            public static GUIContent albedoText = new GUIContent("Base Color", "Albedo (RGB) and Transparency (A)");
 027            public static GUIContent alphaCutoffText = new GUIContent("Alpha Cutoff", "Threshold for alpha cutoff");
 028            public static GUIContent specularMapText = new GUIContent("Spec Gloss", "Specular (RGB) and Glossiness (A)")
 029            public static GUIContent metallicMapText = new GUIContent("Metal Rough", "Metallic (B) and Roughness (G)");
 030            public static GUIContent metallicText = new GUIContent("Metallic", "Metallic value");
 031            public static GUIContent metallicScaleText = new GUIContent("Metallic", "Metallic scale factor");
 032            public static GUIContent roughnessText = new GUIContent("Roughness", "Roughness value");
 33
 034            public static GUIContent roughnessScaleText = new GUIContent("Roughness", "Roughness scale factor");
 035            public static GUIContent glossinessText = new GUIContent("Glossiness", "Glossiness value");
 036            public static GUIContent glossinessScaleText = new GUIContent("Glossiness", "Glossiness scale factor");
 037            public static GUIContent normalMapText = new GUIContent("Normal Map", "Normal Map");
 038            public static GUIContent occlusionText = new GUIContent("Occlusion", "Occlusion (R)");
 039            public static GUIContent emissionText = new GUIContent("Emissive", "Emissive (RGB)");
 40
 041            public static string primaryMapsText = "Main Maps";
 042            public static string renderingMode = "Rendering Mode";
 043            public static GUIContent emissiveWarning = new GUIContent("Emissive value is animated but the material has n
 044            public static readonly string[] blendNames = Enum.GetNames(typeof(BlendMode));
 45        }
 46
 47        MaterialProperty blendMode = null;
 48        MaterialProperty albedoMap = null;
 49        MaterialProperty albedoColor = null;
 50        MaterialProperty alphaCutoff = null;
 51        MaterialProperty specularMap = null;
 52        MaterialProperty specularColor = null;
 53        MaterialProperty metallicMap = null;
 54        MaterialProperty metallic = null;
 55        MaterialProperty smoothness = null;
 56        MaterialProperty bumpScale = null;
 57        MaterialProperty bumpMap = null;
 58        MaterialProperty occlusionStrength = null;
 59        MaterialProperty occlusionMap = null;
 60        MaterialProperty emissionColor = null;
 61        MaterialProperty emissionMap = null;
 62
 63        MaterialEditor m_MaterialEditor;
 064        WorkflowMode m_WorkflowMode = WorkflowMode.MetallicRoughness;
 65
 066        bool m_FirstTimeApply = true;
 67
 68        public void FindProperties(MaterialProperty[] props)
 69        {
 070            blendMode = FindProperty("_Mode", props);
 071            albedoMap = FindProperty("_MainTex", props);
 072            albedoColor = FindProperty("_Color", props);
 073            alphaCutoff = FindProperty("_Cutoff", props);
 074            specularMap = FindProperty("_SpecGlossMap", props, false);
 075            specularColor = FindProperty("_SpecColor", props, false);
 076            metallicMap = FindProperty("_MetallicGlossMap", props, false);
 077            metallic = FindProperty("_Metallic", props, false);
 078            if (specularMap != null && specularColor != null)
 79            {
 080                m_WorkflowMode = WorkflowMode.SpecularGlossiness;
 081            }
 082            else if (metallicMap != null && metallic != null)
 83            {
 084                m_WorkflowMode = WorkflowMode.MetallicRoughness;
 085            }
 86            else
 87            {
 088                m_WorkflowMode = WorkflowMode.Unlit;
 89            }
 90
 091            smoothness = FindProperty("_Glossiness", props);
 092            bumpScale = FindProperty("_BumpScale", props);
 093            bumpMap = FindProperty("_BumpMap", props);
 094            occlusionStrength = FindProperty("_OcclusionStrength", props);
 095            occlusionMap = FindProperty("_OcclusionMap", props);
 096            emissionColor = FindProperty("_EmissionColor", props);
 097            emissionMap = FindProperty("_EmissionMap", props);
 098        }
 99
 100        public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] props)
 101        {
 0102            FindProperties(props); // MaterialProperties can be animated so we do not cache them but fetch them every ev
 0103            m_MaterialEditor = materialEditor;
 0104            Material material = materialEditor.target as Material;
 105
 106            // Make sure that needed setup (ie keywords/renderqueue) are set up if we're switching some existing
 107            // material to a standard shader.
 108            // Do this before any GUI code has been issued to prevent layout issues in subsequent GUILayout statements (
 0109            if (m_FirstTimeApply)
 110            {
 0111                MaterialChanged(material, m_WorkflowMode);
 0112                m_FirstTimeApply = false;
 113            }
 114
 0115            ShaderPropertiesGUI(material);
 0116        }
 117
 118        public void ShaderPropertiesGUI(Material material)
 119        {
 120            // Use default labelWidth
 0121            EditorGUIUtility.labelWidth = 0f;
 122
 123            // Detect any changes to the material
 0124            EditorGUI.BeginChangeCheck();
 125            {
 0126                BlendModePopup();
 127
 128                // Primary properties
 0129                GUILayout.Label(Styles.primaryMapsText, EditorStyles.boldLabel);
 0130                DoAlbedoArea(material);
 0131                DoSpecularMetallicArea();
 0132                m_MaterialEditor.TexturePropertySingleLine(Styles.normalMapText, bumpMap, bumpMap.textureValue != null ?
 0133                m_MaterialEditor.TexturePropertySingleLine(Styles.occlusionText, occlusionMap, occlusionMap.textureValue
 0134                DoEmissionArea(material);
 135
 0136                EditorGUILayout.Space();
 137            }
 0138            if (EditorGUI.EndChangeCheck())
 139            {
 0140                foreach (var obj in blendMode.targets)
 141                {
 0142                    MaterialChanged((Material)obj, m_WorkflowMode);
 143                }
 144            }
 0145        }
 146
 147        internal void DetermineWorkflow(MaterialProperty[] props)
 148        {
 0149            if (FindProperty("_SpecGlossMap", props, false) != null && FindProperty("_SpecColor", props, false) != null)
 150            {
 0151                m_WorkflowMode = WorkflowMode.SpecularGlossiness;
 0152            }
 0153            else if (FindProperty("_MetallicGlossMap", props, false) != null && FindProperty("_Metallic", props, false) 
 154            {
 0155                m_WorkflowMode = WorkflowMode.MetallicRoughness;
 0156            }
 157            else
 158            {
 0159                m_WorkflowMode = WorkflowMode.Unlit;
 160            }
 0161        }
 162
 163        void BlendModePopup()
 164        {
 0165            EditorGUI.showMixedValue = blendMode.hasMixedValue;
 0166            var mode = (BlendMode)blendMode.floatValue;
 167
 0168            EditorGUI.BeginChangeCheck();
 0169            mode = (BlendMode)EditorGUILayout.Popup(Styles.renderingMode, (int)mode, Styles.blendNames);
 0170            if (EditorGUI.EndChangeCheck())
 171            {
 0172                m_MaterialEditor.RegisterPropertyChangeUndo("Rendering Mode");
 0173                blendMode.floatValue = (float)mode;
 174            }
 175
 0176            EditorGUI.showMixedValue = false;
 0177        }
 178
 179        void DoAlbedoArea(Material material)
 180        {
 0181            m_MaterialEditor.TexturePropertySingleLine(Styles.albedoText, albedoMap, albedoColor);
 0182            if (((BlendMode)material.GetFloat("_Mode") == BlendMode.Mask))
 183            {
 0184                m_MaterialEditor.ShaderProperty(alphaCutoff, Styles.alphaCutoffText.text, MaterialEditor.kMiniTextureFie
 185            }
 0186        }
 187
 188        void DoEmissionArea(Material material)
 189        {
 0190            bool hadEmissionTexture = emissionMap.textureValue != null;
 191
 192            // Texture and HDR color controls
 0193            m_MaterialEditor.TexturePropertySingleLine(Styles.emissionText, emissionMap, emissionColor);
 194
 195            // If texture was assigned and color was black set color to white
 0196            float brightness = emissionColor.colorValue.maxColorComponent;
 0197            if (emissionMap.textureValue != null && !hadEmissionTexture && brightness <= 0f)
 198            {
 0199                emissionColor.colorValue = Color.white;
 200            }
 0201        }
 202
 203        void DoSpecularMetallicArea()
 204        {
 0205            bool hasGlossMap = false;
 0206            if (m_WorkflowMode == WorkflowMode.SpecularGlossiness)
 207            {
 0208                hasGlossMap = specularMap.textureValue != null;
 0209                m_MaterialEditor.TexturePropertySingleLine(Styles.specularMapText, specularMap, hasGlossMap ? null : spe
 0210                m_MaterialEditor.ShaderProperty(smoothness, hasGlossMap ? Styles.glossinessScaleText : Styles.glossiness
 0211            }
 0212            else if (m_WorkflowMode == WorkflowMode.MetallicRoughness)
 213            {
 0214                hasGlossMap = metallicMap.textureValue != null;
 0215                m_MaterialEditor.TexturePropertySingleLine(Styles.metallicMapText, metallicMap);
 0216                m_MaterialEditor.ShaderProperty(metallic, hasGlossMap ? Styles.metallicScaleText : Styles.metallicText, 
 0217                m_MaterialEditor.ShaderProperty(smoothness, hasGlossMap ? Styles.roughnessScaleText : Styles.roughnessTe
 218            }
 0219        }
 220
 221        public static void SetupMaterialWithBlendMode(Material material, BlendMode blendMode, float alphaCutoff)
 222        {
 223            switch (blendMode)
 224            {
 225                case BlendMode.Opaque:
 0226                    material.SetOverrideTag("RenderType", "Opaque");
 0227                    material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
 0228                    material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
 0229                    material.SetInt("_ZWrite", 1);
 0230                    material.DisableKeyword("_ALPHATEST_ON");
 0231                    material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
 0232                    material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Geometry;
 0233                    break;
 234                case BlendMode.Mask:
 0235                    material.SetOverrideTag("RenderType", "TransparentCutout");
 0236                    material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
 0237                    material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
 0238                    material.SetInt("_ZWrite", 1);
 0239                    material.EnableKeyword("_ALPHATEST_ON");
 0240                    material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
 0241                    material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.AlphaTest;
 0242                    material.SetFloat("_Cutoff", alphaCutoff);
 0243                    break;
 244                case BlendMode.Blend:
 0245                    material.SetOverrideTag("RenderType", "Transparent");
 0246                    material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
 0247                    material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
 0248                    material.SetInt("_ZWrite", 0);
 0249                    material.DisableKeyword("_ALPHATEST_ON");
 0250                    material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
 0251                    material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent;
 252                    break;
 253            }
 254
 0255            material.SetFloat("_Surface", (float)blendMode);
 0256        }
 257
 258        static void SetMaterialKeywords(Material material, WorkflowMode workflowMode)
 259        {
 260            // Note: keywords must be based on Material value not on MaterialProperty due to multi-edit & material anima
 261            // (MaterialProperty value might come from renderer material property block)
 0262            SetKeyword(material, "_NORMALMAP", material.GetTexture("_BumpMap"));
 0263            if (workflowMode == WorkflowMode.SpecularGlossiness)
 264            {
 0265                SetKeyword(material, "_SPECGLOSSMAP", material.GetTexture("_SpecGlossMap"));
 0266            }
 0267            else if (workflowMode == WorkflowMode.MetallicRoughness)
 268            {
 0269                SetKeyword(material, "_METALLICGLOSSMAP", material.GetTexture("_MetallicGlossMap"));
 270            }
 271
 0272            bool shouldEmissionBeEnabled = material.GetColor("_EmissionColor") != Color.black;
 0273            SetKeyword(material, "_EMISSION", shouldEmissionBeEnabled);
 0274        }
 275
 276        static void MaterialChanged(Material material, WorkflowMode workflowMode)
 277        {
 0278            SetupMaterialWithBlendMode(material, (BlendMode)material.GetFloat("_Mode"), material.GetFloat("_Cutoff"));
 279
 0280            SetMaterialKeywords(material, workflowMode);
 0281        }
 282
 283        static void SetKeyword(Material m, string keyword, bool state)
 284        {
 0285            if (state)
 286            {
 0287                m.EnableKeyword(keyword);
 0288            }
 289            else
 290            {
 0291                m.DisableKeyword(keyword);
 292            }
 0293        }
 294    }
 295} // namespace UnityEditor