summaryrefslogtreecommitdiff
path: root/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Utils/CustomShaderInspector.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Utils/CustomShaderInspector.cs')
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Utils/CustomShaderInspector.cs963
1 files changed, 963 insertions, 0 deletions
diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Utils/CustomShaderInspector.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Utils/CustomShaderInspector.cs
new file mode 100644
index 00000000..439f777e
--- /dev/null
+++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Utils/CustomShaderInspector.cs
@@ -0,0 +1,963 @@
+// Amplify Shader Editor - Visual Shader Editing Tool
+// Copyright (c) Amplify Creations, Lda <info@amplify.pt>
+
+using System;
+using System.Reflection;
+using System.Globalization;
+using UnityEngine;
+using AmplifyShaderEditor;
+
+namespace UnityEditor
+{
+ [CustomEditor( typeof( Shader ) )]
+ internal class CustomShaderInspector : Editor
+ {
+ internal class Styles
+ {
+ public static Texture2D errorIcon = EditorGUIUtilityEx.LoadIcon( "console.erroricon.sml" );
+
+ public static Texture2D warningIcon = EditorGUIUtilityEx.LoadIcon( "console.warnicon.sml" );
+
+ public static GUIContent showSurface = EditorGUIUtilityEx.TextContent( "Show generated code|Show generated code of a surface shader" );
+
+ public static GUIContent showFF = EditorGUIUtilityEx.TextContent( "Show generated code|Show generated code of a fixed function shader" );
+
+ public static GUIContent showCurrent = new GUIContent( "Compile and show code | ▾" );
+
+ public static GUIStyle messageStyle = "CN StatusInfo";
+
+ public static GUIStyle evenBackground = "CN EntryBackEven";
+
+ public static GUIContent no = EditorGUIUtilityEx.TextContent( "no" );
+
+ public static GUIContent builtinShader = EditorGUIUtilityEx.TextContent( "Built-in shader" );
+
+ public static GUIContent arrayValuePopupButton = EditorGUIUtilityEx.TextContent( "..." );
+ }
+
+ private const float kSpace = 5f;
+
+ const float kValueFieldWidth = 200.0f;
+ const float kArrayValuePopupBtnWidth = 25.0f;
+
+ private static readonly string[] kPropertyTypes = new string[]
+ {
+ "Color: ",
+ "Vector: ",
+ "Float: ",
+ "Range: ",
+ "Texture: "
+ };
+
+ private static readonly string[] kTextureTypes = new string[]
+ {
+ "No Texture?: ",
+ "1D?: ",
+ "2D: ",
+ "3D: ",
+ "Cube: ",
+ "2DArray: ",
+ "Any texture: "
+ };
+
+ private static readonly int kErrorViewHash = "ShaderErrorView".GetHashCode();
+
+ private Vector2 m_ScrollPosition = Vector2.zero;
+
+ private PreviewRenderUtility m_previewRenderUtility;
+ private Material m_material;
+ private Mesh m_previewMesh;
+ private Vector2 m_mouseDelta;
+ private Transform m_cameraTransform;
+
+ private static int m_sliderHashCode = -1;
+ private const float MaxDeltaY = 90;
+ private const int DefaultMouseSpeed = 1;
+ private const int ShiftMouseSpeed = 3;
+ private const float DeltaMultiplier = 135f;
+ private void ValidateData()
+ {
+ if ( m_previewRenderUtility == null )
+ {
+ m_previewRenderUtility = new PreviewRenderUtility();
+#if UNITY_2017_1_OR_NEWER
+ m_cameraTransform = m_previewRenderUtility.camera.transform;
+#else
+ m_cameraTransform = m_previewRenderUtility.m_Camera.transform;
+#endif
+ m_cameraTransform.position = new Vector3( 0, 0, -4 );
+ m_cameraTransform.rotation = Quaternion.identity;
+ }
+
+ if ( m_material == null )
+ {
+ m_material = new Material( target as Shader );
+ m_material.hideFlags = HideFlags.DontSave;
+ }
+
+ if ( m_previewMesh == null )
+ {
+ m_previewMesh = Resources.GetBuiltinResource<Mesh>( "Sphere.fbx" );
+ }
+
+ if ( m_sliderHashCode < 0 )
+ {
+ "Slider".GetHashCode();
+ }
+ }
+
+ public override bool HasPreviewGUI()
+ {
+ ValidateData();
+ return true;
+ }
+
+ public static Vector2 CheckMouseMovement( Vector2 scrollPosition, Rect position )
+ {
+ int controlID = GUIUtility.GetControlID( m_sliderHashCode, FocusType.Passive );
+ Event current = Event.current;
+ switch ( current.GetTypeForControl( controlID ) )
+ {
+ case EventType.MouseDown:
+ {
+ if ( position.Contains( current.mousePosition ) && position.width > 50f )
+ {
+ GUIUtility.hotControl = controlID;
+ current.Use();
+ EditorGUIUtility.SetWantsMouseJumping( 1 );
+ }
+ }
+ break;
+ case EventType.MouseUp:
+ {
+ if ( GUIUtility.hotControl == controlID )
+ {
+ GUIUtility.hotControl = 0;
+ }
+ EditorGUIUtility.SetWantsMouseJumping( 0 );
+ }
+ break;
+ case EventType.MouseDrag:
+ {
+ if ( GUIUtility.hotControl == controlID )
+ {
+ scrollPosition -= DeltaMultiplier * current.delta * ( float ) ( ( current.shift ) ? ShiftMouseSpeed : DefaultMouseSpeed ) / Mathf.Min( position.width, position.height );
+ scrollPosition.y = Mathf.Clamp( scrollPosition.y, -MaxDeltaY, MaxDeltaY );
+ current.Use();
+ }
+ }
+ break;
+ }
+ return scrollPosition;
+ }
+
+ public override void OnPreviewGUI( Rect r, GUIStyle background )
+ {
+ m_mouseDelta = CheckMouseMovement( m_mouseDelta, r );
+
+ if ( Event.current.type == EventType.Repaint )
+ {
+ m_previewRenderUtility.BeginPreview( r, background );
+
+ Texture resultRender = m_previewRenderUtility.EndPreview();
+ m_previewRenderUtility.DrawMesh( m_previewMesh, Matrix4x4.identity, m_material, 0 );
+ m_cameraTransform.rotation = Quaternion.Euler( new Vector3( -m_mouseDelta.y, -m_mouseDelta.x, 0 ) );
+ m_cameraTransform.position = m_cameraTransform.forward * -8f;
+#if UNITY_2017_1_OR_NEWER
+ m_previewRenderUtility.camera.Render();
+#else
+ m_previewRenderUtility.m_Camera.Render();
+#endif
+ GUI.DrawTexture( r, resultRender, ScaleMode.StretchToFill, false );
+ }
+ }
+
+ void OnDestroy()
+ {
+ CleanUp();
+ }
+
+ public void OnDisable()
+ {
+ CleanUp();
+ if( m_SrpCompatibilityCheckMaterial != null )
+ {
+ GameObject.DestroyImmediate( m_SrpCompatibilityCheckMaterial );
+ }
+ }
+
+ void CleanUp()
+ {
+ if( m_previewRenderUtility != null )
+ {
+ m_previewRenderUtility.Cleanup();
+ m_previewRenderUtility = null;
+ }
+
+ if( m_previewMesh != null )
+ {
+ Resources.UnloadAsset( m_previewMesh );
+ m_previewMesh = null;
+ }
+
+ if( m_previewRenderUtility != null )
+ {
+ m_previewRenderUtility.Cleanup();
+ m_previewRenderUtility = null;
+ }
+ m_material = null;
+ }
+
+ private Material m_SrpCompatibilityCheckMaterial = null;
+ public Material srpCompatibilityCheckMaterial
+ {
+ get
+ {
+ if( m_SrpCompatibilityCheckMaterial == null )
+ {
+ m_SrpCompatibilityCheckMaterial = new Material( target as Shader );
+ }
+ return m_SrpCompatibilityCheckMaterial;
+ }
+ }
+
+ public virtual void OnEnable()
+ {
+ Shader s = this.target as Shader;
+ if( s!= null )
+ ShaderUtilEx.FetchCachedErrors( s );
+ }
+
+ private static string GetPropertyType( Shader s, int index )
+ {
+ UnityEditor.ShaderUtil.ShaderPropertyType propertyType = UnityEditor.ShaderUtil.GetPropertyType( s, index );
+ if ( propertyType == UnityEditor.ShaderUtil.ShaderPropertyType.TexEnv )
+ {
+ return CustomShaderInspector.kTextureTypes[ ( int ) UnityEditor.ShaderUtil.GetTexDim( s, index ) ];
+ }
+ return CustomShaderInspector.kPropertyTypes[ ( int ) propertyType ];
+ }
+
+ public override void OnInspectorGUI()
+ {
+ Shader shader = this.target as Shader;
+ if ( shader == null )
+ {
+ return;
+ }
+
+ GUI.enabled = true;
+
+ GUILayout.Space( 3 );
+ GUILayout.BeginHorizontal();
+ {
+ if ( GUILayout.Button( "Open in Shader Editor" ) )
+ {
+#if UNITY_2018_3_OR_NEWER
+ ASEPackageManagerHelper.SetupLateShader( shader );
+#else
+ AmplifyShaderEditorWindow.ConvertShaderToASE( shader );
+#endif
+ }
+
+ if ( GUILayout.Button( "Open in Text Editor" ) )
+ {
+ if( UIUtils.IsUnityNativeShader( shader ) )
+ {
+ Debug.LogWarningFormat( "Action not allowed. Attempting to load the native {0} shader into Text Editor", shader.name );
+ }
+ else
+ {
+ AssetDatabase.OpenAsset( shader, 1 );
+ }
+ }
+ }
+ GUILayout.EndHorizontal();
+
+ GUILayout.Space( 5 );
+ EditorGUI.indentLevel = 0;
+ this.ShowShaderCodeArea( shader );
+ if ( shader.isSupported )
+ {
+ EditorGUILayout.LabelField( "Cast shadows", ( !ShaderUtilEx.HasShadowCasterPass( shader ) ) ? "no" : "yes", new GUILayoutOption[ 0 ] );
+ EditorGUILayout.LabelField( "Render queue", ShaderUtilEx.GetRenderQueue( shader ).ToString( System.Globalization.CultureInfo.InvariantCulture ), new GUILayoutOption[ 0 ] );
+ EditorGUILayout.LabelField( "LOD", ShaderUtilEx.GetLOD( shader ).ToString( System.Globalization.CultureInfo.InvariantCulture ), new GUILayoutOption[ 0 ] );
+ EditorGUILayout.LabelField( "Ignore projector", ( !ShaderUtilEx.DoesIgnoreProjector( shader ) ) ? "no" : "yes", new GUILayoutOption[ 0 ] );
+ string label;
+ switch ( ShaderEx.GetDisableBatching( shader ) )
+ {
+ case DisableBatchingType.False:
+ label = "no";
+ break;
+ case DisableBatchingType.True:
+ label = "yes";
+ break;
+ case DisableBatchingType.WhenLODFading:
+ label = "when LOD fading is on";
+ break;
+ default:
+ label = "unknown";
+ break;
+ }
+ EditorGUILayout.LabelField( "Disable batching", label, new GUILayoutOption[ 0 ] );
+#if UNITY_2019_3_OR_NEWER
+ ShowKeywords( shader );
+ srpCompatibilityCheckMaterial.SetPass( 0 );
+#endif
+
+#if UNITY_2018_3_OR_NEWER
+ int shaderActiveSubshaderIndex = ShaderUtilEx.GetShaderActiveSubshaderIndex( shader );
+ int sRPBatcherCompatibilityCode = ShaderUtilEx.GetSRPBatcherCompatibilityCode( shader, shaderActiveSubshaderIndex );
+ string label2 = ( sRPBatcherCompatibilityCode != 0 ) ? "not compatible" : "compatible";
+ EditorGUILayout.LabelField( "SRP Batcher", label2 );
+ if( sRPBatcherCompatibilityCode != 0 )
+ {
+ EditorGUILayout.HelpBox( ShaderUtilEx.GetSRPBatcherCompatibilityIssueReason( shader, shaderActiveSubshaderIndex, sRPBatcherCompatibilityCode ), MessageType.Info );
+ }
+#endif
+ CustomShaderInspector.ShowShaderProperties( shader );
+ }
+ }
+#if UNITY_2019_3_OR_NEWER
+ private void ShowKeywords( Shader s )
+ {
+ EditorGUILayout.BeginHorizontal();
+ EditorGUILayout.PrefixLabel( "Keywords", EditorStyles.miniButton );
+
+ Rect buttonRect = GUILayoutUtility.GetRect( Styles.arrayValuePopupButton, GUI.skin.button, GUILayout.MinWidth( kValueFieldWidth ) );
+ buttonRect.width = kArrayValuePopupBtnWidth;
+ if( GUI.Button( buttonRect, Styles.arrayValuePopupButton, EditorStyles.miniButton ) )
+ {
+ var globalKeywords = ShaderUtilEx.GetShaderGlobalKeywords( s );
+ var localKeywords = ShaderUtilEx.GetShaderLocalKeywords( s );
+ PopupWindow.Show( buttonRect, new KeywordsPopup( globalKeywords, localKeywords, 150.0f ) );
+ }
+
+ EditorGUILayout.EndHorizontal();
+ }
+#endif
+ private void ShowShaderCodeArea( Shader s )
+ {
+ CustomShaderInspector.ShowSurfaceShaderButton( s );
+ CustomShaderInspector.ShowFixedFunctionShaderButton( s );
+ this.ShowCompiledCodeButton( s );
+ this.ShowShaderErrors( s );
+ }
+
+ private static void ShowShaderProperties( Shader s )
+ {
+ GUILayout.Space( 5f );
+ GUILayout.Label( "Properties:", EditorStyles.boldLabel, new GUILayoutOption[ 0 ] );
+ int propertyCount = UnityEditor.ShaderUtil.GetPropertyCount( s );
+ for ( int i = 0; i < propertyCount; i++ )
+ {
+ string propertyName = UnityEditor.ShaderUtil.GetPropertyName( s, i );
+ string label = CustomShaderInspector.GetPropertyType( s, i ) + UnityEditor.ShaderUtil.GetPropertyDescription( s, i );
+ EditorGUILayout.LabelField( propertyName, label, new GUILayoutOption[ 0 ] );
+ }
+ }
+
+ internal static void ShaderErrorListUI( UnityEngine.Object shader, ShaderError[] errors, ref Vector2 scrollPosition )
+ {
+ int num = errors.Length;
+ GUILayout.Space( 5f );
+ GUILayout.Label( string.Format( "Errors ({0}):", num ), EditorStyles.boldLabel, new GUILayoutOption[ 0 ] );
+ int controlID = GUIUtility.GetControlID( CustomShaderInspector.kErrorViewHash, FocusType.Passive );
+ float minHeight = Mathf.Min( ( float ) num * 20f + 40f, 150f );
+ scrollPosition = GUILayout.BeginScrollView( scrollPosition, GUISkinEx.GetCurrentSkin().box, new GUILayoutOption[]
+ {
+ GUILayout.MinHeight(minHeight)
+ } );
+ EditorGUIUtility.SetIconSize( new Vector2( 16f, 16f ) );
+ float height = CustomShaderInspector.Styles.messageStyle.CalcHeight( EditorGUIUtilityEx.TempContent( CustomShaderInspector.Styles.errorIcon ), 100f );
+ Event current = Event.current;
+ for ( int i = 0; i < num; i++ )
+ {
+ Rect controlRect = EditorGUILayout.GetControlRect( false, height, new GUILayoutOption[ 0 ] );
+ string message = errors[ i ].message;
+ string platform = errors[ i ].platform;
+ bool flag = errors[ i ].warning != 0;
+ string lastPathNameComponent = FileUtilEx.GetLastPathNameComponent( errors[ i ].file );
+ int line = errors[ i ].line;
+ if ( current.type == EventType.MouseDown && current.button == 0 && controlRect.Contains( current.mousePosition ) )
+ {
+ GUIUtility.keyboardControl = controlID;
+ if ( current.clickCount == 2 )
+ {
+ string file = errors[ i ].file;
+ UnityEngine.Object @object = ( !string.IsNullOrEmpty( file ) ) ? AssetDatabase.LoadMainAssetAtPath( file ) : null;
+ AssetDatabase.OpenAsset( @object ?? shader, line );
+ GUIUtility.ExitGUI();
+ }
+ current.Use();
+ }
+ if ( current.type == EventType.ContextClick && controlRect.Contains( current.mousePosition ) )
+ {
+ current.Use();
+ GenericMenu genericMenu = new GenericMenu();
+ int errorIndex = i;
+ genericMenu.AddItem( new GUIContent( "Copy error text" ), false, delegate
+ {
+ string text = errors[ errorIndex ].message;
+ if ( !string.IsNullOrEmpty( errors[ errorIndex ].messageDetails ) )
+ {
+ text += '\n';
+ text += errors[ errorIndex ].messageDetails;
+ }
+ EditorGUIUtility.systemCopyBuffer = text;
+ } );
+ genericMenu.ShowAsContext();
+ }
+ if ( current.type == EventType.Repaint && ( i & 1 ) == 0 )
+ {
+ GUIStyle evenBackground = CustomShaderInspector.Styles.evenBackground;
+ evenBackground.Draw( controlRect, false, false, false, false );
+ }
+ Rect rect = controlRect;
+ rect.xMin = rect.xMax;
+ if ( line > 0 )
+ {
+ GUIContent content;
+ if ( string.IsNullOrEmpty( lastPathNameComponent ) )
+ {
+ content = EditorGUIUtilityEx.TempContent( line.ToString( System.Globalization.CultureInfo.InvariantCulture ) );
+ }
+ else
+ {
+ content = EditorGUIUtilityEx.TempContent( lastPathNameComponent + ":" + line.ToString( System.Globalization.CultureInfo.InvariantCulture ) );
+ }
+ Vector2 vector = EditorStyles.miniLabel.CalcSize( content );
+ rect.xMin -= vector.x;
+ GUI.Label( rect, content, EditorStyles.miniLabel );
+ rect.xMin -= 2f;
+ if ( rect.width < 30f )
+ {
+ rect.xMin = rect.xMax - 30f;
+ }
+ }
+ Rect position = rect;
+ position.width = 0f;
+ if ( platform.Length > 0 )
+ {
+ GUIContent content2 = EditorGUIUtilityEx.TempContent( platform );
+ Vector2 vector2 = EditorStyles.miniLabel.CalcSize( content2 );
+ position.xMin -= vector2.x;
+ Color contentColor = GUI.contentColor;
+ GUI.contentColor = new Color( 1f, 1f, 1f, 0.5f );
+ GUI.Label( position, content2, EditorStyles.miniLabel );
+ GUI.contentColor = contentColor;
+ position.xMin -= 2f;
+ }
+ Rect position2 = controlRect;
+ position2.xMax = position.xMin;
+ GUI.Label( position2, EditorGUIUtilityEx.TempContent( message, ( !flag ) ? CustomShaderInspector.Styles.errorIcon : CustomShaderInspector.Styles.warningIcon ), CustomShaderInspector.Styles.messageStyle );
+ }
+ EditorGUIUtility.SetIconSize( Vector2.zero );
+ GUILayout.EndScrollView();
+ }
+
+#if UNITY_2019_3_OR_NEWER
+ ShaderMessage[] m_ShaderMessages;
+#endif
+ private void ShowShaderErrors( Shader s )
+ {
+#if UNITY_2019_3_OR_NEWER
+ if( Event.current.type == EventType.Layout )
+ {
+ int n = ShaderUtil.GetShaderMessageCount( s );
+ m_ShaderMessages = null;
+ if( n >= 1 )
+ {
+ m_ShaderMessages = ShaderUtil.GetShaderMessages( s );
+ }
+ }
+
+ if( m_ShaderMessages == null )
+ return;
+
+ ShaderInspectorEx.ShaderErrorListUI( s, m_ShaderMessages, ref this.m_ScrollPosition );
+#else
+ int shaderErrorCount = ShaderUtilEx.GetShaderErrorCount( s );
+ if ( shaderErrorCount < 1 )
+ {
+ return;
+ }
+ CustomShaderInspector.ShaderErrorListUI( s, ShaderUtilEx.GetShaderErrors( s ), ref this.m_ScrollPosition );
+#endif
+ }
+
+ private void ShowCompiledCodeButton( Shader s )
+ {
+ EditorGUILayout.BeginHorizontal( new GUILayoutOption[ 0 ] );
+ EditorGUILayout.PrefixLabel( "Compiled code", EditorStyles.miniButton );
+ bool flag = ShaderUtilEx.HasShaderSnippets( s ) || ShaderUtilEx.HasSurfaceShaders( s ) || ShaderUtilEx.HasFixedFunctionShaders( s );
+ if ( flag )
+ {
+ GUIContent showCurrent = CustomShaderInspector.Styles.showCurrent;
+ Rect rect = GUILayoutUtility.GetRect( showCurrent, EditorStyles.miniButton, new GUILayoutOption[]
+ {
+ GUILayout.ExpandWidth(false)
+ } );
+ Rect position = new Rect( rect.xMax - 16f, rect.y, 16f, rect.height );
+ if ( EditorGUIEx.ButtonMouseDown( position, GUIContent.none, FocusType.Passive, GUIStyle.none ) )
+ {
+ Rect last = GUILayoutUtilityEx.TopLevel_GetLast();
+ PopupWindow.Show( last, ( PopupWindowContent ) Activator.CreateInstance( System.Type.GetType( "UnityEditor.ShaderInspectorPlatformsPopup, UnityEditor" ), new object[] { s } ) );
+ GUIUtility.ExitGUI();
+ }
+ if ( GUI.Button( rect, showCurrent, EditorStyles.miniButton ) )
+ {
+ ShaderUtilEx.OpenCompiledShader( s, ShaderInspectorPlatformsPopupEx.GetCurrentMode(), ShaderInspectorPlatformsPopupEx.GetCurrentPlatformMask(), ShaderInspectorPlatformsPopupEx.GetCurrentVariantStripping() == 0 );
+ GUIUtility.ExitGUI();
+ }
+ }
+ else
+ {
+ GUILayout.Button( "none (precompiled shader)", GUI.skin.label, new GUILayoutOption[ 0 ] );
+ }
+ EditorGUILayout.EndHorizontal();
+ }
+
+ private static void ShowSurfaceShaderButton( Shader s )
+ {
+ bool flag = ShaderUtilEx.HasSurfaceShaders( s );
+ EditorGUILayout.BeginHorizontal( new GUILayoutOption[ 0 ] );
+ EditorGUILayout.PrefixLabel( "Surface shader", EditorStyles.miniButton );
+ if ( flag )
+ {
+ if ( !( AssetImporter.GetAtPath( AssetDatabase.GetAssetPath( s ) ) == null ) )
+ {
+ if ( GUILayout.Button( CustomShaderInspector.Styles.showSurface, EditorStyles.miniButton, new GUILayoutOption[]
+ {
+ GUILayout.ExpandWidth(false)
+ } ) )
+ {
+ ShaderUtilEx.OpenParsedSurfaceShader( s );
+ GUIUtility.ExitGUI();
+ }
+ }
+ else
+ {
+ GUILayout.Button( CustomShaderInspector.Styles.builtinShader, GUI.skin.label, new GUILayoutOption[ 0 ] );
+ }
+ }
+ else
+ {
+ GUILayout.Button( CustomShaderInspector.Styles.no, GUI.skin.label, new GUILayoutOption[ 0 ] );
+ }
+ EditorGUILayout.EndHorizontal();
+ }
+
+ private static void ShowFixedFunctionShaderButton( Shader s )
+ {
+ bool flag = ShaderUtilEx.HasFixedFunctionShaders( s );
+ EditorGUILayout.BeginHorizontal( new GUILayoutOption[ 0 ] );
+ EditorGUILayout.PrefixLabel( "Fixed function", EditorStyles.miniButton );
+ if ( flag )
+ {
+ if ( !( AssetImporter.GetAtPath( AssetDatabase.GetAssetPath( s ) ) == null ) )
+ {
+ if ( GUILayout.Button( CustomShaderInspector.Styles.showFF, EditorStyles.miniButton, new GUILayoutOption[]
+ {
+ GUILayout.ExpandWidth(false)
+ } ) )
+ {
+ ShaderUtilEx.OpenGeneratedFixedFunctionShader( s );
+ GUIUtility.ExitGUI();
+ }
+ }
+ else
+ {
+ GUILayout.Button( CustomShaderInspector.Styles.builtinShader, GUI.skin.label, new GUILayoutOption[ 0 ] );
+ }
+ }
+ else
+ {
+ GUILayout.Button( CustomShaderInspector.Styles.no, GUI.skin.label, new GUILayoutOption[ 0 ] );
+ }
+ EditorGUILayout.EndHorizontal();
+ }
+ }
+
+ internal class KeywordsPopup : PopupWindowContent
+ {
+ private Vector2 m_ScrollPos = Vector2.zero;
+ private string[] m_GlobalKeywords;
+ private string[] m_LocalKeywords;
+ private bool m_GlobalKeywordsExpended;
+ private bool m_LocalKeywordsExpended;
+ private float m_WindowWidth;
+
+ private static readonly GUIStyle m_Style = EditorStyles.miniLabel;
+
+ public KeywordsPopup( string[] globalKeywords, string[] localKeywords, float windowWidth )
+ {
+ m_GlobalKeywords = globalKeywords;
+ m_LocalKeywords = localKeywords;
+ m_GlobalKeywordsExpended = true;
+ m_LocalKeywordsExpended = true;
+ m_WindowWidth = windowWidth;
+ }
+
+ public override Vector2 GetWindowSize()
+ {
+ var numValues = m_GlobalKeywords.Length + m_LocalKeywords.Length + 2;
+ var lineHeight = m_Style.lineHeight + m_Style.padding.vertical + m_Style.margin.top;
+ return new Vector2( m_WindowWidth, Math.Min( lineHeight * numValues, 250.0f ) );
+ }
+
+ public override void OnGUI( Rect rect )
+ {
+ m_ScrollPos = EditorGUILayout.BeginScrollView( m_ScrollPos );
+
+ m_GlobalKeywordsExpended = KeywordsFoldout( m_GlobalKeywordsExpended, "Global Keywords", m_GlobalKeywords );
+ m_LocalKeywordsExpended = KeywordsFoldout( m_LocalKeywordsExpended, "Local Keywords", m_LocalKeywords );
+
+ EditorGUILayout.EndScrollView();
+ }
+
+ private bool KeywordsFoldout( bool expended, string name, string[] values )
+ {
+ expended = EditorGUILayout.Foldout( expended, name, true, m_Style );
+
+ if( expended )
+ {
+ EditorGUI.indentLevel++;
+ for( int i = 0; i < values.Length; ++i )
+ {
+ EditorGUILayout.LabelField( values[ i ], m_Style );
+ }
+ EditorGUI.indentLevel--;
+ }
+
+ return expended;
+ }
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // UNITY EDITOR EXTENSIONS
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ public enum DisableBatchingType
+ {
+ False,
+ True,
+ WhenLODFading
+ }
+
+ public struct ShaderError
+ {
+ public string message;
+ public string messageDetails;
+ public string platform;
+ public string file;
+ public int line;
+ public int warning;
+ }
+
+ public static class EditorGUIUtilityEx
+ {
+ private static System.Type type = null;
+ public static System.Type Type { get { return ( type == null ) ? type = System.Type.GetType( "UnityEditor.EditorGUIUtility, UnityEditor" ) : type; } }
+
+ public static Texture2D LoadIcon( string icon )
+ {
+ return ( Texture2D ) EditorGUIUtilityEx.Type.InvokeMember( "LoadIcon", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { icon } );
+ }
+
+ public static GUIContent TextContent( string t )
+ {
+ return ( GUIContent ) EditorGUIUtilityEx.Type.InvokeMember( "TextContent", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { t } );
+ }
+
+ internal static GUIContent TempContent( string t )
+ {
+ return ( GUIContent ) EditorGUIUtilityEx.Type.InvokeMember( "TempContent", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { t } );
+ }
+
+ internal static GUIContent TempContent( Texture i )
+ {
+ return ( GUIContent ) EditorGUIUtilityEx.Type.InvokeMember( "TempContent", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { i } );
+ }
+
+ internal static GUIContent TempContent( string t, Texture i )
+ {
+ return ( GUIContent ) EditorGUIUtilityEx.Type.InvokeMember( "TempContent", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { t, i } );
+ }
+ }
+
+ public static class EditorGUILayoutEx
+ {
+ public static System.Type Type = typeof( EditorGUILayout );
+ public static Gradient GradientField( Gradient value, params GUILayoutOption[] options )
+ {
+#if UNITY_2018_3_OR_NEWER
+ return EditorGUILayout.GradientField( value, options );
+#else
+ MethodInfo method = EditorGUILayoutEx.Type.GetMethod( "GradientField", BindingFlags.NonPublic | BindingFlags.Static, null, new Type[] { typeof( Gradient ), typeof( GUILayoutOption[] ) }, null );
+ return (Gradient)method.Invoke( Type, new object[]{ value, options} );
+#endif
+ }
+
+ public static Gradient GradientField( string label, Gradient value, params GUILayoutOption[] options )
+ {
+#if UNITY_2018_3_OR_NEWER
+ return EditorGUILayout.GradientField( label, value, options );
+#else
+ MethodInfo method = EditorGUILayoutEx.Type.GetMethod( "GradientField", BindingFlags.NonPublic | BindingFlags.Static, null, new Type[] { typeof( string ), typeof( Gradient ), typeof( GUILayoutOption[] ) }, null );
+ return (Gradient)method.Invoke( Type, new object[] { label, value, options } );
+#endif
+ }
+ }
+
+ public static class GUILayoutUtilityEx
+ {
+ private static System.Type type = null;
+ public static System.Type Type { get { return ( type == null ) ? type = System.Type.GetType( "UnityEngine.GUILayoutUtility, UnityEngine" ) : type; } }
+
+ public static Rect TopLevel_GetLast()
+ {
+ System.Type guiLayoutGroup = System.Type.GetType( "UnityEngine.GUILayoutGroup, UnityEngine" );
+ var topLevel = GUILayoutUtilityEx.Type.GetProperty( "topLevel", BindingFlags.NonPublic | BindingFlags.Static ).GetValue( null, null );
+ return ( Rect ) guiLayoutGroup.InvokeMember( "GetLast", BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod, null, topLevel, new object[] { } );
+ }
+ }
+
+ public static class ShaderEx
+ {
+ private static System.Type type = null;
+ public static System.Type Type { get { return ( type == null ) ? type = System.Type.GetType( "UnityEngine.Shader, UnityEngine" ) : type; } }
+
+ public static DisableBatchingType GetDisableBatching( Shader s )
+ {
+ return ( DisableBatchingType ) ShaderEx.Type.GetProperty( "disableBatching", BindingFlags.NonPublic | BindingFlags.Instance ).GetValue( s, new object[ 0 ] );
+ }
+ }
+
+ public static class ShaderUtilEx
+ {
+ private static System.Type type = null;
+ public static System.Type Type { get { return ( type == null ) ? type = System.Type.GetType( "UnityEditor.ShaderUtil, UnityEditor" ) : type; } }
+
+ public static void OpenParsedSurfaceShader( Shader s )
+ {
+ ShaderUtilEx.Type.InvokeMember( "OpenParsedSurfaceShader", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { s } );
+ }
+
+ public static void OpenGeneratedFixedFunctionShader( Shader s )
+ {
+ ShaderUtilEx.Type.InvokeMember( "OpenGeneratedFixedFunctionShader", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { s } );
+ }
+
+ public static void OpenCompiledShader( Shader shader, int mode, int customPlatformsMask, bool includeAllVariants )
+ {
+ ShaderUtilEx.Type.InvokeMember( "OpenCompiledShader", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { shader, mode, customPlatformsMask, includeAllVariants } );
+ }
+
+ public static void FetchCachedErrors( Shader s )
+ {
+#if UNITY_2019_3_OR_NEWER
+ ShaderUtilEx.Type.InvokeMember( "FetchCachedMessages", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { s } );
+#else
+ ShaderUtilEx.Type.InvokeMember( "FetchCachedErrors", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { s } );
+#endif
+ }
+
+ public static string[] GetShaderGlobalKeywords( Shader s )
+ {
+ return ShaderUtilEx.Type.InvokeMember( "GetShaderGlobalKeywords", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { s } ) as string[];
+ }
+
+ public static string[] GetShaderLocalKeywords( Shader s )
+ {
+ return ShaderUtilEx.Type.InvokeMember( "GetShaderLocalKeywords", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { s } ) as string[];
+ }
+
+ public static int GetShaderErrorCount( Shader s )
+ {
+#if UNITY_2019_3_OR_NEWER
+ return ShaderUtil.GetShaderMessageCount( s );
+#else
+ return ( int ) ShaderUtilEx.Type.InvokeMember( "GetShaderErrorCount", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { s } );
+#endif
+ }
+
+ public static int GetAvailableShaderCompilerPlatforms()
+ {
+ return (int)ShaderUtilEx.Type.InvokeMember( "GetAvailableShaderCompilerPlatforms", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { } );
+ }
+
+ public static ShaderError[] GetShaderErrors( Shader s )
+ {
+ System.Type shaderErrorType = System.Type.GetType( "UnityEditor.ShaderError, UnityEditor" );
+ var errorList = ( System.Collections.IList ) ShaderUtilEx.Type.InvokeMember( "GetShaderErrors", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { s } );
+
+ FieldInfo messageField = shaderErrorType.GetField( "message", BindingFlags.Public | BindingFlags.Instance );
+ FieldInfo messageDetailsField = shaderErrorType.GetField( "messageDetails", BindingFlags.Public | BindingFlags.Instance );
+ FieldInfo platformField = shaderErrorType.GetField( "platform", BindingFlags.Public | BindingFlags.Instance );
+ FieldInfo fileField = shaderErrorType.GetField( "file", BindingFlags.Public | BindingFlags.Instance );
+ FieldInfo lineField = shaderErrorType.GetField( "line", BindingFlags.Public | BindingFlags.Instance );
+ FieldInfo warningField = shaderErrorType.GetField( "warning", BindingFlags.Public | BindingFlags.Instance );
+
+ ShaderError[] errors = new ShaderError[ errorList.Count ];
+ for ( int i = 0; i < errorList.Count; i++ )
+ {
+ errors[ i ].message = ( string ) messageField.GetValue( errorList[ i ] );
+ errors[ i ].messageDetails = ( string ) messageDetailsField.GetValue( errorList[ i ] );
+ errors[ i ].platform = ( string ) platformField.GetValue( errorList[ i ] );
+ errors[ i ].file = ( string ) fileField.GetValue( errorList[ i ] );
+ errors[ i ].line = ( int ) lineField.GetValue( errorList[ i ] );
+ errors[ i ].warning = ( int ) warningField.GetValue( errorList[ i ] );
+ }
+ return errors;
+ }
+
+ public static bool HasShaderSnippets( Shader s )
+ {
+ return ( bool ) ShaderUtilEx.Type.InvokeMember( "HasShaderSnippets", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { s } );
+ }
+
+ public static bool HasSurfaceShaders( Shader s )
+ {
+ return ( bool ) ShaderUtilEx.Type.InvokeMember( "HasSurfaceShaders", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { s } );
+ }
+
+ public static bool HasFixedFunctionShaders( Shader s )
+ {
+ return ( bool ) ShaderUtilEx.Type.InvokeMember( "HasFixedFunctionShaders", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { s } );
+ }
+
+ public static bool HasShadowCasterPass( Shader s )
+ {
+ return ( bool ) ShaderUtilEx.Type.InvokeMember( "HasShadowCasterPass", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { s } );
+ }
+
+ public static int GetRenderQueue( Shader s )
+ {
+ return ( int ) ShaderUtilEx.Type.InvokeMember( "GetRenderQueue", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { s } );
+ }
+
+ public static int GetLOD( Shader s )
+ {
+ return ( int ) ShaderUtilEx.Type.InvokeMember( "GetLOD", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { s } );
+ }
+
+ public static bool DoesIgnoreProjector( Shader s )
+ {
+ return ( bool ) ShaderUtilEx.Type.InvokeMember( "DoesIgnoreProjector", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { s } );
+ }
+
+#if UNITY_2018_3_OR_NEWER
+ public static int GetShaderActiveSubshaderIndex( Shader s )
+ {
+ return (int)ShaderUtilEx.Type.InvokeMember( "GetShaderActiveSubshaderIndex", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { s } );
+ }
+
+ public static int GetSRPBatcherCompatibilityCode( Shader s, int subShaderIdx )
+ {
+ return (int)ShaderUtilEx.Type.InvokeMember( "GetSRPBatcherCompatibilityCode", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { s, subShaderIdx } );
+ }
+
+ public static string GetSRPBatcherCompatibilityIssueReason( Shader s, int subShaderIdx, int err )
+ {
+ return (string)ShaderUtilEx.Type.InvokeMember( "GetSRPBatcherCompatibilityIssueReason", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { s, subShaderIdx, err } );
+ }
+#endif
+ }
+
+ public static class FileUtilEx
+ {
+ private static System.Type type = null;
+ public static System.Type Type { get { return ( type == null ) ? type = System.Type.GetType( "UnityEditor.FileUtil, UnityEditor" ) : type; } }
+
+ public static string GetLastPathNameComponent( string path )
+ {
+ return ( string ) FileUtilEx.Type.InvokeMember( "GetLastPathNameComponent", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { path } );
+ }
+ }
+
+ public static class ShaderInspectorEx
+ {
+ private static System.Type type = null;
+ public static System.Type Type { get { return ( type == null ) ? type = System.Type.GetType( "UnityEditor.ShaderInspector, UnityEditor" ) : type; } }
+
+#if UNITY_2019_3_OR_NEWER
+ public static void ShaderErrorListUI( UnityEngine.Object shader, ShaderMessage[] messages, ref Vector2 scrollPosition )
+ {
+ Type.InvokeMember( "ShaderErrorListUI", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { shader, messages, scrollPosition } );
+ }
+#endif
+ }
+
+ public static class GUISkinEx
+ {
+ private static System.Type type = null;
+ public static System.Type Type { get { return ( type == null ) ? type = System.Type.GetType( "UnityEngine.GUISkin, UnityEngine" ) : type; } }
+
+ public static GUISkin GetCurrentSkin()
+ {
+ return ( GUISkin ) GUISkinEx.Type.GetField( "current", BindingFlags.NonPublic | BindingFlags.Static ).GetValue( null );
+ }
+ }
+
+ public static class EditorGUIEx
+ {
+ public static System.Type Type = typeof( EditorGUI );
+
+ public static Gradient GradientField( Rect position, Gradient gradient )
+ {
+#if UNITY_2018_3_OR_NEWER
+ return EditorGUI.GradientField( position, gradient );
+#else
+ return (Gradient)EditorGUIEx.Type.InvokeMember( "GradientField", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { position, gradient } );
+#endif
+ }
+
+ public static bool ButtonMouseDown( Rect position, GUIContent content, FocusType focusType, GUIStyle style )
+ {
+#if UNITY_5_6_OR_NEWER
+ return EditorGUI.DropdownButton( position, content, focusType, style );
+#else
+ return ( bool ) EditorGUIEx.Type.InvokeMember( "ButtonMouseDown", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { position, content, focusType, style } );
+#endif
+ }
+
+ public static float kObjectFieldMiniThumbnailHeight
+ {
+ get
+ {
+ return (float)EditorGUIEx.Type.InvokeMember( "kObjectFieldMiniThumbnailHeight", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.GetField, null, null, new object[] {} );
+ }
+ }
+
+ public static float kSingleLineHeight
+ {
+ get
+ {
+ return (float)EditorGUIEx.Type.InvokeMember( "kSingleLineHeight", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.GetField, null, null, new object[] { } );
+ }
+ }
+
+ }
+
+ public static class ShaderInspectorPlatformsPopupEx
+ {
+ private static System.Type type = null;
+ public static System.Type Type { get { return ( type == null ) ? type = System.Type.GetType( "UnityEditor.ShaderInspectorPlatformsPopup, UnityEditor" ) : type; } }
+
+ public static int GetCurrentMode()
+ {
+ return ( int ) ShaderInspectorPlatformsPopupEx.Type.GetProperty( "currentMode", BindingFlags.Public | BindingFlags.Static ).GetValue( null, null );
+ }
+
+ public static int GetCurrentPlatformMask()
+ {
+ return ( int ) ShaderInspectorPlatformsPopupEx.Type.GetProperty( "currentPlatformMask", BindingFlags.Public | BindingFlags.Static ).GetValue( null, null );
+ }
+
+ public static int GetCurrentVariantStripping()
+ {
+ return ( int ) ShaderInspectorPlatformsPopupEx.Type.GetProperty( "currentVariantStripping", BindingFlags.Public | BindingFlags.Static ).GetValue( null, null );
+ }
+ }
+}