forked from cgvr/DeltaVR
		
	
		
			
				
	
	
		
			581 lines
		
	
	
		
			31 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			581 lines
		
	
	
		
			31 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
#if UNITY_EDITOR
 | 
						|
 | 
						|
// Disable 'obsolete' warnings
 | 
						|
#pragma warning disable 0618
 | 
						|
#pragma warning disable 0612
 | 
						|
 | 
						|
using System;
 | 
						|
using UnityEngine;
 | 
						|
 | 
						|
namespace UnityEditor
 | 
						|
{
 | 
						|
    public class BakeryShaderGUI : ShaderGUI
 | 
						|
    {
 | 
						|
        private enum WorkflowMode
 | 
						|
        {
 | 
						|
            Specular,
 | 
						|
            Metallic,
 | 
						|
            Dielectric
 | 
						|
        }
 | 
						|
 | 
						|
        public enum BlendMode
 | 
						|
        {
 | 
						|
            Opaque,
 | 
						|
            Cutout,
 | 
						|
            Fade,		// Old school alpha-blending mode, fresnel does not affect amount of transparency
 | 
						|
            Transparent // Physically plausible transparency mode, implemented as alpha pre-multiply
 | 
						|
        }
 | 
						|
 | 
						|
        public enum SmoothnessMapChannel
 | 
						|
        {
 | 
						|
            SpecularMetallicAlpha,
 | 
						|
            AlbedoAlpha,
 | 
						|
        }
 | 
						|
 | 
						|
        private static class Styles
 | 
						|
        {
 | 
						|
            public static GUIStyle optionsButton = "PaneOptions";
 | 
						|
            public static GUIContent uvSetLabel = new GUIContent("UV Set");
 | 
						|
            public static GUIContent[] uvSetOptions = new GUIContent[] { new GUIContent("UV channel 0"), new GUIContent("UV channel 1") };
 | 
						|
 | 
						|
            public static string emptyTootip = "";
 | 
						|
            public static GUIContent albedoText = new GUIContent("Albedo", "Albedo (RGB) and Transparency (A)");
 | 
						|
            public static GUIContent alphaCutoffText = new GUIContent("Alpha Cutoff", "Threshold for alpha cutoff");
 | 
						|
            public static GUIContent specularMapText = new GUIContent("Specular", "Specular (RGB) and Smoothness (A)");
 | 
						|
            public static GUIContent metallicMapText = new GUIContent("Metallic", "Metallic (R) and Smoothness (A)");
 | 
						|
            public static GUIContent smoothnessText = new GUIContent("Smoothness", "Smoothness value");
 | 
						|
            public static GUIContent smoothnessScaleText = new GUIContent("Smoothness", "Smoothness scale factor");
 | 
						|
            public static GUIContent smoothnessMapChannelText = new GUIContent("Source", "Smoothness texture and channel");
 | 
						|
            public static GUIContent highlightsText = new GUIContent("Specular Highlights", "Specular Highlights");
 | 
						|
            public static GUIContent reflectionsText = new GUIContent("Reflections", "Glossy Reflections");
 | 
						|
            public static GUIContent normalMapText = new GUIContent("Normal Map", "Normal Map");
 | 
						|
            public static GUIContent heightMapText = new GUIContent("Height Map", "Height Map (G)");
 | 
						|
            public static GUIContent occlusionText = new GUIContent("Occlusion", "Occlusion (G)");
 | 
						|
            public static GUIContent emissionText = new GUIContent("Emission", "Emission (RGB)");
 | 
						|
            public static GUIContent detailMaskText = new GUIContent("Detail Mask", "Mask for Secondary Maps (A)");
 | 
						|
            public static GUIContent detailAlbedoText = new GUIContent("Detail Albedo x2", "Albedo (RGB) multiplied by 2");
 | 
						|
            public static GUIContent detailNormalMapText = new GUIContent("Normal Map", "Normal Map");
 | 
						|
 | 
						|
            public static string whiteSpaceString = " ";
 | 
						|
            public static string primaryMapsText = "Main Maps";
 | 
						|
            public static string secondaryMapsText = "Secondary Maps";
 | 
						|
            public static string forwardText = "Forward Rendering Options";
 | 
						|
            public static string renderingMode = "Rendering Mode";
 | 
						|
            public static GUIContent emissiveWarning = new GUIContent("Emissive value is animated but the material has not been configured to support emissive. Please make sure the material itself has some amount of emissive.");
 | 
						|
            public static GUIContent emissiveColorWarning = new GUIContent("Ensure emissive color is non-black for emission to have effect.");
 | 
						|
            public static readonly string[] blendNames = Enum.GetNames(typeof(BlendMode));
 | 
						|
 | 
						|
            public static string bakeryText = "Bakery Options";
 | 
						|
            public static GUIContent doubleSidedLabel = new GUIContent("Double-sided", "Render both sides of triangles.");
 | 
						|
            public static GUIContent vertexLMLabel = new GUIContent("Allow Vertex Lightmaps", "Allows this material to use vertex lightmaps, if present.");
 | 
						|
            public static GUIContent vertexLMdirLabel = new GUIContent("Enable VertexLM directional", "Enables directional vertex lightmaps.");
 | 
						|
            public static GUIContent vertexLMSHLabel = new GUIContent("Enable VertexLM SH", "Enables SH vertex lightmaps.");
 | 
						|
            public static GUIContent vertexLMMaskLabel = new GUIContent("Enable VertexLM Shadowmask", "Enables per-vertex shadowmasks.");
 | 
						|
            public static GUIContent rnmLabel = new GUIContent("Allow RNM Lightmaps", "Allows this material to use RNM lightmaps, if present.");
 | 
						|
            public static GUIContent shLabel = new GUIContent("Allow SH Lightmaps", "Allows this material to use SH lightmaps, if present.");
 | 
						|
            public static GUIContent shnLabel = new GUIContent("Non-linear SH", "This option can enhance contrast (closer to ground truth), but it makes the shader a bit slower.");
 | 
						|
            public static GUIContent specLabel = new GUIContent("Enable Lightmap Specular", "Enables baked specular for all directional modes.");
 | 
						|
            public static GUIContent bicubicLabel = new GUIContent("Force Bicubic Filter", "Enables bicubic filtering for all lightmaps (color/shadowmask/direction/etc) used in the material.");
 | 
						|
            public static GUIContent pshnLabel = new GUIContent("Non-linear Light Probe SH", "Prevents negative values in light probes. This is recommended when baking probes in L1 mode. Can slow down the shader a bit.");
 | 
						|
            public static GUIContent volLabel = new GUIContent("Enable Volumes", "Enable usages of BakeryVolumes");
 | 
						|
            public static GUIContent volLabel0 = new GUIContent("Volume 0");
 | 
						|
            public static GUIContent volLabel1 = new GUIContent("Volume 1");
 | 
						|
            public static GUIContent volLabel2 = new GUIContent("Volume 2");
 | 
						|
            public static GUIContent volLabelMask = new GUIContent("Volume mask");
 | 
						|
        }
 | 
						|
 | 
						|
        MaterialProperty blendMode = null;
 | 
						|
        MaterialProperty albedoMap = null;
 | 
						|
        MaterialProperty albedoColor = null;
 | 
						|
        MaterialProperty alphaCutoff = null;
 | 
						|
        MaterialProperty specularMap = null;
 | 
						|
        MaterialProperty specularColor = null;
 | 
						|
        MaterialProperty metallicMap = null;
 | 
						|
        MaterialProperty metallic = null;
 | 
						|
        MaterialProperty smoothness = null;
 | 
						|
        MaterialProperty smoothnessScale = null;
 | 
						|
        MaterialProperty smoothnessMapChannel = null;
 | 
						|
        MaterialProperty highlights = null;
 | 
						|
        MaterialProperty reflections = null;
 | 
						|
        MaterialProperty bumpScale = null;
 | 
						|
        MaterialProperty bumpMap = null;
 | 
						|
        MaterialProperty occlusionStrength = null;
 | 
						|
        MaterialProperty occlusionMap = null;
 | 
						|
        MaterialProperty heigtMapScale = null;
 | 
						|
        MaterialProperty heightMap = null;
 | 
						|
        MaterialProperty emissionColorForRendering = null;
 | 
						|
        MaterialProperty emissionMap = null;
 | 
						|
        MaterialProperty detailMask = null;
 | 
						|
        MaterialProperty detailAlbedoMap = null;
 | 
						|
        MaterialProperty detailNormalMapScale = null;
 | 
						|
        MaterialProperty detailNormalMap = null;
 | 
						|
        MaterialProperty uvSetSecondary = null;
 | 
						|
        MaterialProperty enableDoubleSided = null;
 | 
						|
        MaterialProperty enableDoubleSidedOn = null;
 | 
						|
        MaterialProperty enableVertexLM = null;
 | 
						|
        MaterialProperty enableVertexLMdir = null;
 | 
						|
        MaterialProperty enableVertexLMSH = null;
 | 
						|
        MaterialProperty enableVertexLMmask = null;
 | 
						|
        MaterialProperty enableSH = null;
 | 
						|
        MaterialProperty enableSHN = null;
 | 
						|
        MaterialProperty enableRNM = null;
 | 
						|
        MaterialProperty enableSpec = null;
 | 
						|
        MaterialProperty enableBicubic = null;
 | 
						|
        MaterialProperty enablePSHN = null;
 | 
						|
        MaterialProperty enableVolumes = null;
 | 
						|
        MaterialProperty volume0 = null;
 | 
						|
        MaterialProperty volume1 = null;
 | 
						|
        MaterialProperty volume2 = null;
 | 
						|
        MaterialProperty volumeMask = null;
 | 
						|
        MaterialProperty volumeMin = null;
 | 
						|
        MaterialProperty volumeInvSize = null;
 | 
						|
 | 
						|
        BakeryVolume assignedVolume = null;
 | 
						|
 | 
						|
        MaterialEditor m_MaterialEditor;
 | 
						|
        WorkflowMode m_WorkflowMode = WorkflowMode.Specular;
 | 
						|
        ColorPickerHDRConfig m_ColorPickerHDRConfig = new ColorPickerHDRConfig(0f, 99f, 1 / 99f, 3f);
 | 
						|
 | 
						|
        bool m_FirstTimeApply = true;
 | 
						|
 | 
						|
        public void FindProperties(MaterialProperty[] props)
 | 
						|
        {
 | 
						|
            blendMode = FindProperty("_Mode", props);
 | 
						|
            albedoMap = FindProperty("_MainTex", props);
 | 
						|
            albedoColor = FindProperty("_Color", props);
 | 
						|
            alphaCutoff = FindProperty("_Cutoff", props);
 | 
						|
            specularMap = FindProperty("_SpecGlossMap", props, false);
 | 
						|
            specularColor = FindProperty("_SpecColor", props, false);
 | 
						|
            metallicMap = FindProperty("_MetallicGlossMap", props, false);
 | 
						|
            metallic = FindProperty("_Metallic", props, false);
 | 
						|
            if (specularMap != null && specularColor != null)
 | 
						|
                m_WorkflowMode = WorkflowMode.Specular;
 | 
						|
            else if (metallicMap != null && metallic != null)
 | 
						|
                m_WorkflowMode = WorkflowMode.Metallic;
 | 
						|
            else
 | 
						|
                m_WorkflowMode = WorkflowMode.Dielectric;
 | 
						|
            smoothness = FindProperty("_Glossiness", props);
 | 
						|
            smoothnessScale = FindProperty("_GlossMapScale", props, false);
 | 
						|
            smoothnessMapChannel = FindProperty("_SmoothnessTextureChannel", props, false);
 | 
						|
            highlights = FindProperty("_SpecularHighlights", props, false);
 | 
						|
            reflections = FindProperty("_GlossyReflections", props, false);
 | 
						|
            bumpScale = FindProperty("_BumpScale", props);
 | 
						|
            bumpMap = FindProperty("_BumpMap", props);
 | 
						|
            heigtMapScale = FindProperty("_Parallax", props);
 | 
						|
            heightMap = FindProperty("_ParallaxMap", props);
 | 
						|
            occlusionStrength = FindProperty("_OcclusionStrength", props);
 | 
						|
            occlusionMap = FindProperty("_OcclusionMap", props);
 | 
						|
            emissionColorForRendering = FindProperty("_EmissionColor", props);
 | 
						|
            emissionMap = FindProperty("_EmissionMap", props);
 | 
						|
            detailMask = FindProperty("_DetailMask", props);
 | 
						|
            detailAlbedoMap = FindProperty("_DetailAlbedoMap", props);
 | 
						|
            detailNormalMapScale = FindProperty("_DetailNormalMapScale", props);
 | 
						|
            detailNormalMap = FindProperty("_DetailNormalMap", props);
 | 
						|
            uvSetSecondary = FindProperty("_UVSec", props);
 | 
						|
            enableDoubleSided = FindProperty("_BAKERY_2SIDED", props);
 | 
						|
            enableDoubleSidedOn = FindProperty("_BAKERY_2SIDEDON", props);
 | 
						|
            enableVertexLM = FindProperty("_BAKERY_VERTEXLM", props);
 | 
						|
            enableVertexLMdir = FindProperty("_BAKERY_VERTEXLMDIR", props);
 | 
						|
            enableVertexLMSH = FindProperty("_BAKERY_VERTEXLMSH", props);
 | 
						|
            enableVertexLMmask = FindProperty("_BAKERY_VERTEXLMMASK", props);
 | 
						|
            enableSH = FindProperty("_BAKERY_SH", props);
 | 
						|
            enableSHN = FindProperty("_BAKERY_SHNONLINEAR", props);
 | 
						|
            enableRNM = FindProperty("_BAKERY_RNM", props);
 | 
						|
            enableSpec = FindProperty("_BAKERY_LMSPEC", props);
 | 
						|
            enableBicubic = FindProperty("_BAKERY_BICUBIC", props);
 | 
						|
            enablePSHN = FindProperty("_BAKERY_PROBESHNONLINEAR", props);
 | 
						|
            enableVolumes = FindProperty("_BAKERY_VOLUME", props);
 | 
						|
            volume0 = FindProperty("_Volume0", props);
 | 
						|
            volume1 = FindProperty("_Volume1", props);
 | 
						|
            volume2 = FindProperty("_Volume2", props);
 | 
						|
            volumeMask = FindProperty("_VolumeMask", props);
 | 
						|
            volumeMin = FindProperty("_VolumeMin", props);
 | 
						|
            volumeInvSize = FindProperty("_VolumeInvSize", props);
 | 
						|
        }
 | 
						|
 | 
						|
        public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] props)
 | 
						|
        {
 | 
						|
            FindProperties(props); // MaterialProperties can be animated so we do not cache them but fetch them every event to ensure animated values are updated correctly
 | 
						|
            m_MaterialEditor = materialEditor;
 | 
						|
            Material material = materialEditor.target as Material;
 | 
						|
 | 
						|
            // Make sure that needed keywords are set up if we're switching some existing
 | 
						|
            // material to a standard shader.
 | 
						|
            if (m_FirstTimeApply)
 | 
						|
            {
 | 
						|
                SetMaterialKeywords(material, m_WorkflowMode);
 | 
						|
                m_FirstTimeApply = false;
 | 
						|
            }
 | 
						|
 | 
						|
            ShaderPropertiesGUI(material);
 | 
						|
        }
 | 
						|
 | 
						|
        public void ShaderPropertiesGUI(Material material)
 | 
						|
        {
 | 
						|
            // Use default labelWidth
 | 
						|
            EditorGUIUtility.labelWidth = 0f;
 | 
						|
 | 
						|
            // Detect any changes to the material
 | 
						|
            EditorGUI.BeginChangeCheck();
 | 
						|
            {
 | 
						|
                BlendModePopup();
 | 
						|
 | 
						|
                // Primary properties
 | 
						|
                GUILayout.Label(Styles.primaryMapsText, EditorStyles.boldLabel);
 | 
						|
                DoAlbedoArea(material);
 | 
						|
                DoSpecularMetallicArea();
 | 
						|
                m_MaterialEditor.TexturePropertySingleLine(Styles.normalMapText, bumpMap, bumpMap.textureValue != null ? bumpScale : null);
 | 
						|
                m_MaterialEditor.TexturePropertySingleLine(Styles.heightMapText, heightMap, heightMap.textureValue != null ? heigtMapScale : null);
 | 
						|
                m_MaterialEditor.TexturePropertySingleLine(Styles.occlusionText, occlusionMap, occlusionMap.textureValue != null ? occlusionStrength : null);
 | 
						|
                DoEmissionArea(material);
 | 
						|
                m_MaterialEditor.TexturePropertySingleLine(Styles.detailMaskText, detailMask);
 | 
						|
                EditorGUI.BeginChangeCheck();
 | 
						|
                m_MaterialEditor.TextureScaleOffsetProperty(albedoMap);
 | 
						|
                if (EditorGUI.EndChangeCheck())
 | 
						|
                {
 | 
						|
                    emissionMap.textureScaleAndOffset = albedoMap.textureScaleAndOffset; // Apply the main texture scale and offset to the emission texture as well, for Enlighten's sake
 | 
						|
                }
 | 
						|
 | 
						|
                EditorGUILayout.Space();
 | 
						|
 | 
						|
                // Secondary properties
 | 
						|
                GUILayout.Label(Styles.secondaryMapsText, EditorStyles.boldLabel);
 | 
						|
                m_MaterialEditor.TexturePropertySingleLine(Styles.detailAlbedoText, detailAlbedoMap);
 | 
						|
                m_MaterialEditor.TexturePropertySingleLine(Styles.detailNormalMapText, detailNormalMap, detailNormalMapScale);
 | 
						|
                m_MaterialEditor.TextureScaleOffsetProperty(detailAlbedoMap);
 | 
						|
                m_MaterialEditor.ShaderProperty(uvSetSecondary, Styles.uvSetLabel.text);
 | 
						|
 | 
						|
                // Third properties
 | 
						|
                GUILayout.Label(Styles.forwardText, EditorStyles.boldLabel);
 | 
						|
                if (highlights != null)
 | 
						|
                    m_MaterialEditor.ShaderProperty(highlights, Styles.highlightsText);
 | 
						|
                if (reflections != null)
 | 
						|
                    m_MaterialEditor.ShaderProperty(reflections, Styles.reflectionsText);
 | 
						|
 | 
						|
                GUILayout.Label(Styles.bakeryText, EditorStyles.boldLabel);
 | 
						|
 | 
						|
                m_MaterialEditor.ShaderProperty(enableDoubleSidedOn, Styles.doubleSidedLabel);
 | 
						|
                enableDoubleSided.floatValue = enableDoubleSidedOn.floatValue > 0 ? 0 : 2;
 | 
						|
 | 
						|
                m_MaterialEditor.ShaderProperty(enableVertexLM, Styles.vertexLMLabel);
 | 
						|
                if (enableVertexLM.floatValue > 0)
 | 
						|
                {
 | 
						|
                    m_MaterialEditor.ShaderProperty(enableVertexLMdir, Styles.vertexLMdirLabel);
 | 
						|
                    //if (enableVertexLMdir.floatValue > 0) enableVertexLMSH.floatValue = 0;
 | 
						|
                }
 | 
						|
                if (enableVertexLM.floatValue > 0)
 | 
						|
                {
 | 
						|
                    m_MaterialEditor.ShaderProperty(enableVertexLMSH, Styles.vertexLMSHLabel);
 | 
						|
                    //if (enableVertexLMSH.floatValue > 0) enableVertexLMdir.floatValue = 0;
 | 
						|
                }
 | 
						|
                if (enableVertexLM.floatValue > 0)
 | 
						|
                {
 | 
						|
                    m_MaterialEditor.ShaderProperty(enableVertexLMmask, Styles.vertexLMMaskLabel);
 | 
						|
                }
 | 
						|
                m_MaterialEditor.ShaderProperty(enableRNM, Styles.rnmLabel);
 | 
						|
                m_MaterialEditor.ShaderProperty(enableSH, Styles.shLabel);
 | 
						|
                if (enableSH.floatValue > 0 || enableVertexLMSH.floatValue > 0)
 | 
						|
                    m_MaterialEditor.ShaderProperty(enableSHN, Styles.shnLabel);
 | 
						|
                m_MaterialEditor.ShaderProperty(enableSpec, Styles.specLabel);
 | 
						|
                m_MaterialEditor.ShaderProperty(enableBicubic, Styles.bicubicLabel);
 | 
						|
                m_MaterialEditor.ShaderProperty(enablePSHN, Styles.pshnLabel);
 | 
						|
 | 
						|
                m_MaterialEditor.ShaderProperty(enableVolumes, Styles.volLabel);
 | 
						|
                if (enableVolumes.floatValue > 0)
 | 
						|
                {
 | 
						|
                    var prevAssignedVolume = assignedVolume;
 | 
						|
                    assignedVolume = EditorGUILayout.ObjectField(volume0.textureValue == null ? "Assign volume" : "Assign different volume", assignedVolume, typeof(BakeryVolume), true) as BakeryVolume;
 | 
						|
                    if (prevAssignedVolume != assignedVolume)
 | 
						|
                    {
 | 
						|
                        volume0.textureValue = assignedVolume.bakedTexture0;
 | 
						|
                        volume1.textureValue = assignedVolume.bakedTexture1;
 | 
						|
                        volume2.textureValue = assignedVolume.bakedTexture2;
 | 
						|
                        volumeMask.textureValue = assignedVolume.bakedMask;
 | 
						|
                        var b = assignedVolume.bounds;
 | 
						|
                        volumeMin.vectorValue = b.min;
 | 
						|
                        volumeInvSize.vectorValue = new Vector3(1.0f/b.size.x, 1.0f/b.size.y, 1.0f/b.size.z);
 | 
						|
                        assignedVolume = null;
 | 
						|
                    }
 | 
						|
                    if (volume0.textureValue != null)
 | 
						|
                    {
 | 
						|
                        if (GUILayout.Button("Unset volume"))
 | 
						|
                        {
 | 
						|
                            volume0.textureValue = null;
 | 
						|
                            volume1.textureValue = null;
 | 
						|
                            volume2.textureValue = null;
 | 
						|
                            volumeMask.textureValue = null;
 | 
						|
                            volumeMin.vectorValue = Vector3.zero;
 | 
						|
                            volumeInvSize.vectorValue = Vector3.one * 1000001;
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                    EditorGUILayout.LabelField("Current Volume: " + (volume0.textureValue == null ? "<none or global>" : volume0.textureValue.name.Substring(0, volume0.textureValue.name.Length-1)));
 | 
						|
                    EditorGUI.BeginDisabledGroup(true);
 | 
						|
                    m_MaterialEditor.TexturePropertySingleLine(Styles.volLabel0, volume0);
 | 
						|
                    m_MaterialEditor.TexturePropertySingleLine(Styles.volLabel1, volume1);
 | 
						|
                    m_MaterialEditor.TexturePropertySingleLine(Styles.volLabel2, volume2);
 | 
						|
                    m_MaterialEditor.TexturePropertySingleLine(Styles.volLabelMask, volumeMask);
 | 
						|
                    var bmin4 = volumeMin.vectorValue;
 | 
						|
                    var bmin = new Vector3(bmin4.x, bmin4.y, bmin4.z);
 | 
						|
                    var invSize = volumeInvSize.vectorValue;
 | 
						|
                    var bmax = new Vector3(1.0f/invSize.x + bmin.x, 1.0f/invSize.y + bmin.y, 1.0f/invSize.z + bmin.z);
 | 
						|
                    EditorGUILayout.LabelField("Min: " + bmin);
 | 
						|
                    EditorGUILayout.LabelField("Max: " + bmax);
 | 
						|
                    EditorGUI.EndDisabledGroup();
 | 
						|
 | 
						|
                }
 | 
						|
 | 
						|
                EditorGUILayout.Space();
 | 
						|
            }
 | 
						|
            if (EditorGUI.EndChangeCheck())
 | 
						|
            {
 | 
						|
                foreach (var obj in blendMode.targets)
 | 
						|
                    MaterialChanged((Material)obj, m_WorkflowMode);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        internal void DetermineWorkflow(MaterialProperty[] props)
 | 
						|
        {
 | 
						|
            if (FindProperty("_SpecGlossMap", props, false) != null && FindProperty("_SpecColor", props, false) != null)
 | 
						|
                m_WorkflowMode = WorkflowMode.Specular;
 | 
						|
            else if (FindProperty("_MetallicGlossMap", props, false) != null && FindProperty("_Metallic", props, false) != null)
 | 
						|
                m_WorkflowMode = WorkflowMode.Metallic;
 | 
						|
            else
 | 
						|
                m_WorkflowMode = WorkflowMode.Dielectric;
 | 
						|
        }
 | 
						|
 | 
						|
        public override void AssignNewShaderToMaterial(Material material, Shader oldShader, Shader newShader)
 | 
						|
        {
 | 
						|
            // _Emission property is lost after assigning Standard shader to the material
 | 
						|
            // thus transfer it before assigning the new shader
 | 
						|
            if (material.HasProperty("_Emission"))
 | 
						|
            {
 | 
						|
                material.SetColor("_EmissionColor", material.GetColor("_Emission"));
 | 
						|
            }
 | 
						|
 | 
						|
            base.AssignNewShaderToMaterial(material, oldShader, newShader);
 | 
						|
 | 
						|
            if (oldShader == null || !oldShader.name.Contains("Legacy Shaders/"))
 | 
						|
            {
 | 
						|
                SetupMaterialWithBlendMode(material, (BlendMode)material.GetFloat("_Mode"));
 | 
						|
                return;
 | 
						|
            }
 | 
						|
 | 
						|
            BlendMode blendMode = BlendMode.Opaque;
 | 
						|
            if (oldShader.name.Contains("/Transparent/Cutout/"))
 | 
						|
            {
 | 
						|
                blendMode = BlendMode.Cutout;
 | 
						|
            }
 | 
						|
            else if (oldShader.name.Contains("/Transparent/"))
 | 
						|
            {
 | 
						|
                // NOTE: legacy shaders did not provide physically based transparency
 | 
						|
                // therefore Fade mode
 | 
						|
                blendMode = BlendMode.Fade;
 | 
						|
            }
 | 
						|
            material.SetFloat("_Mode", (float)blendMode);
 | 
						|
 | 
						|
            DetermineWorkflow(MaterialEditor.GetMaterialProperties(new Material[] { material }));
 | 
						|
            MaterialChanged(material, m_WorkflowMode);
 | 
						|
        }
 | 
						|
 | 
						|
        void BlendModePopup()
 | 
						|
        {
 | 
						|
            EditorGUI.showMixedValue = blendMode.hasMixedValue;
 | 
						|
            var mode = (BlendMode)blendMode.floatValue;
 | 
						|
 | 
						|
            EditorGUI.BeginChangeCheck();
 | 
						|
            mode = (BlendMode)EditorGUILayout.Popup(Styles.renderingMode, (int)mode, Styles.blendNames);
 | 
						|
            if (EditorGUI.EndChangeCheck())
 | 
						|
            {
 | 
						|
                m_MaterialEditor.RegisterPropertyChangeUndo("Rendering Mode");
 | 
						|
                blendMode.floatValue = (float)mode;
 | 
						|
            }
 | 
						|
 | 
						|
            EditorGUI.showMixedValue = false;
 | 
						|
        }
 | 
						|
 | 
						|
        void DoAlbedoArea(Material material)
 | 
						|
        {
 | 
						|
            m_MaterialEditor.TexturePropertySingleLine(Styles.albedoText, albedoMap, albedoColor);
 | 
						|
            if (((BlendMode)material.GetFloat("_Mode") == BlendMode.Cutout))
 | 
						|
            {
 | 
						|
                m_MaterialEditor.ShaderProperty(alphaCutoff, Styles.alphaCutoffText.text, MaterialEditor.kMiniTextureFieldLabelIndentLevel + 1);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        void DoEmissionArea(Material material)
 | 
						|
        {
 | 
						|
            bool showHelpBox = !HasValidEmissiveKeyword(material);
 | 
						|
 | 
						|
            bool hadEmissionTexture = emissionMap.textureValue != null;
 | 
						|
 | 
						|
            // Texture and HDR color controls
 | 
						|
            m_MaterialEditor.TexturePropertyWithHDRColor(Styles.emissionText, emissionMap, emissionColorForRendering, m_ColorPickerHDRConfig, false);
 | 
						|
 | 
						|
            // If texture was assigned and color was black set color to white
 | 
						|
            float brightness = emissionColorForRendering.colorValue.maxColorComponent;
 | 
						|
            if (emissionMap.textureValue != null && !hadEmissionTexture && brightness <= 0f)
 | 
						|
                emissionColorForRendering.colorValue = Color.white;
 | 
						|
 | 
						|
            // Emission for GI?
 | 
						|
            m_MaterialEditor.LightmapEmissionProperty(MaterialEditor.kMiniTextureFieldLabelIndentLevel + 1);
 | 
						|
 | 
						|
            if (showHelpBox)
 | 
						|
            {
 | 
						|
                EditorGUILayout.HelpBox(Styles.emissiveWarning.text, MessageType.Warning);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        void DoSpecularMetallicArea()
 | 
						|
        {
 | 
						|
            bool hasGlossMap = false;
 | 
						|
            if (m_WorkflowMode == WorkflowMode.Specular)
 | 
						|
            {
 | 
						|
                hasGlossMap = specularMap.textureValue != null;
 | 
						|
                m_MaterialEditor.TexturePropertySingleLine(Styles.specularMapText, specularMap, hasGlossMap ? null : specularColor);
 | 
						|
            }
 | 
						|
            else if (m_WorkflowMode == WorkflowMode.Metallic)
 | 
						|
            {
 | 
						|
                hasGlossMap = metallicMap.textureValue != null;
 | 
						|
                m_MaterialEditor.TexturePropertySingleLine(Styles.metallicMapText, metallicMap, hasGlossMap ? null : metallic);
 | 
						|
            }
 | 
						|
 | 
						|
            bool showSmoothnessScale = hasGlossMap;
 | 
						|
            if (smoothnessMapChannel != null)
 | 
						|
            {
 | 
						|
                int smoothnessChannel = (int)smoothnessMapChannel.floatValue;
 | 
						|
                if (smoothnessChannel == (int)SmoothnessMapChannel.AlbedoAlpha)
 | 
						|
                    showSmoothnessScale = true;
 | 
						|
            }
 | 
						|
 | 
						|
            int indentation = 2; // align with labels of texture properties
 | 
						|
            m_MaterialEditor.ShaderProperty(showSmoothnessScale ? smoothnessScale : smoothness, showSmoothnessScale ? Styles.smoothnessScaleText : Styles.smoothnessText, indentation);
 | 
						|
 | 
						|
            ++indentation;
 | 
						|
            if (smoothnessMapChannel != null)
 | 
						|
                m_MaterialEditor.ShaderProperty(smoothnessMapChannel, Styles.smoothnessMapChannelText, indentation);
 | 
						|
        }
 | 
						|
 | 
						|
        public static void SetupMaterialWithBlendMode(Material material, BlendMode blendMode)
 | 
						|
        {
 | 
						|
            switch (blendMode)
 | 
						|
            {
 | 
						|
                case BlendMode.Opaque:
 | 
						|
                    material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
 | 
						|
                    material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
 | 
						|
                    material.SetInt("_ZWrite", 1);
 | 
						|
                    material.DisableKeyword("_ALPHATEST_ON");
 | 
						|
                    material.DisableKeyword("_ALPHABLEND_ON");
 | 
						|
                    material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
 | 
						|
                    material.renderQueue = -1;
 | 
						|
                    break;
 | 
						|
                case BlendMode.Cutout:
 | 
						|
                    material.SetOverrideTag("RenderType", "TransparentCutout");
 | 
						|
                    material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
 | 
						|
                    material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
 | 
						|
                    material.SetInt("_ZWrite", 1);
 | 
						|
                    material.EnableKeyword("_ALPHATEST_ON");
 | 
						|
                    material.DisableKeyword("_ALPHABLEND_ON");
 | 
						|
                    material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
 | 
						|
                    material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.AlphaTest;
 | 
						|
                    break;
 | 
						|
                case BlendMode.Fade:
 | 
						|
                    material.SetOverrideTag("RenderType", "Transparent");
 | 
						|
                    material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
 | 
						|
                    material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
 | 
						|
                    material.SetInt("_ZWrite", 0);
 | 
						|
                    material.DisableKeyword("_ALPHATEST_ON");
 | 
						|
                    material.EnableKeyword("_ALPHABLEND_ON");
 | 
						|
                    material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
 | 
						|
                    material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent;
 | 
						|
                    break;
 | 
						|
                case BlendMode.Transparent:
 | 
						|
                    material.SetOverrideTag("RenderType", "Transparent");
 | 
						|
                    material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
 | 
						|
                    material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
 | 
						|
                    material.SetInt("_ZWrite", 0);
 | 
						|
                    material.DisableKeyword("_ALPHATEST_ON");
 | 
						|
                    material.DisableKeyword("_ALPHABLEND_ON");
 | 
						|
                    material.EnableKeyword("_ALPHAPREMULTIPLY_ON");
 | 
						|
                    material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent;
 | 
						|
                    break;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        static SmoothnessMapChannel GetSmoothnessMapChannel(Material material)
 | 
						|
        {
 | 
						|
            int ch = (int)material.GetFloat("_SmoothnessTextureChannel");
 | 
						|
            if (ch == (int)SmoothnessMapChannel.AlbedoAlpha)
 | 
						|
                return SmoothnessMapChannel.AlbedoAlpha;
 | 
						|
            else
 | 
						|
                return SmoothnessMapChannel.SpecularMetallicAlpha;
 | 
						|
        }
 | 
						|
 | 
						|
        static bool ShouldEmissionBeEnabled(Material mat, Color color)
 | 
						|
        {
 | 
						|
            var realtimeEmission = (mat.globalIlluminationFlags & MaterialGlobalIlluminationFlags.RealtimeEmissive) > 0;
 | 
						|
            return color.maxColorComponent > 0.1f / 255.0f || realtimeEmission;
 | 
						|
        }
 | 
						|
 | 
						|
        static void SetMaterialKeywords(Material material, WorkflowMode workflowMode)
 | 
						|
        {
 | 
						|
            // Note: keywords must be based on Material value not on MaterialProperty due to multi-edit & material animation
 | 
						|
            // (MaterialProperty value might come from renderer material property block)
 | 
						|
            SetKeyword(material, "_NORMALMAP", material.GetTexture("_BumpMap") || material.GetTexture("_DetailNormalMap"));
 | 
						|
            if (workflowMode == WorkflowMode.Specular)
 | 
						|
                SetKeyword(material, "_SPECGLOSSMAP", material.GetTexture("_SpecGlossMap"));
 | 
						|
            else if (workflowMode == WorkflowMode.Metallic)
 | 
						|
                SetKeyword(material, "_METALLICGLOSSMAP", material.GetTexture("_MetallicGlossMap"));
 | 
						|
            SetKeyword(material, "_PARALLAXMAP", material.GetTexture("_ParallaxMap"));
 | 
						|
            SetKeyword(material, "_DETAIL_MULX2", material.GetTexture("_DetailAlbedoMap") || material.GetTexture("_DetailNormalMap"));
 | 
						|
 | 
						|
            bool shouldEmissionBeEnabled = ShouldEmissionBeEnabled(material, material.GetColor("_EmissionColor"));
 | 
						|
            SetKeyword(material, "_EMISSION", shouldEmissionBeEnabled);
 | 
						|
 | 
						|
            if (material.HasProperty("_SmoothnessTextureChannel"))
 | 
						|
            {
 | 
						|
                SetKeyword(material, "_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A", GetSmoothnessMapChannel(material) == SmoothnessMapChannel.AlbedoAlpha);
 | 
						|
            }
 | 
						|
 | 
						|
            // Setup lightmap emissive flags
 | 
						|
            MaterialGlobalIlluminationFlags flags = material.globalIlluminationFlags;
 | 
						|
            if ((flags & (MaterialGlobalIlluminationFlags.BakedEmissive | MaterialGlobalIlluminationFlags.RealtimeEmissive)) != 0)
 | 
						|
            {
 | 
						|
                flags &= ~MaterialGlobalIlluminationFlags.EmissiveIsBlack;
 | 
						|
                if (!shouldEmissionBeEnabled)
 | 
						|
                    flags |= MaterialGlobalIlluminationFlags.EmissiveIsBlack;
 | 
						|
 | 
						|
                material.globalIlluminationFlags = flags;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        bool HasValidEmissiveKeyword(Material material)
 | 
						|
        {
 | 
						|
            // Material animation might be out of sync with the material keyword.
 | 
						|
            // So if the emission support is disabled on the material, but the property blocks have a value that requires it, then we need to show a warning.
 | 
						|
            // (note: (Renderer MaterialPropertyBlock applies its values to emissionColorForRendering))
 | 
						|
            bool hasEmissionKeyword = material.IsKeywordEnabled("_EMISSION");
 | 
						|
            if (!hasEmissionKeyword && ShouldEmissionBeEnabled(material, emissionColorForRendering.colorValue))
 | 
						|
                return false;
 | 
						|
            else
 | 
						|
                return true;
 | 
						|
        }
 | 
						|
 | 
						|
        static void MaterialChanged(Material material, WorkflowMode workflowMode)
 | 
						|
        {
 | 
						|
            SetupMaterialWithBlendMode(material, (BlendMode)material.GetFloat("_Mode"));
 | 
						|
 | 
						|
            SetMaterialKeywords(material, workflowMode);
 | 
						|
        }
 | 
						|
 | 
						|
        static void SetKeyword(Material m, string keyword, bool state)
 | 
						|
        {
 | 
						|
            if (state)
 | 
						|
                m.EnableKeyword(keyword);
 | 
						|
            else
 | 
						|
                m.DisableKeyword(keyword);
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
#endif
 |