using System; using UnityEditor.Rendering.Universal; using UnityEditor.Rendering.Universal.ShaderGUI; using UnityEngine; using static Unity.Rendering.Universal.ShaderUtils; using System.Collections.Generic; using System.Linq; using UnityEditor.Rendering; using UnityEditor.ShaderGraph; using UnityEditor.ShaderGraph.Drawing; using UnityEngine.Rendering; using UnityEngine.Rendering.Universal; using BlendMode = UnityEngine.Rendering.BlendMode; using RenderQueue = UnityEngine.Rendering.RenderQueue; using System.Reflection; namespace UnityEditor { // Used for ShaderGraph Lit shaders class LitMASIMGUI : BaseShaderGUI { public MaterialProperty workflowMode; public MaterialProperty blendSrc; public MaterialProperty blendDst; public MaterialProperty temporalAcm; MaterialProperty[] properties; // collect properties from the material properties public override void FindProperties(MaterialProperty[] properties) { // save off the list of all properties for shadergraph this.properties = properties; var material = materialEditor?.target as Material; if (material == null) return; base.FindProperties(properties); workflowMode = BaseShaderGUI.FindProperty(Property.SpecularWorkflowMode, properties, false); blendSrc = BaseShaderGUI.FindProperty("_BlendSrc", properties, false); blendDst = BaseShaderGUI.FindProperty("_BlendDst", properties, false); zwriteProp = BaseShaderGUI.FindProperty("_ZWrite", properties, false); temporalAcm = BaseShaderGUI.FindProperty("_SSRTemporalMul", properties, false); } static string[] surfaceNames = new string[] { "Opaque", "Transparent", "Fade", }; bool hasInitialized = false; bool hasSSR = false; public override void AssignNewShaderToMaterial(Material material, Shader oldShader, Shader newShader) { base.AssignNewShaderToMaterial(material, oldShader, newShader); float surface = material.GetFloat("_Surface"); Debug.Log(oldShader.name); if (oldShader.name.StartsWith("Universal Render Pipeline")) { bool hasBlendmode = oldShader.FindPropertyIndex("_Blend") >= 0; if (hasBlendmode) { float blend = material.GetFloat("_Blend"); if (surface > 0.0f && blend == (float)BaseShaderGUI.BlendMode.Alpha) { surface = 2.0f; material.SetFloat("_Surface", surface); } } bool hasEmission = material.IsKeywordEnabled("_EMISSION"); if (hasEmission) { material.SetFloat("_Emission", 1); } } bool hasTemporalAcm = newShader.FindPropertyIndex("_SSRTemporalMul") >= 0; switch (surface) { case 0: material.SetFloat("_BlendSrc", (float)UnityEngine.Rendering.BlendMode.One); material.SetFloat("_BlendDst", (float)UnityEngine.Rendering.BlendMode.Zero); material.SetFloat("_ZWrite", 1); material.renderQueue = -1; if (hasTemporalAcm) material.SetFloat("_SSRTemporalMul", 1.0f); break; case 1: material.SetFloat("_BlendSrc", (float)UnityEngine.Rendering.BlendMode.One); material.SetFloat("_BlendDst", (float)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); material.SetFloat("_ZWrite", 0); if (hasTemporalAcm) material.SetFloat("_SSRTemporalMul", 0.0f); material.renderQueue = 3000; break; case 2: material.SetFloat("_BlendSrc", (float)UnityEngine.Rendering.BlendMode.SrcAlpha); material.SetFloat("_BlendDst", (float)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); material.SetFloat("_ZWrite", 0); if (hasTemporalAcm) material.SetFloat("_SSRTemporalMul", 0.0f); material.renderQueue = 3000; break; } } public override void DrawSurfaceOptions(Material material) { int val = (int)surfaceTypeProp.floatValue; EditorGUI.BeginChangeCheck(); EditorGUI.showMixedValue = surfaceTypeProp.hasMixedValue; int newValue = EditorGUILayout.Popup(Styles.surfaceType, val, surfaceNames); EditorGUI.showMixedValue = false; if (EditorGUI.EndChangeCheck() && (newValue != val || surfaceTypeProp.hasMixedValue)) { materialEditor.RegisterPropertyChangeUndo(Styles.surfaceType.text); surfaceTypeProp.floatValue = val = newValue; switch (newValue) { case 0: blendSrc.floatValue = (float)UnityEngine.Rendering.BlendMode.One; blendDst.floatValue = (float)UnityEngine.Rendering.BlendMode.Zero; zwriteProp.floatValue = 1; SetQueue(-1); if (temporalAcm != null) temporalAcm.floatValue = 1; break; case 1: blendSrc.floatValue = (float)UnityEngine.Rendering.BlendMode.One; blendDst.floatValue = (float)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha; zwriteProp.floatValue = 0; if (temporalAcm != null) temporalAcm.floatValue = 0; SetQueue(3000); break; case 2: blendSrc.floatValue = (float)UnityEngine.Rendering.BlendMode.SrcAlpha; blendDst.floatValue = (float)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha; zwriteProp.floatValue = 0; if (temporalAcm != null) temporalAcm.floatValue = 0; SetQueue(3000); break; } } if (val != 0) { EditorGUILayout.HelpBox("Non-opaque surfaces are EXPENSIVE on Quest and other mobile devices. Avoid when possible!", MessageType.Warning); } DoPopup(Styles.cullingText, cullingProp, Styles.renderFaceNames); //DoPopup(Styles.zwriteText, zwriteProp, Styles.zwriteNames); materialEditor.RenderQueueField(); if (ztestProp != null) materialEditor.IntPopupShaderProperty(ztestProp, Styles.ztestText.text, Styles.ztestNames, Styles.ztestValues); DrawFloatToggleProperty(Styles.alphaClipText, alphaClipProp); if ((alphaClipProp != null) && (alphaCutoffProp != null) && (alphaClipProp.floatValue == 1)) materialEditor.ShaderProperty(alphaCutoffProp, Styles.alphaClipThresholdText, 1); DrawFloatToggleProperty(Styles.castShadowText, castShadowsProp); DrawFloatToggleProperty(Styles.receiveShadowText, receiveShadowsProp); hasInitialized = true; } void SetQueue(int value) { UnityEngine.Object[] array3 = materialEditor.targets; foreach (UnityEngine.Object @object in array3) { ((Material)@object).renderQueue = value; } } void ValidateQueue(Material mat) { } public static void UpdateMaterial(Material material, MaterialUpdateType updateType) { // newly created materials should initialize the globalIlluminationFlags (default is off) if (updateType == MaterialUpdateType.CreatedNewMaterial) material.globalIlluminationFlags = MaterialGlobalIlluminationFlags.BakedEmissive; bool automaticRenderQueue = GetAutomaticQueueControlSetting(material); //BaseShaderGUI.UpdateMaterialSurfaceOptions(material, automaticRenderQueue); LitGUI.SetupSpecularWorkflowKeyword(material, out bool isSpecularWorkflow); } public override void ValidateMaterial(Material material) { if (material == null) throw new ArgumentNullException("material"); UpdateMaterial(material, MaterialUpdateType.ModifiedMaterial); } // material main surface inputs public override void DrawSurfaceInputs(Material material) { DrawShaderGraphProperties(material, properties); } public override void DrawAdvancedOptions(Material material) { // Always show the queue control field. Only show the render queue field if queue control is set to user override DoPopup(Styles.queueControl, queueControlProp, Styles.queueControlNames); //if (material.HasProperty(Property.QueueControl) && material.GetFloat(Property.QueueControl) == (float)QueueControl.UserOverride) base.DrawAdvancedOptions(material); // ignore emission color for shadergraphs, because shadergraphs don't have a hard-coded emission property, it's up to the user materialEditor.DoubleSidedGIField(); materialEditor.LightmapEmissionFlagsProperty(0, enabled: true, ignoreEmissionColor: true); } } } // namespace UnityEditor