// Custom property draw, we don't want things that are connected to an edge or useless like the render queue protected bool MaterialPropertiesGUI(Material material, bool autoLabelWidth = true) { if (material == null || material.shader == null) { return(false); } if (autoLabelWidth) { EditorGUIUtility.wideMode = false; EditorGUIUtility.labelWidth = nodeTarget.nodeWidth / 3.0f; } MaterialProperty[] properties = MaterialEditor.GetMaterialProperties(new [] { material }); var portViews = GetPortViewsFromFieldName(nameof(ShaderNode.materialInputs)); MaterialEditor editor; if (!materialEditors.TryGetValue(material, out editor)) { editor = materialEditors[material] = Editor.CreateEditor(material) as MaterialEditor; MixturePropertyDrawer.RegisterEditor(editor, this, owner.graph); } bool propertiesChanged = CheckPropertyChanged(material, properties); foreach (var property in properties) { if ((property.flags & (MaterialProperty.PropFlags.HideInInspector | MaterialProperty.PropFlags.PerRendererData)) != 0) { continue; } // Retrieve the port view from the property name var portView = portViews?.FirstOrDefault(p => p.portData.identifier == property.name); if (portView != null && portView.connected) { continue; } float h = editor.GetPropertyHeight(property, property.displayName); Rect r = EditorGUILayout.GetControlRect(true, h); if (property.name.Contains("Vector2")) { property.vectorValue = (Vector4)EditorGUI.Vector2Field(r, property.displayName, (Vector2)property.vectorValue); } else if (property.name.Contains("Vector3")) { property.vectorValue = (Vector4)EditorGUI.Vector3Field(r, property.displayName, (Vector3)property.vectorValue); } else { editor.ShaderProperty(r, property, property.displayName); } } return(propertiesChanged); }
protected bool MaterialPropertiesGUI(Material material, bool fromInspector, bool autoLabelWidth = true) { if (material == null || material.shader == null) { return(false); } if (autoLabelWidth) { EditorGUIUtility.wideMode = false; EditorGUIUtility.labelWidth = nodeTarget.nodeWidth / 3.0f; } MaterialProperty[] properties = MaterialEditor.GetMaterialProperties(new [] { material }); var portViews = GetPortViewsFromFieldName(nameof(ShaderNode.materialInputs)); MaterialEditor editor; if (!materialEditors.TryGetValue(material, out editor)) { editor = materialEditors[material] = Editor.CreateEditor(material) as MaterialEditor; MixturePropertyDrawer.RegisterEditor(editor, this, owner.graph); } bool propertiesChanged = CheckPropertyChanged(material, properties); foreach (var property in properties) { if ((property.flags & (MaterialProperty.PropFlags.HideInInspector | MaterialProperty.PropFlags.PerRendererData)) != 0) { continue; } int idx = material.shader.FindPropertyIndex(property.name); var propertyAttributes = material.shader.GetPropertyAttributes(idx); if (!fromInspector && propertyAttributes.Contains("ShowInInspector")) { continue; } // Retrieve the port view from the property name var portView = portViews?.FirstOrDefault(p => p.portData.identifier == property.name); if (portView != null && portView.connected) { continue; } // We only display textures that are excluded from the filteredOutProperties (i.e they are not exposed as ports) if (property.type == MaterialProperty.PropType.Texture && nodeTarget is ShaderNode sn) { if (!sn.GetFilterOutProperties().Contains(property.name)) { continue; } } // TODO: cache to improve the performance of the UI var visibleIfAtribute = propertyAttributes.FirstOrDefault(s => s.Contains("VisibleIf")); if (!string.IsNullOrEmpty(visibleIfAtribute)) { var match = visibleIfRegex.Match(visibleIfAtribute); if (match.Success) { string propertyName = match.Groups[1].Value; string[] accpectedValues = match.Groups[2].Value.Split(','); if (material.HasProperty(propertyName)) { float f = material.GetFloat(propertyName); bool show = false; foreach (var value in accpectedValues) { float f2 = float.Parse(value); if (f == f2) { show = true; } } if (!show) { continue; } } else { continue; } } } // Hide all the properties that are not supported in the current dimension var currentDimension = nodeTarget.rtSettings.GetTextureDimension(owner.graph); string displayName = property.displayName; bool is2D = displayName.Contains(MixtureUtils.texture2DPrefix); bool is3D = displayName.Contains(MixtureUtils.texture3DPrefix); bool isCube = displayName.Contains(MixtureUtils.textureCubePrefix); if (is2D || is3D || isCube) { if (currentDimension == TextureDimension.Tex2D && !is2D) { continue; } if (currentDimension == TextureDimension.Tex3D && !is3D) { continue; } if (currentDimension == TextureDimension.Cube && !isCube) { continue; } displayName = Regex.Replace(displayName, @"_2D|_3D|_Cube", "", RegexOptions.IgnoreCase); } // In ShaderGraph we can put [Inspector] in the name of the property to show it only in the inspector and not in the node if (property.displayName.ToLower().Contains("[inspector]")) { if (fromInspector) { displayName = Regex.Replace(property.displayName, @"\[inspector\]\s*", "", RegexOptions.IgnoreCase); } else { continue; } } float h = editor.GetPropertyHeight(property, displayName); // We always display textures on a single line without scale or offset because they are not supported if (property.type == MaterialProperty.PropType.Texture) { h = EditorGUIUtility.singleLineHeight; } Rect r = EditorGUILayout.GetControlRect(true, h); if (property.name.Contains("Vector2")) { property.vectorValue = (Vector4)EditorGUI.Vector2Field(r, displayName, (Vector2)property.vectorValue); } else if (property.name.Contains("Vector3")) { property.vectorValue = (Vector4)EditorGUI.Vector3Field(r, displayName, (Vector3)property.vectorValue); } else if (property.type == MaterialProperty.PropType.Range) { if (material.shader.GetPropertyAttributes(idx).Any(a => a.Contains("IntRange"))) { property.floatValue = EditorGUI.IntSlider(r, displayName, (int)property.floatValue, (int)property.rangeLimits.x, (int)property.rangeLimits.y); } else { property.floatValue = EditorGUI.Slider(r, displayName, property.floatValue, property.rangeLimits.x, property.rangeLimits.y); } } else if (property.type == MaterialProperty.PropType.Texture) { property.textureValue = (Texture)EditorGUI.ObjectField(r, displayName, property.textureValue, typeof(Texture), false); } else { editor.ShaderProperty(r, property, displayName); } } return(propertiesChanged); }