initial commit

This commit is contained in:
Jo 2025-01-07 02:06:59 +01:00
parent 6715289efe
commit 788c3389af
37645 changed files with 2526849 additions and 80 deletions

View file

@ -0,0 +1,785 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor.Rendering;
using UnityEditor.Rendering.Universal;
using UnityEditor.ShaderGraph;
using UnityEditor.ShaderGraph.Drawing;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
using static Unity.Rendering.Universal.ShaderUtils;
using RenderQueue = UnityEngine.Rendering.RenderQueue;
namespace UnityEditor
{
public abstract class BaseShaderGUI : ShaderGUI
{
#region EnumsAndClasses
[Flags]
[URPHelpURL("shaders-in-universalrp")]
protected enum Expandable
{
SurfaceOptions = 1 << 0,
SurfaceInputs = 1 << 1,
Advanced = 1 << 2,
Details = 1 << 3,
}
public enum SurfaceType
{
Opaque,
Transparent
}
public enum BlendMode
{
Alpha, // Old school alpha-blending mode, fresnel does not affect amount of transparency
Premultiply, // Physically plausible transparency mode, implemented as alpha pre-multiply
Additive,
Multiply
}
public enum SmoothnessSource
{
SpecularAlpha,
BaseAlpha,
}
public enum RenderFace
{
Front = 2,
Back = 1,
Both = 0
}
public enum QueueControl
{
Auto = 0,
UserOverride = 1
}
protected class Styles
{
public static readonly string[] surfaceTypeNames = Enum.GetNames(typeof(SurfaceType));
public static readonly string[] blendModeNames = Enum.GetNames(typeof(BlendMode));
public static readonly string[] renderFaceNames = Enum.GetNames(typeof(RenderFace));
public static readonly string[] zwriteNames = Enum.GetNames(typeof(UnityEditor.Rendering.Universal.ShaderGraph.ZWriteControl));
public static readonly string[] queueControlNames = Enum.GetNames(typeof(QueueControl));
// need to skip the first entry for ztest (ZTestMode.Disabled is not a valid value)
public static readonly int[] ztestValues = ((int[])Enum.GetValues(typeof(UnityEditor.Rendering.Universal.ShaderGraph.ZTestMode))).Skip(1).ToArray();
public static readonly string[] ztestNames = Enum.GetNames(typeof(UnityEditor.Rendering.Universal.ShaderGraph.ZTestMode)).Skip(1).ToArray();
// Categories
public static readonly GUIContent SurfaceOptions =
EditorGUIUtility.TrTextContent("Surface Options", "Controls how URP Renders the material on screen.");
public static readonly GUIContent SurfaceInputs = EditorGUIUtility.TrTextContent("Surface Inputs",
"These settings describe the look and feel of the surface itself.");
public static readonly GUIContent AdvancedLabel = EditorGUIUtility.TrTextContent("Advanced Options",
"These settings affect behind-the-scenes rendering and underlying calculations.");
public static readonly GUIContent surfaceType = EditorGUIUtility.TrTextContent("Surface Type",
"Select a surface type for your texture. Choose between Opaque or Transparent.");
public static readonly GUIContent blendingMode = EditorGUIUtility.TrTextContent("Blending Mode",
"Controls how the color of the Transparent surface blends with the Material color in the background.");
public static readonly GUIContent cullingText = EditorGUIUtility.TrTextContent("Render Face",
"Specifies which faces to cull from your geometry. Front culls front faces. Back culls backfaces. None means that both sides are rendered.");
public static readonly GUIContent zwriteText = EditorGUIUtility.TrTextContent("Depth Write",
"Controls whether the shader writes depth. Auto will write only when the shader is opaque.");
public static readonly GUIContent ztestText = EditorGUIUtility.TrTextContent("Depth Test",
"Specifies the depth test mode. The default is LEqual.");
public static readonly GUIContent alphaClipText = EditorGUIUtility.TrTextContent("Alpha Clipping",
"Makes your Material act like a Cutout shader. Use this to create a transparent effect with hard edges between opaque and transparent areas.");
public static readonly GUIContent alphaClipThresholdText = EditorGUIUtility.TrTextContent("Threshold",
"Sets where the Alpha Clipping starts. The higher the value is, the brighter the effect is when clipping starts.");
public static readonly GUIContent castShadowText = EditorGUIUtility.TrTextContent("Cast Shadows",
"When enabled, this GameObject will cast shadows onto any geometry that can receive them.");
public static readonly GUIContent receiveShadowText = EditorGUIUtility.TrTextContent("Receive Shadows",
"When enabled, other GameObjects can cast shadows onto this GameObject.");
public static readonly GUIContent baseMap = EditorGUIUtility.TrTextContent("Base Map",
"Specifies the base Material and/or Color of the surface. If youve selected Transparent or Alpha Clipping under Surface Options, your Material uses the Textures alpha channel or color.");
public static readonly GUIContent emissionMap = EditorGUIUtility.TrTextContent("Emission Map",
"Determines the color and intensity of light that the surface of the material emits.");
public static readonly GUIContent normalMapText =
EditorGUIUtility.TrTextContent("Normal Map", "Designates a Normal Map to create the illusion of bumps and dents on this Material's surface.");
public static readonly GUIContent bumpScaleNotSupported =
EditorGUIUtility.TrTextContent("Bump scale is not supported on mobile platforms");
public static readonly GUIContent fixNormalNow = EditorGUIUtility.TrTextContent("Fix now",
"Converts the assigned texture to be a normal map format.");
public static readonly GUIContent queueSlider = EditorGUIUtility.TrTextContent("Sorting Priority",
"Determines the chronological rendering order for a Material. Materials with lower value are rendered first.");
public static readonly GUIContent queueControl = EditorGUIUtility.TrTextContent("Queue Control",
"Controls whether render queue is automatically set based on material surface type, or explicitly set by the user.");
public static readonly GUIContent documentationIcon = EditorGUIUtility.TrIconContent("_Help", $"Open Reference for URP Shaders.");
}
#endregion
#region Variables
protected MaterialEditor materialEditor { get; set; }
protected MaterialProperty surfaceTypeProp { get; set; }
protected MaterialProperty blendModeProp { get; set; }
protected MaterialProperty cullingProp { get; set; }
protected MaterialProperty ztestProp { get; set; }
protected MaterialProperty zwriteProp { get; set; }
protected MaterialProperty alphaClipProp { get; set; }
protected MaterialProperty alphaCutoffProp { get; set; }
protected MaterialProperty castShadowsProp { get; set; }
protected MaterialProperty receiveShadowsProp { get; set; }
// Common Surface Input properties
protected MaterialProperty baseMapProp { get; set; }
protected MaterialProperty baseColorProp { get; set; }
protected MaterialProperty emissionMapProp { get; set; }
protected MaterialProperty emissionColorProp { get; set; }
protected MaterialProperty queueOffsetProp { get; set; }
protected MaterialProperty queueControlProp { get; set; }
public bool m_FirstTimeApply = true;
// By default, everything is expanded, except advanced
readonly MaterialHeaderScopeList m_MaterialScopeList = new MaterialHeaderScopeList(uint.MaxValue & ~(uint)Expandable.Advanced);
#endregion
private const int queueOffsetRange = 50;
////////////////////////////////////
// General Functions //
////////////////////////////////////
#region GeneralFunctions
[Obsolete("MaterialChanged has been renamed ValidateMaterial", false)]
public virtual void MaterialChanged(Material material)
{
ValidateMaterial(material);
}
public virtual void FindProperties(MaterialProperty[] properties)
{
var material = materialEditor?.target as Material;
if (material == null)
return;
surfaceTypeProp = FindProperty(Property.SurfaceType, properties, false);
blendModeProp = FindProperty(Property.BlendMode, properties, false);
cullingProp = FindProperty(Property.CullMode, properties, false);
zwriteProp = FindProperty(Property.ZWriteControl, properties, false);
ztestProp = FindProperty(Property.ZTest, properties, false);
alphaClipProp = FindProperty(Property.AlphaClip, properties, false);
// ShaderGraph Lit and Unlit Subtargets only
castShadowsProp = FindProperty(Property.CastShadows, properties, false);
queueControlProp = FindProperty(Property.QueueControl, properties, false);
// ShaderGraph Lit, and Lit.shader
receiveShadowsProp = FindProperty(Property.ReceiveShadows, properties, false);
// The following are not mandatory for shadergraphs (it's up to the user to add them to their graph)
alphaCutoffProp = FindProperty("_Cutoff", properties, false);
baseMapProp = FindProperty("_BaseMap", properties, false);
baseColorProp = FindProperty("_BaseColor", properties, false);
emissionMapProp = FindProperty(Property.EmissionMap, properties, false);
emissionColorProp = FindProperty(Property.EmissionColor, properties, false);
queueOffsetProp = FindProperty(Property.QueueOffset, properties, false);
}
public override void OnGUI(MaterialEditor materialEditorIn, MaterialProperty[] properties)
{
if (materialEditorIn == null)
throw new ArgumentNullException("materialEditorIn");
materialEditor = materialEditorIn;
Material material = materialEditor.target as Material;
FindProperties(properties); // MaterialProperties can be animated so we do not cache them but fetch them every event to ensure animated values are updated correctly
// Make sure that needed setup (ie keywords/renderqueue) are set up if we're switching some existing
// material to a universal shader.
if (m_FirstTimeApply)
{
OnOpenGUI(material, materialEditorIn);
m_FirstTimeApply = false;
}
ShaderPropertiesGUI(material);
}
protected virtual uint materialFilter => uint.MaxValue;
public virtual void OnOpenGUI(Material material, MaterialEditor materialEditor)
{
var filter = (Expandable)materialFilter;
// Generate the foldouts
if (filter.HasFlag(Expandable.SurfaceOptions))
m_MaterialScopeList.RegisterHeaderScope(Styles.SurfaceOptions, (uint)Expandable.SurfaceOptions, DrawSurfaceOptions);
if (filter.HasFlag(Expandable.SurfaceInputs))
m_MaterialScopeList.RegisterHeaderScope(Styles.SurfaceInputs, (uint)Expandable.SurfaceInputs, DrawSurfaceInputs);
if (filter.HasFlag(Expandable.Details))
FillAdditionalFoldouts(m_MaterialScopeList);
if (filter.HasFlag(Expandable.Advanced))
m_MaterialScopeList.RegisterHeaderScope(Styles.AdvancedLabel, (uint)Expandable.Advanced, DrawAdvancedOptions);
}
public void ShaderPropertiesGUI(Material material)
{
m_MaterialScopeList.DrawHeaders(materialEditor, material);
}
#endregion
////////////////////////////////////
// Drawing Functions //
////////////////////////////////////
#region DrawingFunctions
internal void DrawShaderGraphProperties(Material material, IEnumerable<MaterialProperty> properties)
{
if (properties == null)
return;
ShaderGraphPropertyDrawers.DrawShaderGraphGUI(materialEditor, properties);
}
internal static void DrawFloatToggleProperty(GUIContent styles, MaterialProperty prop)
{
if (prop == null)
return;
EditorGUI.BeginChangeCheck();
EditorGUI.showMixedValue = prop.hasMixedValue;
bool newValue = EditorGUILayout.Toggle(styles, prop.floatValue == 1);
if (EditorGUI.EndChangeCheck())
prop.floatValue = newValue ? 1.0f : 0.0f;
EditorGUI.showMixedValue = false;
}
public virtual void DrawSurfaceOptions(Material material)
{
DoPopup(Styles.surfaceType, surfaceTypeProp, Styles.surfaceTypeNames);
if ((surfaceTypeProp != null) && ((SurfaceType)surfaceTypeProp.floatValue == SurfaceType.Transparent))
DoPopup(Styles.blendingMode, blendModeProp, Styles.blendModeNames);
DoPopup(Styles.cullingText, cullingProp, Styles.renderFaceNames);
DoPopup(Styles.zwriteText, zwriteProp, Styles.zwriteNames);
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);
}
public virtual void DrawSurfaceInputs(Material material)
{
DrawBaseProperties(material);
}
public virtual void DrawAdvancedOptions(Material material)
{
// Only draw the sorting priority field if queue control is set to "auto"
bool autoQueueControl = GetAutomaticQueueControlSetting(material);
if (autoQueueControl)
DrawQueueOffsetField();
materialEditor.EnableInstancingField();
}
protected void DrawQueueOffsetField()
{
if (queueOffsetProp != null)
materialEditor.IntSliderShaderProperty(queueOffsetProp, -queueOffsetRange, queueOffsetRange, Styles.queueSlider);
}
[Obsolete("DrawAdditionalFoldouts has been deprecated. Use FillAdditionalFoldouts instead, and materialScopesList.RegisterHeaderScope", false)]
public virtual void DrawAdditionalFoldouts(Material material) { }
public virtual void FillAdditionalFoldouts(MaterialHeaderScopeList materialScopesList) { }
public virtual void DrawBaseProperties(Material material)
{
if (baseMapProp != null && baseColorProp != null) // Draw the baseMap, most shader will have at least a baseMap
{
materialEditor.TexturePropertySingleLine(Styles.baseMap, baseMapProp, baseColorProp);
}
}
private void DrawEmissionTextureProperty()
{
if ((emissionMapProp == null) || (emissionColorProp == null))
return;
using (new EditorGUI.IndentLevelScope(2))
{
materialEditor.TexturePropertyWithHDRColor(Styles.emissionMap, emissionMapProp, emissionColorProp, false);
}
}
protected virtual void DrawEmissionProperties(Material material, bool keyword)
{
var emissive = true;
if (!keyword)
{
DrawEmissionTextureProperty();
}
else
{
emissive = materialEditor.EmissionEnabledProperty();
using (new EditorGUI.DisabledScope(!emissive))
{
DrawEmissionTextureProperty();
}
}
// If texture was assigned and color was black set color to white
if ((emissionMapProp != null) && (emissionColorProp != null))
{
var hadEmissionTexture = emissionMapProp?.textureValue != null;
var brightness = emissionColorProp.colorValue.maxColorComponent;
if (emissionMapProp.textureValue != null && !hadEmissionTexture && brightness <= 0f)
emissionColorProp.colorValue = Color.white;
}
if (emissive)
{
// Change the GI emission flag and fix it up with emissive as black if necessary.
materialEditor.LightmapEmissionFlagsProperty(MaterialEditor.kMiniTextureFieldLabelIndentLevel, true);
}
}
public static void DrawNormalArea(MaterialEditor materialEditor, MaterialProperty bumpMap, MaterialProperty bumpMapScale = null)
{
if (bumpMapScale != null)
{
materialEditor.TexturePropertySingleLine(Styles.normalMapText, bumpMap,
bumpMap.textureValue != null ? bumpMapScale : null);
if (bumpMapScale.floatValue != 1 &&
UnityEditorInternal.InternalEditorUtility.IsMobilePlatform(
EditorUserBuildSettings.activeBuildTarget))
if (materialEditor.HelpBoxWithButton(Styles.bumpScaleNotSupported, Styles.fixNormalNow))
bumpMapScale.floatValue = 1;
}
else
{
materialEditor.TexturePropertySingleLine(Styles.normalMapText, bumpMap);
}
}
protected static void DrawTileOffset(MaterialEditor materialEditor, MaterialProperty textureProp)
{
if (textureProp != null)
materialEditor.TextureScaleOffsetProperty(textureProp);
}
#endregion
////////////////////////////////////
// Material Data Functions //
////////////////////////////////////
#region MaterialDataFunctions
// this function is shared with ShaderGraph Lit/Unlit GUIs and also the hand-written GUIs
internal static void UpdateMaterialSurfaceOptions(Material material, bool automaticRenderQueue)
{
// Setup blending - consistent across all Universal RP shaders
SetupMaterialBlendModeInternal(material, out int renderQueue);
// apply automatic render queue
if (automaticRenderQueue && (renderQueue != material.renderQueue))
material.renderQueue = renderQueue;
bool isShaderGraph = material.IsShaderGraph();
// Cast Shadows
bool castShadows = true;
if (material.HasProperty(Property.CastShadows))
{
castShadows = (material.GetFloat(Property.CastShadows) != 0.0f);
}
else
{
if (isShaderGraph)
{
// Lit.shadergraph or Unlit.shadergraph, but no material control defined
// enable the pass in the material, so shader can decide...
castShadows = true;
}
else
{
// Lit.shader or Unlit.shader -- set based on transparency
castShadows = Rendering.Universal.ShaderGUI.LitGUI.IsOpaque(material);
}
}
material.SetShaderPassEnabled("ShadowCaster", castShadows);
// Receive Shadows
if (material.HasProperty(Property.ReceiveShadows))
CoreUtils.SetKeyword(material, ShaderKeywordStrings._RECEIVE_SHADOWS_OFF, material.GetFloat(Property.ReceiveShadows) == 0.0f);
}
// this function is shared between ShaderGraph and hand-written GUIs
internal static void UpdateMaterialRenderQueueControl(Material material)
{
//
// Render Queue Control handling
//
// Check for a raw render queue (the actual serialized setting - material.renderQueue has already been converted)
// setting of -1, indicating that the material property should be inherited from the shader.
// If we find this, add a new property "render queue control" set to 0 so we will
// always know to follow the surface type of the material (this matches the hand-written behavior)
// If we find another value, add the the property set to 1 so we will know that the
// user has explicitly selected a render queue and we should not override it.
//
bool isShaderGraph = material.IsShaderGraph(); // Non-shadergraph materials use automatic behavior
int rawRenderQueue = MaterialAccess.ReadMaterialRawRenderQueue(material);
if (!isShaderGraph || rawRenderQueue == -1)
{
material.SetFloat(Property.QueueControl, (float)QueueControl.Auto); // Automatic behavior - surface type override
}
else
{
material.SetFloat(Property.QueueControl, (float)QueueControl.UserOverride); // User has selected explicit render queue
}
}
internal static bool GetAutomaticQueueControlSetting(Material material)
{
// If a Shader Graph material doesn't yet have the queue control property,
// we should not engage automatic behavior until the shader gets reimported.
bool automaticQueueControl = !material.IsShaderGraph();
if (material.HasProperty(Property.QueueControl))
{
var queueControl = material.GetFloat(Property.QueueControl);
if (queueControl < 0.0f)
{
// The property was added with a negative value, indicating it needs to be validated for this material
UpdateMaterialRenderQueueControl(material);
}
automaticQueueControl = (material.GetFloat(Property.QueueControl) == (float)QueueControl.Auto);
}
return automaticQueueControl;
}
// this is the function used by Lit.shader, Unlit.shader GUIs
public static void SetMaterialKeywords(Material material, Action<Material> shadingModelFunc = null, Action<Material> shaderFunc = null)
{
UpdateMaterialSurfaceOptions(material, automaticRenderQueue: true);
// Setup double sided GI based on Cull state
if (material.HasProperty(Property.CullMode))
material.doubleSidedGI = (RenderFace)material.GetFloat(Property.CullMode) != RenderFace.Front;
// Temporary fix for lightmapping. TODO: to be replaced with attribute tag.
if (material.HasProperty("_MainTex"))
{
material.SetTexture("_MainTex", material.GetTexture("_BaseMap"));
material.SetTextureScale("_MainTex", material.GetTextureScale("_BaseMap"));
material.SetTextureOffset("_MainTex", material.GetTextureOffset("_BaseMap"));
}
if (material.HasProperty("_Color"))
material.SetColor("_Color", material.GetColor("_BaseColor"));
// Emission
if (material.HasProperty(Property.EmissionColor))
MaterialEditor.FixupEmissiveFlag(material);
bool shouldEmissionBeEnabled =
(material.globalIlluminationFlags & MaterialGlobalIlluminationFlags.EmissiveIsBlack) == 0;
// Not sure what this is used for, I don't see this property declared by any Unity shader in our repo...
// I'm guessing it is some kind of legacy material upgrade support thing? Or maybe just dead code now...
if (material.HasProperty("_EmissionEnabled") && !shouldEmissionBeEnabled)
shouldEmissionBeEnabled = material.GetFloat("_EmissionEnabled") >= 0.5f;
CoreUtils.SetKeyword(material, ShaderKeywordStrings._EMISSION, shouldEmissionBeEnabled);
// Normal Map
if (material.HasProperty("_BumpMap"))
CoreUtils.SetKeyword(material, ShaderKeywordStrings._NORMALMAP, material.GetTexture("_BumpMap"));
// Shader specific keyword functions
shadingModelFunc?.Invoke(material);
shaderFunc?.Invoke(material);
}
internal static void SetMaterialSrcDstBlendProperties(Material material, UnityEngine.Rendering.BlendMode srcBlend, UnityEngine.Rendering.BlendMode dstBlend)
{
if (material.HasProperty(Property.SrcBlend))
material.SetFloat(Property.SrcBlend, (float)srcBlend);
if (material.HasProperty(Property.DstBlend))
material.SetFloat(Property.DstBlend, (float)dstBlend);
}
internal static void SetMaterialZWriteProperty(Material material, bool zwriteEnabled)
{
if (material.HasProperty(Property.ZWrite))
material.SetFloat(Property.ZWrite, zwriteEnabled ? 1.0f : 0.0f);
}
internal static void SetupMaterialBlendModeInternal(Material material, out int automaticRenderQueue)
{
if (material == null)
throw new ArgumentNullException("material");
bool alphaClip = false;
if (material.HasProperty(Property.AlphaClip))
alphaClip = material.GetFloat(Property.AlphaClip) >= 0.5;
CoreUtils.SetKeyword(material, ShaderKeywordStrings._ALPHATEST_ON, alphaClip);
// default is to use the shader render queue
int renderQueue = material.shader.renderQueue;
material.SetOverrideTag("RenderType", ""); // clear override tag
if (material.HasProperty(Property.SurfaceType))
{
SurfaceType surfaceType = (SurfaceType)material.GetFloat(Property.SurfaceType);
bool zwrite = false;
CoreUtils.SetKeyword(material, ShaderKeywordStrings._SURFACE_TYPE_TRANSPARENT, surfaceType == SurfaceType.Transparent);
if (surfaceType == SurfaceType.Opaque)
{
if (alphaClip)
{
renderQueue = (int)RenderQueue.AlphaTest;
material.SetOverrideTag("RenderType", "TransparentCutout");
}
else
{
renderQueue = (int)RenderQueue.Geometry;
material.SetOverrideTag("RenderType", "Opaque");
}
SetMaterialSrcDstBlendProperties(material, UnityEngine.Rendering.BlendMode.One, UnityEngine.Rendering.BlendMode.Zero);
zwrite = true;
material.DisableKeyword(ShaderKeywordStrings._ALPHAPREMULTIPLY_ON);
material.DisableKeyword(ShaderKeywordStrings._SURFACE_TYPE_TRANSPARENT);
}
else // SurfaceType Transparent
{
BlendMode blendMode = (BlendMode)material.GetFloat(Property.BlendMode);
material.DisableKeyword(ShaderKeywordStrings._ALPHAPREMULTIPLY_ON);
material.DisableKeyword(ShaderKeywordStrings._ALPHAMODULATE_ON);
// Specific Transparent Mode Settings
switch (blendMode)
{
case BlendMode.Alpha:
SetMaterialSrcDstBlendProperties(material,
UnityEngine.Rendering.BlendMode.SrcAlpha,
UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
break;
case BlendMode.Premultiply:
SetMaterialSrcDstBlendProperties(material,
UnityEngine.Rendering.BlendMode.One,
UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
material.EnableKeyword(ShaderKeywordStrings._ALPHAPREMULTIPLY_ON);
break;
case BlendMode.Additive:
SetMaterialSrcDstBlendProperties(material,
UnityEngine.Rendering.BlendMode.SrcAlpha,
UnityEngine.Rendering.BlendMode.One);
break;
case BlendMode.Multiply:
SetMaterialSrcDstBlendProperties(material,
UnityEngine.Rendering.BlendMode.DstColor,
UnityEngine.Rendering.BlendMode.Zero);
material.EnableKeyword(ShaderKeywordStrings._ALPHAMODULATE_ON);
break;
}
// General Transparent Material Settings
material.SetOverrideTag("RenderType", "Transparent");
zwrite = false;
material.EnableKeyword(ShaderKeywordStrings._SURFACE_TYPE_TRANSPARENT);
renderQueue = (int)RenderQueue.Transparent;
}
// check for override enum
if (material.HasProperty(Property.ZWriteControl))
{
var zwriteControl = (UnityEditor.Rendering.Universal.ShaderGraph.ZWriteControl)material.GetFloat(Property.ZWriteControl);
if (zwriteControl == UnityEditor.Rendering.Universal.ShaderGraph.ZWriteControl.ForceEnabled)
zwrite = true;
else if (zwriteControl == UnityEditor.Rendering.Universal.ShaderGraph.ZWriteControl.ForceDisabled)
zwrite = false;
}
SetMaterialZWriteProperty(material, zwrite);
material.SetShaderPassEnabled("DepthOnly", zwrite);
}
else
{
// no surface type property -- must be hard-coded by the shadergraph,
// so ensure the pass is enabled at the material level
material.SetShaderPassEnabled("DepthOnly", true);
}
// must always apply queue offset, even if not set to material control
if (material.HasProperty(Property.QueueOffset))
renderQueue += (int)material.GetFloat(Property.QueueOffset);
automaticRenderQueue = renderQueue;
}
public static void SetupMaterialBlendMode(Material material)
{
SetupMaterialBlendModeInternal(material, out int renderQueue);
// apply automatic render queue
if (renderQueue != material.renderQueue)
material.renderQueue = renderQueue;
}
public override void AssignNewShaderToMaterial(Material material, Shader oldShader, Shader newShader)
{
// Clear all keywords for fresh start
// Note: this will nuke user-selected custom keywords when they change shaders
material.shaderKeywords = null;
base.AssignNewShaderToMaterial(material, oldShader, newShader);
// Setup keywords based on the new shader
UpdateMaterial(material, MaterialUpdateType.ChangedAssignedShader);
}
#endregion
////////////////////////////////////
// Helper Functions //
////////////////////////////////////
#region HelperFunctions
public static void TwoFloatSingleLine(GUIContent title, MaterialProperty prop1, GUIContent prop1Label,
MaterialProperty prop2, GUIContent prop2Label, MaterialEditor materialEditor, float labelWidth = 30f)
{
const int kInterFieldPadding = 2;
Rect rect = EditorGUILayout.GetControlRect();
EditorGUI.PrefixLabel(rect, title);
var indent = EditorGUI.indentLevel;
var preLabelWidth = EditorGUIUtility.labelWidth;
EditorGUI.indentLevel = 0;
EditorGUIUtility.labelWidth = labelWidth;
Rect propRect1 = new Rect(rect.x + preLabelWidth, rect.y,
(rect.width - preLabelWidth) * 0.5f - 1, EditorGUIUtility.singleLineHeight);
EditorGUI.BeginChangeCheck();
EditorGUI.showMixedValue = prop1.hasMixedValue;
var prop1val = EditorGUI.FloatField(propRect1, prop1Label, prop1.floatValue);
if (EditorGUI.EndChangeCheck())
prop1.floatValue = prop1val;
Rect propRect2 = new Rect(propRect1.x + propRect1.width + kInterFieldPadding, rect.y,
propRect1.width, EditorGUIUtility.singleLineHeight);
EditorGUI.BeginChangeCheck();
EditorGUI.showMixedValue = prop2.hasMixedValue;
var prop2val = EditorGUI.FloatField(propRect2, prop2Label, prop2.floatValue);
if (EditorGUI.EndChangeCheck())
prop2.floatValue = prop2val;
EditorGUI.indentLevel = indent;
EditorGUIUtility.labelWidth = preLabelWidth;
EditorGUI.showMixedValue = false;
}
public void DoPopup(GUIContent label, MaterialProperty property, string[] options)
{
if (property != null)
materialEditor.PopupShaderProperty(property, label, options);
}
// Helper to show texture and color properties
public static Rect TextureColorProps(MaterialEditor materialEditor, GUIContent label, MaterialProperty textureProp, MaterialProperty colorProp, bool hdr = false)
{
Rect rect = EditorGUILayout.GetControlRect();
EditorGUI.showMixedValue = textureProp.hasMixedValue;
materialEditor.TexturePropertyMiniThumbnail(rect, textureProp, label.text, label.tooltip);
EditorGUI.showMixedValue = false;
if (colorProp != null)
{
EditorGUI.BeginChangeCheck();
EditorGUI.showMixedValue = colorProp.hasMixedValue;
int indentLevel = EditorGUI.indentLevel;
EditorGUI.indentLevel = 0;
Rect rectAfterLabel = new Rect(rect.x + EditorGUIUtility.labelWidth, rect.y,
EditorGUIUtility.fieldWidth, EditorGUIUtility.singleLineHeight);
var col = EditorGUI.ColorField(rectAfterLabel, GUIContent.none, colorProp.colorValue, true,
false, hdr);
EditorGUI.indentLevel = indentLevel;
if (EditorGUI.EndChangeCheck())
{
materialEditor.RegisterPropertyChangeUndo(colorProp.displayName);
colorProp.colorValue = col;
}
EditorGUI.showMixedValue = false;
}
return rect;
}
// Copied from shaderGUI as it is a protected function in an abstract class, unavailable to others
public new static MaterialProperty FindProperty(string propertyName, MaterialProperty[] properties)
{
return FindProperty(propertyName, properties, true);
}
// Copied from shaderGUI as it is a protected function in an abstract class, unavailable to others
public new static MaterialProperty FindProperty(string propertyName, MaterialProperty[] properties, bool propertyIsMandatory)
{
for (int index = 0; index < properties.Length; ++index)
{
if (properties[index] != null && properties[index].name == propertyName)
return properties[index];
}
if (propertyIsMandatory)
throw new ArgumentException("Could not find MaterialProperty: '" + propertyName + "', Num properties: " + (object)properties.Length);
return null;
}
#endregion
}
}

View file

@ -0,0 +1,782 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor.Rendering;
using UnityEditor.Rendering.Universal;
using UnityEditor.ShaderGraph;
using UnityEditor.ShaderGraph.Drawing;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
using static Unity.Rendering.Universal.ShaderUtils;
using RenderQueue = UnityEngine.Rendering.RenderQueue;
namespace UnityEditor
{
public abstract class BaseShaderGUI : ShaderGUI
{
#region EnumsAndClasses
[Flags]
[URPHelpURL("shaders-in-universalrp")]
protected enum Expandable
{
SurfaceOptions = 1 << 0,
SurfaceInputs = 1 << 1,
Advanced = 1 << 2,
Details = 1 << 3,
}
public enum SurfaceType
{
Opaque,
Transparent
}
public enum BlendMode
{
Alpha, // Old school alpha-blending mode, fresnel does not affect amount of transparency
Premultiply, // Physically plausible transparency mode, implemented as alpha pre-multiply
Additive,
Multiply
}
public enum SmoothnessSource
{
SpecularAlpha,
BaseAlpha,
}
public enum RenderFace
{
Front = 2,
Back = 1,
Both = 0
}
public enum QueueControl
{
Auto = 0,
UserOverride = 1
}
protected class Styles
{
public static readonly string[] surfaceTypeNames = Enum.GetNames(typeof(SurfaceType));
public static readonly string[] blendModeNames = Enum.GetNames(typeof(BlendMode));
public static readonly string[] renderFaceNames = Enum.GetNames(typeof(RenderFace));
public static readonly string[] zwriteNames = Enum.GetNames(typeof(UnityEditor.Rendering.Universal.ShaderGraph.ZWriteControl));
public static readonly string[] queueControlNames = Enum.GetNames(typeof(QueueControl));
// need to skip the first entry for ztest (ZTestMode.Disabled is not a valid value)
public static readonly int[] ztestValues = ((int[])Enum.GetValues(typeof(UnityEditor.Rendering.Universal.ShaderGraph.ZTestMode))).Skip(1).ToArray();
public static readonly string[] ztestNames = Enum.GetNames(typeof(UnityEditor.Rendering.Universal.ShaderGraph.ZTestMode)).Skip(1).ToArray();
// Categories
public static readonly GUIContent SurfaceOptions =
EditorGUIUtility.TrTextContent("Surface Options", "Controls how URP Renders the material on screen.");
public static readonly GUIContent SurfaceInputs = EditorGUIUtility.TrTextContent("Surface Inputs",
"These settings describe the look and feel of the surface itself.");
public static readonly GUIContent AdvancedLabel = EditorGUIUtility.TrTextContent("Advanced Options",
"These settings affect behind-the-scenes rendering and underlying calculations.");
public static readonly GUIContent surfaceType = EditorGUIUtility.TrTextContent("Surface Type",
"Select a surface type for your texture. Choose between Opaque or Transparent.");
public static readonly GUIContent blendingMode = EditorGUIUtility.TrTextContent("Blending Mode",
"Controls how the color of the Transparent surface blends with the Material color in the background.");
public static readonly GUIContent cullingText = EditorGUIUtility.TrTextContent("Render Face",
"Specifies which faces to cull from your geometry. Front culls front faces. Back culls backfaces. None means that both sides are rendered.");
public static readonly GUIContent zwriteText = EditorGUIUtility.TrTextContent("Depth Write",
"Controls whether the shader writes depth. Auto will write only when the shader is opaque.");
public static readonly GUIContent ztestText = EditorGUIUtility.TrTextContent("Depth Test",
"Specifies the depth test mode. The default is LEqual.");
public static readonly GUIContent alphaClipText = EditorGUIUtility.TrTextContent("Alpha Clipping",
"Makes your Material act like a Cutout shader. Use this to create a transparent effect with hard edges between opaque and transparent areas.");
public static readonly GUIContent alphaClipThresholdText = EditorGUIUtility.TrTextContent("Threshold",
"Sets where the Alpha Clipping starts. The higher the value is, the brighter the effect is when clipping starts.");
public static readonly GUIContent castShadowText = EditorGUIUtility.TrTextContent("Cast Shadows",
"When enabled, this GameObject will cast shadows onto any geometry that can receive them.");
public static readonly GUIContent receiveShadowText = EditorGUIUtility.TrTextContent("Receive Shadows",
"When enabled, other GameObjects can cast shadows onto this GameObject.");
public static readonly GUIContent baseMap = EditorGUIUtility.TrTextContent("Base Map",
"Specifies the base Material and/or Color of the surface. If youve selected Transparent or Alpha Clipping under Surface Options, your Material uses the Textures alpha channel or color.");
public static readonly GUIContent emissionMap = EditorGUIUtility.TrTextContent("Emission Map",
"Determines the color and intensity of light that the surface of the material emits.");
public static readonly GUIContent normalMapText =
EditorGUIUtility.TrTextContent("Normal Map", "Designates a Normal Map to create the illusion of bumps and dents on this Material's surface.");
public static readonly GUIContent bumpScaleNotSupported =
EditorGUIUtility.TrTextContent("Bump scale is not supported on mobile platforms");
public static readonly GUIContent fixNormalNow = EditorGUIUtility.TrTextContent("Fix now",
"Converts the assigned texture to be a normal map format.");
public static readonly GUIContent queueSlider = EditorGUIUtility.TrTextContent("Sorting Priority",
"Determines the chronological rendering order for a Material. Materials with lower value are rendered first.");
public static readonly GUIContent queueControl = EditorGUIUtility.TrTextContent("Queue Control",
"Controls whether render queue is automatically set based on material surface type, or explicitly set by the user.");
public static readonly GUIContent documentationIcon = EditorGUIUtility.TrIconContent("_Help", $"Open Reference for URP Shaders.");
}
#endregion
#region Variables
protected MaterialEditor materialEditor { get; set; }
protected MaterialProperty surfaceTypeProp { get; set; }
protected MaterialProperty blendModeProp { get; set; }
protected MaterialProperty cullingProp { get; set; }
protected MaterialProperty ztestProp { get; set; }
protected MaterialProperty zwriteProp { get; set; }
protected MaterialProperty alphaClipProp { get; set; }
protected MaterialProperty alphaCutoffProp { get; set; }
protected MaterialProperty castShadowsProp { get; set; }
protected MaterialProperty receiveShadowsProp { get; set; }
// Common Surface Input properties
protected MaterialProperty baseMapProp { get; set; }
protected MaterialProperty baseColorProp { get; set; }
protected MaterialProperty emissionMapProp { get; set; }
protected MaterialProperty emissionColorProp { get; set; }
protected MaterialProperty queueOffsetProp { get; set; }
protected MaterialProperty queueControlProp { get; set; }
public bool m_FirstTimeApply = true;
// By default, everything is expanded, except advanced
readonly MaterialHeaderScopeList m_MaterialScopeList = new MaterialHeaderScopeList(uint.MaxValue & ~(uint)Expandable.Advanced);
#endregion
private const int queueOffsetRange = 50;
////////////////////////////////////
// General Functions //
////////////////////////////////////
#region GeneralFunctions
[Obsolete("MaterialChanged has been renamed ValidateMaterial", false)]
public virtual void MaterialChanged(Material material)
{
ValidateMaterial(material);
}
public virtual void FindProperties(MaterialProperty[] properties)
{
var material = materialEditor?.target as Material;
if (material == null)
return;
surfaceTypeProp = FindProperty(Property.SurfaceType, properties, false);
blendModeProp = FindProperty(Property.BlendMode, properties, false);
cullingProp = FindProperty(Property.CullMode, properties, false);
zwriteProp = FindProperty(Property.ZWriteControl, properties, false);
ztestProp = FindProperty(Property.ZTest, properties, false);
alphaClipProp = FindProperty(Property.AlphaClip, properties, false);
// ShaderGraph Lit and Unlit Subtargets only
castShadowsProp = FindProperty(Property.CastShadows, properties, false);
queueControlProp = FindProperty(Property.QueueControl, properties, false);
// ShaderGraph Lit, and Lit.shader
receiveShadowsProp = FindProperty(Property.ReceiveShadows, properties, false);
// The following are not mandatory for shadergraphs (it's up to the user to add them to their graph)
alphaCutoffProp = FindProperty("_Cutoff", properties, false);
baseMapProp = FindProperty("_BaseMap", properties, false);
baseColorProp = FindProperty("_BaseColor", properties, false);
emissionMapProp = FindProperty(Property.EmissionMap, properties, false);
emissionColorProp = FindProperty(Property.EmissionColor, properties, false);
queueOffsetProp = FindProperty(Property.QueueOffset, properties, false);
}
public override void OnGUI(MaterialEditor materialEditorIn, MaterialProperty[] properties)
{
if (materialEditorIn == null)
throw new ArgumentNullException("materialEditorIn");
materialEditor = materialEditorIn;
Material material = materialEditor.target as Material;
FindProperties(properties); // MaterialProperties can be animated so we do not cache them but fetch them every event to ensure animated values are updated correctly
// Make sure that needed setup (ie keywords/renderqueue) are set up if we're switching some existing
// material to a universal shader.
if (m_FirstTimeApply)
{
OnOpenGUI(material, materialEditorIn);
m_FirstTimeApply = false;
}
ShaderPropertiesGUI(material);
}
protected virtual uint materialFilter => uint.MaxValue;
public virtual void OnOpenGUI(Material material, MaterialEditor materialEditor)
{
var filter = (Expandable)materialFilter;
// Generate the foldouts
if (filter.HasFlag(Expandable.SurfaceOptions))
m_MaterialScopeList.RegisterHeaderScope(Styles.SurfaceOptions, (uint)Expandable.SurfaceOptions, DrawSurfaceOptions);
if (filter.HasFlag(Expandable.SurfaceInputs))
m_MaterialScopeList.RegisterHeaderScope(Styles.SurfaceInputs, (uint)Expandable.SurfaceInputs, DrawSurfaceInputs);
if (filter.HasFlag(Expandable.Details))
FillAdditionalFoldouts(m_MaterialScopeList);
if (filter.HasFlag(Expandable.Advanced))
m_MaterialScopeList.RegisterHeaderScope(Styles.AdvancedLabel, (uint)Expandable.Advanced, DrawAdvancedOptions);
}
public void ShaderPropertiesGUI(Material material)
{
m_MaterialScopeList.DrawHeaders(materialEditor, material);
}
#endregion
////////////////////////////////////
// Drawing Functions //
////////////////////////////////////
#region DrawingFunctions
internal void DrawShaderGraphProperties(Material material, IEnumerable<MaterialProperty> properties)
{
if (properties == null)
return;
ShaderGraphPropertyDrawers.DrawShaderGraphGUI(materialEditor, properties);
}
internal static void DrawFloatToggleProperty(GUIContent styles, MaterialProperty prop)
{
if (prop == null)
return;
EditorGUI.BeginChangeCheck();
EditorGUI.showMixedValue = prop.hasMixedValue;
bool newValue = EditorGUILayout.Toggle(styles, prop.floatValue == 1);
if (EditorGUI.EndChangeCheck())
prop.floatValue = newValue ? 1.0f : 0.0f;
EditorGUI.showMixedValue = false;
}
public virtual void DrawSurfaceOptions(Material material)
{
DoPopup(Styles.surfaceType, surfaceTypeProp, Styles.surfaceTypeNames);
if ((surfaceTypeProp != null) && ((SurfaceType)surfaceTypeProp.floatValue == SurfaceType.Transparent))
DoPopup(Styles.blendingMode, blendModeProp, Styles.blendModeNames);
DoPopup(Styles.cullingText, cullingProp, Styles.renderFaceNames);
DoPopup(Styles.zwriteText, zwriteProp, Styles.zwriteNames);
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);
}
public virtual void DrawSurfaceInputs(Material material)
{
DrawBaseProperties(material);
}
public virtual void DrawAdvancedOptions(Material material)
{
// Only draw the sorting priority field if queue control is set to "auto"
bool autoQueueControl = GetAutomaticQueueControlSetting(material);
if (autoQueueControl)
DrawQueueOffsetField();
materialEditor.EnableInstancingField();
}
protected void DrawQueueOffsetField()
{
if (queueOffsetProp != null)
materialEditor.IntSliderShaderProperty(queueOffsetProp, -queueOffsetRange, queueOffsetRange, Styles.queueSlider);
}
public virtual void FillAdditionalFoldouts(MaterialHeaderScopeList materialScopesList) { }
public virtual void DrawBaseProperties(Material material)
{
if (baseMapProp != null && baseColorProp != null) // Draw the baseMap, most shader will have at least a baseMap
{
materialEditor.TexturePropertySingleLine(Styles.baseMap, baseMapProp, baseColorProp);
}
}
private void DrawEmissionTextureProperty()
{
if ((emissionMapProp == null) || (emissionColorProp == null))
return;
using (new EditorGUI.IndentLevelScope(2))
{
materialEditor.TexturePropertyWithHDRColor(Styles.emissionMap, emissionMapProp, emissionColorProp, false);
}
}
protected virtual void DrawEmissionProperties(Material material, bool keyword)
{
var emissive = true;
if (!keyword)
{
DrawEmissionTextureProperty();
}
else
{
emissive = materialEditor.EmissionEnabledProperty();
using (new EditorGUI.DisabledScope(!emissive))
{
DrawEmissionTextureProperty();
}
}
// If texture was assigned and color was black set color to white
if ((emissionMapProp != null) && (emissionColorProp != null))
{
var hadEmissionTexture = emissionMapProp?.textureValue != null;
var brightness = emissionColorProp.colorValue.maxColorComponent;
if (emissionMapProp.textureValue != null && !hadEmissionTexture && brightness <= 0f)
emissionColorProp.colorValue = Color.white;
}
if (emissive)
{
// Change the GI emission flag and fix it up with emissive as black if necessary.
materialEditor.LightmapEmissionFlagsProperty(MaterialEditor.kMiniTextureFieldLabelIndentLevel, true);
}
}
public static void DrawNormalArea(MaterialEditor materialEditor, MaterialProperty bumpMap, MaterialProperty bumpMapScale = null)
{
if (bumpMapScale != null)
{
materialEditor.TexturePropertySingleLine(Styles.normalMapText, bumpMap,
bumpMap.textureValue != null ? bumpMapScale : null);
if (bumpMapScale.floatValue != 1 &&
UnityEditorInternal.InternalEditorUtility.IsMobilePlatform(
EditorUserBuildSettings.activeBuildTarget))
if (materialEditor.HelpBoxWithButton(Styles.bumpScaleNotSupported, Styles.fixNormalNow))
bumpMapScale.floatValue = 1;
}
else
{
materialEditor.TexturePropertySingleLine(Styles.normalMapText, bumpMap);
}
}
protected static void DrawTileOffset(MaterialEditor materialEditor, MaterialProperty textureProp)
{
if (textureProp != null)
materialEditor.TextureScaleOffsetProperty(textureProp);
}
#endregion
////////////////////////////////////
// Material Data Functions //
////////////////////////////////////
#region MaterialDataFunctions
// this function is shared with ShaderGraph Lit/Unlit GUIs and also the hand-written GUIs
internal static void UpdateMaterialSurfaceOptions(Material material, bool automaticRenderQueue)
{
// Setup blending - consistent across all Universal RP shaders
SetupMaterialBlendModeInternal(material, out int renderQueue);
// apply automatic render queue
if (automaticRenderQueue && (renderQueue != material.renderQueue))
material.renderQueue = renderQueue;
bool isShaderGraph = material.IsShaderGraph();
// Cast Shadows
bool castShadows = true;
if (material.HasProperty(Property.CastShadows))
{
castShadows = (material.GetFloat(Property.CastShadows) != 0.0f);
}
else
{
if (isShaderGraph)
{
// Lit.shadergraph or Unlit.shadergraph, but no material control defined
// enable the pass in the material, so shader can decide...
castShadows = true;
}
else
{
// Lit.shader or Unlit.shader -- set based on transparency
castShadows = Rendering.Universal.ShaderGUI.LitGUI.IsOpaque(material);
}
}
material.SetShaderPassEnabled("ShadowCaster", castShadows);
// Receive Shadows
if (material.HasProperty(Property.ReceiveShadows))
CoreUtils.SetKeyword(material, ShaderKeywordStrings._RECEIVE_SHADOWS_OFF, material.GetFloat(Property.ReceiveShadows) == 0.0f);
}
// this function is shared between ShaderGraph and hand-written GUIs
internal static void UpdateMaterialRenderQueueControl(Material material)
{
//
// Render Queue Control handling
//
// Check for a raw render queue (the actual serialized setting - material.renderQueue has already been converted)
// setting of -1, indicating that the material property should be inherited from the shader.
// If we find this, add a new property "render queue control" set to 0 so we will
// always know to follow the surface type of the material (this matches the hand-written behavior)
// If we find another value, add the the property set to 1 so we will know that the
// user has explicitly selected a render queue and we should not override it.
//
bool isShaderGraph = material.IsShaderGraph(); // Non-shadergraph materials use automatic behavior
int rawRenderQueue = MaterialAccess.ReadMaterialRawRenderQueue(material);
if (!isShaderGraph || rawRenderQueue == -1)
{
material.SetFloat(Property.QueueControl, (float)QueueControl.Auto); // Automatic behavior - surface type override
}
else
{
material.SetFloat(Property.QueueControl, (float)QueueControl.UserOverride); // User has selected explicit render queue
}
}
internal static bool GetAutomaticQueueControlSetting(Material material)
{
// If a Shader Graph material doesn't yet have the queue control property,
// we should not engage automatic behavior until the shader gets reimported.
bool automaticQueueControl = !material.IsShaderGraph();
if (material.HasProperty(Property.QueueControl))
{
var queueControl = material.GetFloat(Property.QueueControl);
if (queueControl < 0.0f)
{
// The property was added with a negative value, indicating it needs to be validated for this material
UpdateMaterialRenderQueueControl(material);
}
automaticQueueControl = (material.GetFloat(Property.QueueControl) == (float)QueueControl.Auto);
}
return automaticQueueControl;
}
// this is the function used by Lit.shader, Unlit.shader GUIs
public static void SetMaterialKeywords(Material material, Action<Material> shadingModelFunc = null, Action<Material> shaderFunc = null)
{
UpdateMaterialSurfaceOptions(material, automaticRenderQueue: true);
// Setup double sided GI based on Cull state
if (material.HasProperty(Property.CullMode))
material.doubleSidedGI = (RenderFace)material.GetFloat(Property.CullMode) != RenderFace.Front;
// Temporary fix for lightmapping. TODO: to be replaced with attribute tag.
if (material.HasProperty("_MainTex"))
{
material.SetTexture("_MainTex", material.GetTexture("_BaseMap"));
material.SetTextureScale("_MainTex", material.GetTextureScale("_BaseMap"));
material.SetTextureOffset("_MainTex", material.GetTextureOffset("_BaseMap"));
}
if (material.HasProperty("_Color"))
material.SetColor("_Color", material.GetColor("_BaseColor"));
// Emission
if (material.HasProperty(Property.EmissionColor))
MaterialEditor.FixupEmissiveFlag(material);
bool shouldEmissionBeEnabled =
(material.globalIlluminationFlags & MaterialGlobalIlluminationFlags.EmissiveIsBlack) == 0;
// Not sure what this is used for, I don't see this property declared by any Unity shader in our repo...
// I'm guessing it is some kind of legacy material upgrade support thing? Or maybe just dead code now...
if (material.HasProperty("_EmissionEnabled") && !shouldEmissionBeEnabled)
shouldEmissionBeEnabled = material.GetFloat("_EmissionEnabled") >= 0.5f;
CoreUtils.SetKeyword(material, ShaderKeywordStrings._EMISSION, shouldEmissionBeEnabled);
// Normal Map
if (material.HasProperty("_BumpMap"))
CoreUtils.SetKeyword(material, ShaderKeywordStrings._NORMALMAP, material.GetTexture("_BumpMap"));
// Shader specific keyword functions
shadingModelFunc?.Invoke(material);
shaderFunc?.Invoke(material);
}
internal static void SetMaterialSrcDstBlendProperties(Material material, UnityEngine.Rendering.BlendMode srcBlend, UnityEngine.Rendering.BlendMode dstBlend)
{
if (material.HasProperty(Property.SrcBlend))
material.SetFloat(Property.SrcBlend, (float)srcBlend);
if (material.HasProperty(Property.DstBlend))
material.SetFloat(Property.DstBlend, (float)dstBlend);
}
internal static void SetMaterialZWriteProperty(Material material, bool zwriteEnabled)
{
if (material.HasProperty(Property.ZWrite))
material.SetFloat(Property.ZWrite, zwriteEnabled ? 1.0f : 0.0f);
}
internal static void SetupMaterialBlendModeInternal(Material material, out int automaticRenderQueue)
{
if (material == null)
throw new ArgumentNullException("material");
bool alphaClip = false;
if (material.HasProperty(Property.AlphaClip))
alphaClip = material.GetFloat(Property.AlphaClip) >= 0.5;
CoreUtils.SetKeyword(material, ShaderKeywordStrings._ALPHATEST_ON, alphaClip);
// default is to use the shader render queue
int renderQueue = material.shader.renderQueue;
material.SetOverrideTag("RenderType", ""); // clear override tag
if (material.HasProperty(Property.SurfaceType))
{
SurfaceType surfaceType = (SurfaceType)material.GetFloat(Property.SurfaceType);
bool zwrite = false;
CoreUtils.SetKeyword(material, ShaderKeywordStrings._SURFACE_TYPE_TRANSPARENT, surfaceType == SurfaceType.Transparent);
if (surfaceType == SurfaceType.Opaque)
{
if (alphaClip)
{
renderQueue = (int)RenderQueue.AlphaTest;
material.SetOverrideTag("RenderType", "TransparentCutout");
}
else
{
renderQueue = (int)RenderQueue.Geometry;
material.SetOverrideTag("RenderType", "Opaque");
}
SetMaterialSrcDstBlendProperties(material, UnityEngine.Rendering.BlendMode.One, UnityEngine.Rendering.BlendMode.Zero);
zwrite = true;
material.DisableKeyword(ShaderKeywordStrings._ALPHAPREMULTIPLY_ON);
material.DisableKeyword(ShaderKeywordStrings._SURFACE_TYPE_TRANSPARENT);
}
else // SurfaceType Transparent
{
BlendMode blendMode = (BlendMode)material.GetFloat(Property.BlendMode);
// Specific Transparent Mode Settings
switch (blendMode)
{
case BlendMode.Alpha:
SetMaterialSrcDstBlendProperties(material,
UnityEngine.Rendering.BlendMode.SrcAlpha,
UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
material.DisableKeyword(ShaderKeywordStrings._ALPHAPREMULTIPLY_ON);
break;
case BlendMode.Premultiply:
SetMaterialSrcDstBlendProperties(material,
UnityEngine.Rendering.BlendMode.One,
UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
material.EnableKeyword(ShaderKeywordStrings._ALPHAPREMULTIPLY_ON);
break;
case BlendMode.Additive:
SetMaterialSrcDstBlendProperties(material,
UnityEngine.Rendering.BlendMode.SrcAlpha,
UnityEngine.Rendering.BlendMode.One);
material.DisableKeyword(ShaderKeywordStrings._ALPHAPREMULTIPLY_ON);
break;
case BlendMode.Multiply:
SetMaterialSrcDstBlendProperties(material,
UnityEngine.Rendering.BlendMode.DstColor,
UnityEngine.Rendering.BlendMode.Zero);
material.DisableKeyword(ShaderKeywordStrings._ALPHAPREMULTIPLY_ON);
material.EnableKeyword(ShaderKeywordStrings._ALPHAMODULATE_ON);
break;
}
// General Transparent Material Settings
material.SetOverrideTag("RenderType", "Transparent");
zwrite = false;
material.EnableKeyword(ShaderKeywordStrings._SURFACE_TYPE_TRANSPARENT);
renderQueue = (int)RenderQueue.Transparent;
}
// check for override enum
if (material.HasProperty(Property.ZWriteControl))
{
var zwriteControl = (UnityEditor.Rendering.Universal.ShaderGraph.ZWriteControl)material.GetFloat(Property.ZWriteControl);
if (zwriteControl == UnityEditor.Rendering.Universal.ShaderGraph.ZWriteControl.ForceEnabled)
zwrite = true;
else if (zwriteControl == UnityEditor.Rendering.Universal.ShaderGraph.ZWriteControl.ForceDisabled)
zwrite = false;
}
SetMaterialZWriteProperty(material, zwrite);
material.SetShaderPassEnabled("DepthOnly", zwrite);
}
else
{
// no surface type property -- must be hard-coded by the shadergraph,
// so ensure the pass is enabled at the material level
material.SetShaderPassEnabled("DepthOnly", true);
}
// must always apply queue offset, even if not set to material control
if (material.HasProperty(Property.QueueOffset))
renderQueue += (int)material.GetFloat(Property.QueueOffset);
automaticRenderQueue = renderQueue;
}
public static void SetupMaterialBlendMode(Material material)
{
SetupMaterialBlendModeInternal(material, out int renderQueue);
// apply automatic render queue
if (renderQueue != material.renderQueue)
material.renderQueue = renderQueue;
}
public override void AssignNewShaderToMaterial(Material material, Shader oldShader, Shader newShader)
{
// Clear all keywords for fresh start
// Note: this will nuke user-selected custom keywords when they change shaders
material.shaderKeywords = null;
base.AssignNewShaderToMaterial(material, oldShader, newShader);
// Setup keywords based on the new shader
UpdateMaterial(material, MaterialUpdateType.ChangedAssignedShader);
}
#endregion
////////////////////////////////////
// Helper Functions //
////////////////////////////////////
#region HelperFunctions
public static void TwoFloatSingleLine(GUIContent title, MaterialProperty prop1, GUIContent prop1Label,
MaterialProperty prop2, GUIContent prop2Label, MaterialEditor materialEditor, float labelWidth = 30f)
{
const int kInterFieldPadding = 2;
Rect rect = EditorGUILayout.GetControlRect();
EditorGUI.PrefixLabel(rect, title);
var indent = EditorGUI.indentLevel;
var preLabelWidth = EditorGUIUtility.labelWidth;
EditorGUI.indentLevel = 0;
EditorGUIUtility.labelWidth = labelWidth;
Rect propRect1 = new Rect(rect.x + preLabelWidth, rect.y,
(rect.width - preLabelWidth) * 0.5f - 1, EditorGUIUtility.singleLineHeight);
EditorGUI.BeginChangeCheck();
EditorGUI.showMixedValue = prop1.hasMixedValue;
var prop1val = EditorGUI.FloatField(propRect1, prop1Label, prop1.floatValue);
if (EditorGUI.EndChangeCheck())
prop1.floatValue = prop1val;
Rect propRect2 = new Rect(propRect1.x + propRect1.width + kInterFieldPadding, rect.y,
propRect1.width, EditorGUIUtility.singleLineHeight);
EditorGUI.BeginChangeCheck();
EditorGUI.showMixedValue = prop2.hasMixedValue;
var prop2val = EditorGUI.FloatField(propRect2, prop2Label, prop2.floatValue);
if (EditorGUI.EndChangeCheck())
prop2.floatValue = prop2val;
EditorGUI.indentLevel = indent;
EditorGUIUtility.labelWidth = preLabelWidth;
EditorGUI.showMixedValue = false;
}
public void DoPopup(GUIContent label, MaterialProperty property, string[] options)
{
if (property != null)
materialEditor.PopupShaderProperty(property, label, options);
}
// Helper to show texture and color properties
public static Rect TextureColorProps(MaterialEditor materialEditor, GUIContent label, MaterialProperty textureProp, MaterialProperty colorProp, bool hdr = false)
{
Rect rect = EditorGUILayout.GetControlRect();
EditorGUI.showMixedValue = textureProp.hasMixedValue;
materialEditor.TexturePropertyMiniThumbnail(rect, textureProp, label.text, label.tooltip);
EditorGUI.showMixedValue = false;
if (colorProp != null)
{
EditorGUI.BeginChangeCheck();
EditorGUI.showMixedValue = colorProp.hasMixedValue;
int indentLevel = EditorGUI.indentLevel;
EditorGUI.indentLevel = 0;
Rect rectAfterLabel = new Rect(rect.x + EditorGUIUtility.labelWidth, rect.y,
EditorGUIUtility.fieldWidth, EditorGUIUtility.singleLineHeight);
var col = EditorGUI.ColorField(rectAfterLabel, GUIContent.none, colorProp.colorValue, true,
false, hdr);
EditorGUI.indentLevel = indentLevel;
if (EditorGUI.EndChangeCheck())
{
materialEditor.RegisterPropertyChangeUndo(colorProp.displayName);
colorProp.colorValue = col;
}
EditorGUI.showMixedValue = false;
}
return rect;
}
// Copied from shaderGUI as it is a protected function in an abstract class, unavailable to others
public new static MaterialProperty FindProperty(string propertyName, MaterialProperty[] properties)
{
return FindProperty(propertyName, properties, true);
}
// Copied from shaderGUI as it is a protected function in an abstract class, unavailable to others
public new static MaterialProperty FindProperty(string propertyName, MaterialProperty[] properties, bool propertyIsMandatory)
{
for (int index = 0; index < properties.Length; ++index)
{
if (properties[index] != null && properties[index].name == propertyName)
return properties[index];
}
if (propertyIsMandatory)
throw new ArgumentException("Could not find MaterialProperty: '" + propertyName + "', Num properties: " + (object)properties.Length);
return null;
}
#endregion
}
}

View file

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: faa1af574d7a1e94a89f04dbe126d52f
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5faac1f019b9d88418c3721b7845b4d2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,86 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
using UnityEngine.UIElements;
using UnityEditor.UIElements;
namespace UnityEditor
{
public class EnumFieldUtils : MonoBehaviour
{
public class EnumData
{
public Enum[] values;
public int[] flagValues;
public string[] displayNames;
public string[] names;
public string[] tooltip;
public bool flags;
public Type underlyingType;
public bool unsigned;
public bool serializable;
}
static FieldInfo s_EnumDataField;
public static FieldInfo enumDataField
{
get
{
if (s_EnumDataField == null)
{
s_EnumDataField = typeof(EnumField).GetField("m_EnumData", BindingFlags.Instance | BindingFlags.NonPublic);
}
return s_EnumDataField;
}
}
static FieldInfo s_values;
static FieldInfo s_flagValues;
static FieldInfo s_displayNames;
static FieldInfo s_names;
static FieldInfo s_tooltip;
static void InitializeFields()
{
Type enumType = enumDataField.FieldType;
s_values = enumType.GetField("values", BindingFlags.Instance | BindingFlags.Public);
s_flagValues = enumType.GetField("flagValues", BindingFlags.Instance | BindingFlags.Public);
s_displayNames = enumType.GetField("displayNames", BindingFlags.Instance | BindingFlags.Public);
s_names = enumType.GetField("names", BindingFlags.Instance | BindingFlags.Public);
s_tooltip = enumType.GetField("tooltip", BindingFlags.Instance | BindingFlags.Public);
}
public static object GetBoxedEnumData(EnumData enumData)
{
if (s_values == null)
{
InitializeFields();
}
Type enumType = enumDataField.FieldType;
object s_BoxedEnumData = Activator.CreateInstance(enumType);
s_values.SetValue(s_BoxedEnumData, enumData.values);
s_flagValues.SetValue(s_BoxedEnumData, enumData.flagValues);
s_displayNames.SetValue(s_BoxedEnumData, enumData.displayNames);
s_names.SetValue(s_BoxedEnumData, enumData.names);
s_tooltip.SetValue(s_BoxedEnumData, enumData.tooltip);
return s_BoxedEnumData;
}
static Action<EnumField, Enum> s_UpdateValueLabelAction;
public static Action<EnumField, Enum> UpdateValueLabelAction
{
get
{
if (s_UpdateValueLabelAction == null)
{
MethodInfo updateValueInfo = typeof(EnumField).GetMethod("UpdateValueLabel", BindingFlags.Instance | BindingFlags.NonPublic);
s_UpdateValueLabelAction = (Action<EnumField, Enum>)updateValueInfo.CreateDelegate(typeof(Action<EnumField, Enum>));
}
return s_UpdateValueLabelAction;
}
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d01dcc398770dc44f863c389ddfa01d0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,13 @@
using SLZ.SLZEditorTools;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
public class ForceReloadDrawer : MaterialPropertyDrawer
{
public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor)
{
ShaderGUIUtils.ForceRebuild(editor);
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 34c606745ae9ccb4bb0c7a630eb88ecf
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 03e55040d94ce7448bb143a63b1e201a
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,726 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine.UIElements;
using UnityEngine.Rendering;
using Object = UnityEngine.Object;
using Unity.Collections.LowLevel.Unsafe;
using System.Reflection;
using SLZ.SLZEditorTools;
using UnityEditor.SLZMaterialUI;
using System.Linq;
using System.Runtime.CompilerServices;
using static UnityEngine.Rendering.DebugUI.MessageBox;
using UnityEditor.ShaderGraph;
namespace UnityEditor // This MUST be in the base editor namespace!!!!!
{
[CanEditMultipleObjects]
public class LitMASGUI : UIElementsMaterialEditor
{
const string keyword_DETAILS_ON = "_DETAILS_ON";
const string keyword_BRDF = "_BRDFMAP";
const string keyword_EXPENSIVE_TP = "_EXPENSIVE_TP";
const string defaultMASGUID = "75f1fbacfa73385419ec8d7700a107ea";
static string s_defaultMASPath;
static string defaultMASPath
{
get
{
if (s_defaultMASPath == null)
{
s_defaultMASPath = AssetDatabase.GUIDToAssetPath(defaultMASGUID);
}
return s_defaultMASPath;
}
}
enum PName
{
_BaseMap = 0,
_BaseColor,
_MetallicGlossMap,
_Normals,
_BumpMap,
_Emission,
_EmissionMap,
_EmissionColor,
_EmissionFalloff,
_BakedMutiplier,
_Details,
_DetailMap,
g_tBRDFMap,
BRDFMAP,
_HitRamp,
_HitColor,
// Rendering properties
_Surface,
_BlendSrc,
_BlendDst,
_ZWrite,
_Cull,
// Triplanar properties
_Expensive,
_RotateUVs,
_DetailsuseLocalUVs,
_UVScaler,
}
static ReadOnlySpan<string> propertyNames => new string[] {
"_BaseMap",
"_BaseColor",
"_MetallicGlossMap",
"_Normals",
"_BumpMap",
"_Emission",
"_EmissionMap",
"_EmissionColor",
"_EmissionFalloff",
"_BakedMutiplier",
"_Details",
"_DetailMap",
"g_tBRDFMap",
"BRDFMAP",
"_HitRamp",
"_HitColor",
// Rendering properties
"_Surface",
"_BlendSrc",
"_BlendDst",
"_ZWrite",
"_Cull",
// Triplanar properties
"_Expensive",
"_RotateUVs",
"_DetailsuseLocalUVs",
"_UVScaler",
};
class ShaderPropertyTable
{
public int[] nameToPropIdx;
//public int _BaseMap = -1;
//public int _BaseColor = -1;
//public int _Normals = -1;
//public int _MetallicGlossMap = -1;
//public int _Emission = -1;
//public int _EmissionMap = -1;
//public int _EmissionColor = -1;
//public int _EmissionFalloff = -1;
//public int _BakedMutiplier = -1;
//public int _Details = -1;
//public int _DetailMap = -1;
//public int _SSROff = -1;
//public int _SSRTemporalMul = -1;
public List<int> unknownProperties;
public int texturePropertyCount;
}
public override VisualElement CreateInspectorGUI()
{
Debug.Log("Added Visual Element?");
VisualElement root = new VisualElement();
VisualElement MainWindow = new VisualElement();
root.Add(MainWindow);
bool success = base.Initialize(root,MainWindow);
if (!success)
{
return null;
}
MainWindow.styleSheets.Add(ShaderGUIUtils.shaderGUISheet);
MaterialProperty[] props = materialProperties;
int[] propIdx = ShaderGUIUtils.GetMaterialPropertyShaderIdx(props, base.shader);
ShaderImporter shaderImporter = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(base.shader)) as ShaderImporter;
//ShaderGUIUtils.SanitizeMaterials(this.targets, props, propIdx, shader);
ShaderPropertyTable propTable = GetPropertyTable(props);
materialFields = new List<BaseMaterialField>(props.Length + propTable.texturePropertyCount + 5); // Scale/offsets are separate fields, double the number of texture properties
//int currentFieldIdx = 0;
//----------------------------------------------------------------
// Rendering Properties ------------------------------------------
//----------------------------------------------------------------
Foldout drawProps = new Foldout();
{
//drawProps.value = false;
RenderQueueDropdown renderQueue = new RenderQueueDropdown(serializedObject, shader);
int surfaceIdx = PropertyIdx(ref propTable, PName._Surface);
int blendSrcIdx = PropertyIdx(ref propTable, PName._BlendSrc);
int blendDstIdx = PropertyIdx(ref propTable, PName._BlendDst);
int zWriteIdx = PropertyIdx(ref propTable, PName._ZWrite);
if (surfaceIdx != -1 && blendSrcIdx != -1 && blendDstIdx != -1 && zWriteIdx != -1)
{
MaterialDummyField blendSrcField = new MaterialDummyField(props[blendSrcIdx], propIdx[blendSrcIdx]);
MaterialDummyField blendDstField = new MaterialDummyField(props[blendDstIdx], propIdx[blendDstIdx]);
MaterialDummyField zWriteField = new MaterialDummyField(props[zWriteIdx], propIdx[zWriteIdx]);
materialFields.Add(blendSrcField);
materialFields.Add(blendDstField);
materialFields.Add(zWriteField);
SurfaceTypeField surfaceTypeField = new SurfaceTypeField();
surfaceTypeField.Initialize(
props[surfaceIdx],
propIdx[surfaceIdx],
blendSrcField,
blendDstField,
zWriteField,
renderQueue
);
surfaceTypeField.tooltip = LitMASGui_Tooltips.Surface.ToString();
materialFields.Add(surfaceTypeField);
drawProps.contentContainer.Add(surfaceTypeField);
}
int cullIdx = PropertyIdx(ref propTable, PName._Cull);
if (cullIdx != -1)
{
List<int> cullChoices = new List<int>() { (int)CullMode.Back, (int)CullMode.Front, (int)CullMode.Off};
Dictionary<int, string> cullLabels = new Dictionary<int, string>() { { (int)CullMode.Back, "Front" }, { (int)CullMode.Front, "Back" }, { (int)CullMode.Off, "Both (EXPENSIVE)" } };
MaterialIntPopup cullPopup = new MaterialIntPopup();
cullPopup.label = "Rendered Side";
cullPopup.Initialize(props[cullIdx], propIdx[cullIdx], cullChoices, cullLabels);
materialFields.Add(cullPopup);
drawProps.contentContainer.Add(cullPopup);
}
drawProps.contentContainer.Add(renderQueue);
}
MainWindow.Add(drawProps);
//----------------------------------------------------------------
// Core Properties -----------------------------------------------
//----------------------------------------------------------------
Foldout baseProps = new Foldout();
Texture2D MaterialIcon = ShaderGUIUtils.GetClosestUnityIconMip("Material Icon", 16);
ShaderGUIUtils.SetHeaderStyle(baseProps, "Core Shading", MaterialIcon);
bool hasCoreProperty = false;
// Base Map ------------------------------------------------------
TextureField baseMapField = null;
int baseMapIdx = PropertyIdx(ref propTable, PName._BaseMap);
if (baseMapIdx != -1)
{
baseMapField = new TextureField(props[baseMapIdx], propIdx[baseMapIdx], false);
baseMapField.tooltip2 = LitMASGui_Tooltips.BaseMap.ToString();
baseProps.Add(baseMapField);
materialFields.Add(baseMapField);
hasCoreProperty = true;
}
// Base Color ----------------------------------------------------
int baseColorIdx = PropertyIdx(ref propTable, PName._BaseColor);
if (baseColorIdx != -1)
{
MaterialColorField baseColorField = new MaterialColorField();
if (baseMapField != null)
{
baseColorField.Initialize(props[baseColorIdx], propIdx[baseColorIdx], true);
baseMapField.rightAlignBox.Add(baseColorField);
}
else
{
baseColorField.Initialize(props[baseColorIdx], propIdx[baseColorIdx], false);
baseProps.Add(baseColorField);
}
baseColorField.tooltip = LitMASGui_Tooltips.BaseColor.ToString();
materialFields.Add(baseColorField);
hasCoreProperty = true;
}
// MAS Map -------------------------------------------------------
int MASMapIdx = PropertyIdx(ref propTable, PName._MetallicGlossMap);
if (MASMapIdx != -1)
{
Texture2D defaultMAS = AssetDatabase.LoadAssetAtPath<Texture2D>(defaultMASPath);
TextureField MASMap = new TextureField(props[MASMapIdx], propIdx[MASMapIdx], false, shaderImporter?.GetDefaultTexture(props[MASMapIdx].name));
MASMap.tooltip2 = LitMASGui_Tooltips.MASMap.ToString();
baseProps.Add(MASMap);
materialFields.Add(MASMap);
hasCoreProperty = true;
MAS_defaultSlider defaultSlider = new MAS_defaultSlider(MASMap);
MASMap.rightAlignBox.Add(defaultSlider);
}
// Normal Map ----------------------------------------------------
int NormalMapIdx = PropertyIdx(ref propTable, PName._BumpMap);
if (NormalMapIdx != -1)
{
TextureField NormalMap = new TextureField(props[NormalMapIdx], propIdx[NormalMapIdx], true);
NormalMap.tooltip2 = LitMASGui_Tooltips.NormalMap.ToString();
baseProps.Add(NormalMap);
materialFields.Add(NormalMap);
int NormalsIdx = PropertyIdx(ref propTable, PName._Normals);
if (NormalsIdx != -1)
{
NormalMap.leftAlignBox.SetEnabled(props[NormalsIdx].floatValue > 0.0);
MaterialToggleField normalToggle = new MaterialToggleField();
normalToggle.Initialize(props[NormalsIdx], propIdx[NormalsIdx], null, false, true);
normalToggle.RegisterValueChangedCallback(evt => NormalMap.leftAlignBox.SetEnabled(evt.newValue));
NormalMap.rightAlignBox.Add(normalToggle);
materialFields.Add(normalToggle);
}
hasCoreProperty = true;
}
int BRDFRampIdx = PropertyIdx(ref propTable, PName.g_tBRDFMap);
if(BRDFRampIdx != -1)
{
TextureField BRDFRamp = new TextureField(props[BRDFRampIdx], propIdx[BRDFRampIdx], false);
//NormalMap.tooltip2 = LitMASGui_Tooltips.NormalMap.ToString();
baseProps.Add(BRDFRamp);
materialFields.Add(BRDFRamp);
int BRDFRampToggleIdx = PropertyIdx(ref propTable, PName.BRDFMAP);
if (BRDFRampToggleIdx != -1)
{
BRDFRamp.leftAlignBox.SetEnabled(props[BRDFRampToggleIdx].floatValue > 0.0);
MaterialToggleField BRDFRampToggle = new MaterialToggleField();
BRDFRampToggle.Initialize(props[BRDFRampToggleIdx], propIdx[BRDFRampToggleIdx], keyword_BRDF, false, true);
BRDFRampToggle.RegisterValueChangedCallback(evt => BRDFRamp.leftAlignBox.SetEnabled(evt.newValue));
BRDFRamp.rightAlignBox.Add(BRDFRampToggle);
materialFields.Add(BRDFRampToggle);
}
hasCoreProperty = true;
}
// Triplanar options ---------------------------------------------
int fixSeamsIdx = PropertyIdx(ref propTable, PName._Expensive);
if (fixSeamsIdx != -1)
{
MaterialToggleField seamToggle = new MaterialToggleField();
seamToggle.Initialize(props[fixSeamsIdx], propIdx[fixSeamsIdx], keyword_EXPENSIVE_TP, false);
materialFields.Add(seamToggle);
baseProps.Add(seamToggle);
}
int rotateUVsIdx = PropertyIdx(ref propTable, PName._RotateUVs);
if (rotateUVsIdx != -1)
{
MaterialToggleField rotateUVsToggle = new MaterialToggleField();
rotateUVsToggle.Initialize(props[rotateUVsIdx], propIdx[rotateUVsIdx], null, false);
materialFields.Add(rotateUVsToggle);
baseProps.Add(rotateUVsToggle);
}
int triplanarScaleIdx = PropertyIdx(ref propTable, PName._UVScaler);
if (triplanarScaleIdx != -1)
{
MaterialFloatField triplanarScaleField = new MaterialFloatField();
triplanarScaleField.Initialize(props[triplanarScaleIdx], propIdx[triplanarScaleIdx]);
materialFields.Add(triplanarScaleField);
baseProps.Add(triplanarScaleField);
}
// Base map tiling offset ----------------------------------------
if (baseMapIdx != -1 && (props[baseMapIdx].flags & MaterialProperty.PropFlags.NoScaleOffset) == 0)
{
MaterialScaleOffsetField baseScaleOffsetField = new MaterialScaleOffsetField(props[baseMapIdx], propIdx[baseMapIdx]);
baseProps.Add(baseScaleOffsetField);
materialFields.Add(baseScaleOffsetField);
}
if (hasCoreProperty)
{
Texture2D RTIcon = ShaderGUIUtils.GetClosestUnityIconMip("RenderTexture Icon", 16);
ShaderGUIUtils.SetHeaderStyle(drawProps, "Rendering Properties", RTIcon);
MainWindow.Add(baseProps);
}
//----------------------------------------------------------------
// Emission Properties -------------------------------------------
//----------------------------------------------------------------
Toggle emissionToggle = null;
Foldout emissionProps = new Foldout();
bool hasEmissionProperty = false;
// Emission Map --------------------------------------------------
TextureField emissionMapField = null;
int emissionMapIdx = PropertyIdx(ref propTable, PName._EmissionMap);
if (emissionMapIdx != -1)
{
emissionMapField = new TextureField(props[emissionMapIdx], propIdx[emissionMapIdx], false);
emissionMapField.tooltip2 = LitMASGui_Tooltips.EmissionMap.ToString();
emissionProps.Add(emissionMapField);
materialFields.Add(emissionMapField);
hasEmissionProperty = true;
}
int emissionColorIdx = PropertyIdx(ref propTable, PName._EmissionColor);
if (emissionColorIdx != -1)
{
MaterialColorField emissionColorField = new MaterialColorField();
emissionColorField.hdr = true;
if (emissionMapIdx != -1)
{
emissionColorField.Initialize(props[emissionColorIdx], propIdx[emissionColorIdx], true);
emissionMapField.rightAlignBox.Add(emissionColorField);
}
else
{
emissionColorField.Initialize(props[emissionColorIdx], propIdx[emissionColorIdx], false);
emissionProps.Add(emissionColorField);
}
emissionColorField.tooltip = LitMASGui_Tooltips.EmissionColor.ToString();
materialFields.Add(emissionColorField);
hasEmissionProperty = true;
}
int emissionFalloffIdx = PropertyIdx(ref propTable, PName._EmissionFalloff);
if (emissionFalloffIdx != -1)
{
MaterialFloatField emissionFalloffField = new MaterialFloatField();
emissionFalloffField.Initialize(props[emissionFalloffIdx], propIdx[emissionFalloffIdx]);
emissionProps.Add(emissionFalloffField);
emissionFalloffField.tooltip = LitMASGui_Tooltips.EmissionFalloff.ToString();
materialFields.Add(emissionFalloffField);
hasEmissionProperty = true;
}
int emissionMultiplierIdx = PropertyIdx(ref propTable, PName._BakedMutiplier);
if (emissionMultiplierIdx != -1)
{
MaterialFloatField emissionMultiplierField = new MaterialFloatField();
emissionMultiplierField.Initialize(props[emissionMultiplierIdx], propIdx[emissionMultiplierIdx]);
emissionProps.Add(emissionMultiplierField);
emissionMultiplierField.tooltip = LitMASGui_Tooltips.EmissionFalloff.ToString();
materialFields.Add(emissionMultiplierField);
hasEmissionProperty = true;
}
int emissionToggleIdx = PropertyIdx(ref propTable, PName._Emission);
EmissionToggleField emissionMatToggle = null;
if (emissionToggleIdx != -1)
{
emissionMatToggle = new EmissionToggleField();
emissionMatToggle.Initialize(props[emissionToggleIdx], propIdx[emissionToggleIdx], null, false, true);
emissionMatToggle.RegisterCallback<ChangeEvent<bool>>(evt => { emissionProps.contentContainer.SetEnabled(evt.newValue); });
emissionToggle = emissionMatToggle;
materialFields.Add(emissionMatToggle);
hasEmissionProperty = true;
bool emissionEnabled = props[emissionToggleIdx].floatValue > 0.0f;
emissionProps.contentContainer.SetEnabled(emissionEnabled);
}
if (hasEmissionProperty)
{
GIFlagsPopup emissionFlags = new GIFlagsPopup(serializedObject);
emissionProps.Add(emissionFlags);
Toggle doubleSidedGIToggle = new Toggle("Double Sided GI");
SetAlignStyle(doubleSidedGIToggle);
doubleSidedGIToggle.bindingPath = "m_DoubleSidedGI";
emissionProps.Add(doubleSidedGIToggle);
Texture2D LightIcon = ShaderGUIUtils.GetClosestUnityIconMip("Light Icon", 16);
ShaderGUIUtils.SetHeaderStyle(emissionProps, "Emission", LightIcon, emissionToggle);
MainWindow.Add(emissionProps);
}
//----------------------------------------------------------------
// Detail Properties ---------------------------------------------
//----------------------------------------------------------------
Toggle detailToggle = null;
Foldout detailProps = new Foldout();
bool hasDetails = false;
int detailMapIdx = PropertyIdx(ref propTable, PName._DetailMap);
if (detailMapIdx != -1)
{
TextureField detailsMapField = new TextureField(props[detailMapIdx], propIdx[detailMapIdx], false, shaderImporter?.GetDefaultTexture(props[detailMapIdx].name));
detailsMapField.tooltip2 = LitMASGui_Tooltips.DetailMap.ToString();
detailProps.Add(detailsMapField);
materialFields.Add(detailsMapField);
hasDetails = true;
MaterialScaleOffsetField detailScaleOffset = new MaterialScaleOffsetField(props[detailMapIdx], propIdx[detailMapIdx]);
detailProps.Add(detailScaleOffset);
materialFields.Add(detailScaleOffset);
}
int detailToggleIdx = PropertyIdx(ref propTable, PName._Details);
if (detailToggleIdx != -1 && hasDetails)
{
MaterialToggleField detailMatToggle = new MaterialToggleField();
detailMatToggle.Initialize(props[detailToggleIdx], propIdx[detailToggleIdx], keyword_DETAILS_ON, false, true);
detailMatToggle.RegisterCallback<ChangeEvent<bool>>(evt => { detailProps.contentContainer.SetEnabled(evt.newValue); });
bool detailEnabled = props[detailToggleIdx].floatValue > 0.0f;
detailProps.contentContainer.SetEnabled(detailEnabled);
materialFields.Add(detailMatToggle);
detailToggle = detailMatToggle;
}
if (hasDetails)
{
Texture2D detailIcon = ShaderGUIUtils.GetClosestUnityIconMip("Grid Icon", 16);
ShaderGUIUtils.SetHeaderStyle(detailProps, "Details", detailIcon, detailToggle);
MainWindow.Add(detailProps);
}
//----------------------------------------------------------------
// Impact Properties --------------------------------------------
//----------------------------------------------------------------
Foldout ImpactProps = new Foldout();
bool hasImpacts = false;
int hitRampIdx = PropertyIdx(ref propTable, PName._HitRamp);
TextureField hitRamp = null;
if (hitRampIdx != -1)
{
hitRamp = new TextureField(props[hitRampIdx], propIdx[hitRampIdx], false);
ImpactProps.Add(hitRamp);
materialFields.Add(hitRamp);
hasImpacts = true;
}
int hitColorIdx = PropertyIdx(ref propTable, PName._HitColor);
if (hitRampIdx != -1)
{
MaterialColorField hitColorField = new MaterialColorField();
hitColorField.hdr = true;
if (hitColorIdx != -1)
{
hitColorField.Initialize(props[hitColorIdx], propIdx[hitColorIdx], true);
hitRamp.rightAlignBox.Add(hitColorField);
}
else
{
hitColorField.Initialize(props[emissionColorIdx], propIdx[emissionColorIdx], false);
ImpactProps.Add(hitColorField);
}
hitColorField.tooltip = LitMASGui_Tooltips.EmissionColor.ToString();
materialFields.Add(hitColorField);
hasImpacts = true;
}
if (hasImpacts)
{
Texture2D impactIcon = ShaderGUIUtils.GetClosestUnityIconMip("RaycastCollider Icon", 16);
ShaderGUIUtils.SetHeaderStyle(ImpactProps, "Impacts", impactIcon);
MainWindow.Add(ImpactProps);
}
//----------------------------------------------------------------
// Unknown Properties --------------------------------------------
//----------------------------------------------------------------
Foldout unknownProps = new Foldout();
Texture2D otherIcon = ShaderGUIUtils.GetClosestUnityIconMip("Settings Icon", 16);
ShaderGUIUtils.SetHeaderStyle(unknownProps, "Other", otherIcon);
int numUnknown = propTable.unknownProperties.Count;
List<int> unknownPropIdx = propTable.unknownProperties;
for (int i = 0; i < numUnknown; i++)
{
MaterialProperty prop = props[unknownPropIdx[i]];
int shaderIdx = propIdx[unknownPropIdx[i]];
if ((prop.flags & MaterialProperty.PropFlags.HideInInspector) != 0)
{
continue;
}
switch (prop.type)
{
case (MaterialProperty.PropType.Texture):
if ((prop.flags & MaterialProperty.PropFlags.NonModifiableTextureData) != 0) continue;
TextureField tf = new TextureField(prop, shaderIdx, (prop.flags & MaterialProperty.PropFlags.Normal) != 0, shaderImporter?.GetDefaultTexture(prop.name));
unknownProps.Add(tf);
materialFields.Add(tf);
if ((prop.flags & MaterialProperty.PropFlags.NoScaleOffset) == 0)
{
MaterialScaleOffsetField msof = new MaterialScaleOffsetField(prop, shaderIdx);
unknownProps.Add(msof);
materialFields.Add(msof);
}
break;
case (MaterialProperty.PropType.Color):
MaterialColorField cf = new MaterialColorField();
if ((prop.flags & MaterialProperty.PropFlags.HDR) != 0)
{
cf.hdr = true;
}
cf.Initialize(prop, shaderIdx, false);
unknownProps.Add(cf);
materialFields.Add(cf);
break;
case (MaterialProperty.PropType.Vector):
MaterialVectorField vf = new MaterialVectorField();
vf.Initialize(prop, shaderIdx);
unknownProps.Add(vf);
materialFields.Add(vf);
break;
case (MaterialProperty.PropType.Range):
if (shader.GetPropertyAttributes(shaderIdx).Contains("IntRange"))
{
MaterialIntRangeField irf = new MaterialIntRangeField();
irf.Initialize(prop, shaderIdx);
unknownProps.Add(irf);
materialFields.Add(irf);
}
else
{
MaterialRangeField rf = new MaterialRangeField();
rf.Initialize(prop, shaderIdx);
unknownProps.Add(rf);
materialFields.Add(rf);
}
break;
case (MaterialProperty.PropType.Float):
string[] attributes = shader.GetPropertyAttributes(shaderIdx);
string keyword;
if (HasToggleAttribute(attributes, out keyword))
{
MaterialToggleField tgf = new MaterialToggleField();
tgf.Initialize(prop, shaderIdx, keyword, false);
unknownProps.Add(tgf);
materialFields.Add(tgf);
}
else
{
MaterialFloatField ff = new MaterialFloatField();
ff.Initialize(prop, shaderIdx);
unknownProps.Add(ff);
materialFields.Add(ff);
}
break;
case (MaterialProperty.PropType.Int):
MaterialIntField inf = new MaterialIntField();
inf.Initialize(prop, shaderIdx);
unknownProps.Add(inf);
materialFields.Add(inf);
break;
}
}
if (numUnknown > 0)
{
MainWindow.Add(unknownProps);
}
return root;
}
static char[] attributeSeparators = new char[2] { '(', ')' };
bool HasToggleAttribute(string[] attributes, out string keyword)
{
int numAttr = attributes.Length;
for (int i = 0; i < numAttr; i++)
{
if (attributes[i].StartsWith("Toggle"))
{
if (attributes[i].Equals("ToggleUI"))
{
keyword = null;
}
else
{
// Debug.Log(attributes[i]);
string[] split = attributes[i].Split(attributeSeparators);
keyword = split[1];
}
return true;
}
}
keyword = null;
return false;
}
private ShaderPropertyTable GetPropertyTable(MaterialProperty[] props)
{
int numProps = props.Length;
int numNames = propertyNames.Length;
ShaderPropertyTable output = new ShaderPropertyTable();
int[] nameToPropIdx = new int[numNames];
output.nameToPropIdx = nameToPropIdx;
for (int i = 0; i < numNames; i++) nameToPropIdx[i] = -1;
output.unknownProperties = new List<int>(numProps);
for (int propIdx = 0; propIdx < numProps; propIdx++)
{
if (props[propIdx].type == MaterialProperty.PropType.Texture) output.texturePropertyCount++;
bool unknown = true;
string propName = props[propIdx].name;
for (int nameIdx = 0; nameIdx < numNames; nameIdx++)
{
if (nameToPropIdx[nameIdx] == -1 && string.Equals(propertyNames[nameIdx], propName))
{
nameToPropIdx[nameIdx] = propIdx;
unknown = false;
break;
}
}
if (unknown)
{
output.unknownProperties.Add(propIdx);
}
}
return output;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static int PropertyIdx(ref ShaderPropertyTable table, PName name)
{
return table.nameToPropIdx[(int)name];
}
static void SetAlignStyle(VisualElement vi)
{
VisualElement left = vi.ElementAt(0);
left.AddToClassList("materialGUILeftBox");
left.style.overflow = Overflow.Hidden;
left.style.minWidth = 0;
VisualElement right = vi.ElementAt(1);
right.AddToClassList("materialGUIRightBox");
vi.style.justifyContent = Justify.FlexStart;
vi.style.marginRight = 3;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 30e0cd503f4520e40808615cd58eaafc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,52 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace SLZ.SLZEditorTools
{
internal static class LitMASGui_Tooltips
{
public static ReadOnlySpan<char> BaseMap =>
"Base Color (RGB).\nThe color of the material. When the material is metallic, this also tints the reflections";
public static ReadOnlySpan<char> BaseColor =>
"Base color, tints the albedo map";
public static ReadOnlySpan<char> MASMap =>
"Metallic (R), Ambient Occlusion (G), Smoothness (B).\nThe metallic controls how reflective the surface is and how much the albedo tints reflections. " +
"Ambient occlusion is fake pre-baked shadows that darkens areas like crevices or creases which are likely to be shadowed by surface itself. " +
"Smoothness controls the sharpness of reflections, and for non-metallic surfaces the strength of reflections.";
public static ReadOnlySpan<char> NormalMap =>
"Unused (R), Normal Oct Y (G), Geometric Roughness (B), Normal Oct X (A).\nVector map that offsets the normal (direction the surface is facing) when calculating lighting. Used to add high-resolution detail to otherwise simple mesh geometry. " +
"Also contains roughness calculated from the normal variance for the mips in the blue channel. Assumes normals are encoded into hemi-octahedral format and stored in the G and A channels. " +
"The texture importer will by default automatically convert textures marked as normal maps to hemi-octahedral format and calculate geometric roughness";
public static ReadOnlySpan<char> EmissionMap =>
"Emission Color (RGB).\nControls the intensity and color of light being emitted by the material";
public static ReadOnlySpan<char> EmissionColor =>
"Tints the emission from the emission map. Additionally, the alpha channel controls " +
"how much the albedo map tints the emission. As the alpha goes to 0, the emission is increasingly tinted by the albedo";
public static ReadOnlySpan<char> EmissionFalloff =>
"Controls the strength of the emission fresenel. This is an effect where the strength of the emission decreases as the surface points farther away from the camera.";
public static ReadOnlySpan<char> EmissionBakedMultiplier =>
"Artificially increases the strength of the emission when baking lights. WARNING: this will make specular lighting too " +
"dark for other shaders that don't guestimate the specular from diffuse light probes. Shaders that do not use Bonelab's " +
"custom lighting model will most likely only get specular lighting from reflection probes, and this " +
"multiplier does not effect the brightness of this material as seen by reflection probes.";
public static ReadOnlySpan<char> DetailMap =>
"Overlay Brighten/Darken (R), Normal X (G), Geometric Roughness (B), Normal Y (A).\nRed channel brightens or darkens the material, with 0.5 being neutral. " +
"The rest of the channels are exactly like the normal map, and are blended with the normal map to allow having two different scales of normal details";
public static ReadOnlySpan<char> Surface =>
"How the material is blended with the background. Opaque does what you'd expect and does not blend with what's behind it. Transparent is physically transparent, ie " +
"only the diffuse lighting component is alpha blended with the background. Specular reflections off the surface are unaffected by alpha and are added " +
"to the background. Thus you can still see reflections off a 0 alpha transparent object. Addtionally, as the metallic goes to 1, the material becomes opaque. Fade is " +
"simple alpha blending; as the alpha goes to 0 the material fully disappears";
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 681d21469bfc6a849b96b89958d9e0fa
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,112 @@
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEditor.SLZMaterialUI;
using UnityEngine;
using UnityEngine.UIElements;
public class MAS_defaultSlider : VisualElement
{
public TextureField MASField;
struct MASProperties
{
public int metallic;
public int smoothness;
}
static Dictionary<Texture, MASProperties> MASProps;
static Texture[] MASTextures;
const int numSmoothness = 10;
const int numMetallic = 1;
const int smoothIncr = 100 / numSmoothness;
const int metalIncr = 100 / numMetallic;
const string defaultTexPath = "Packages/com.unity.render-pipelines.universal/Textures/Default/MAS/";
SliderInt SmoothnessSlider;
Toggle MetallicCheck;
static void Init()
{
int numTex = (numSmoothness + 1) * (numMetallic+1);
MASTextures = new Texture[numTex];
MASProps = new Dictionary<Texture, MASProperties>(numTex);
int index = 0;
for (int m = 0; m <= 100; m += metalIncr)
{
string mDigits = Mathf.Min(m, 99).ToString().PadLeft(2,'0');
for (int s = 0; s <= 100; s += smoothIncr)
{
string sDigits = Mathf.Min(s, 99).ToString().PadLeft(2,'0');
string path = string.Format("{0}/MAS_M{1}_S{2}.png", defaultTexPath, mDigits, sDigits);
//Debug.Log(path);
Texture2D mas = AssetDatabase.LoadAssetAtPath<Texture2D>(path);
MASTextures[index] = mas;
index++;
MASProps.Add(mas, new MASProperties { metallic = m, smoothness = s });
}
}
}
public MAS_defaultSlider(TextureField MASField)
{
this.MASField = MASField;
SmoothnessSlider = new SliderInt(0, smoothIncr);
MetallicCheck = new Toggle();
MetallicCheck.style.marginRight = 8;
MetallicCheck.style.marginBottom = 0;
this.style.flexDirection = FlexDirection.Row;
this.style.alignItems = Align.Center;
this.style.justifyContent = Justify.SpaceBetween;
this.style.flexGrow = 1;
this.style.paddingTop = 0;
this.style.marginTop = 0;
SmoothnessSlider.style.flexGrow = 1;
SmoothnessSlider.style.flexShrink = 1;
SmoothnessSlider.style.marginTop = 0;
SmoothnessSlider.style.marginRight = 4;
//SmoothnessSlider.style.alignSelf = Align.Center;
//SmoothnessSlider.label = "Smoothness";
Label metalLabel = new Label("Metal");
Label SmoothLabel = new Label("Smoothness");
Add(metalLabel);
Add(MetallicCheck);
Add(SmoothLabel);
Add(SmoothnessSlider);
CheckIfDefault();
MASField.texObjField.RegisterValueChangedCallback(evt => CheckIfDefault());
SmoothnessSlider.RegisterValueChangedCallback(evt =>
{
int index = evt.newValue + (MetallicCheck.value ? numSmoothness + 1 : 0);
MASField.texObjField.value = MASTextures[index];
});
MetallicCheck.RegisterValueChangedCallback(evt =>
{
int index = SmoothnessSlider.value + (evt.newValue ? numSmoothness + 1 : 0);
MASField.texObjField.value = MASTextures[index];
});
}
void CheckIfDefault()
{
if (MASProps == null || MASTextures == null)
{
Init();
}
MASProperties props;
Texture2D mas = MASField.texObjField.value as Texture2D;
if (mas != null && MASProps.TryGetValue(mas, out props))
{
this.style.display = DisplayStyle.Flex;
SmoothnessSlider.SetValueWithoutNotify(props.smoothness / numSmoothness);
MetallicCheck.SetValueWithoutNotify(props.metallic > 0);
}
else
{
this.style.display = DisplayStyle.None;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b19b1d15cfa66184596abb2867615e59
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,222 @@
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

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 01b3876e9bed3ad49a32f59cbcf453d8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: c811f0193eef849ec831aecd46767d34
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,3 @@
{
"reference": "GUID:2bafac87e7f4b9b418d9448d219b01ab"
}

View file

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 4fb7e7ed7072b3742ae4d27c3ee5649d
AssemblyDefinitionReferenceImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,15 @@
using System.Runtime.CompilerServices;
using UnityEngine;
[assembly: InternalsVisibleTo("Unity.RenderPipelines.Universal.Editor")]
namespace UnityEditor.Rendering.Universal
{
internal static class MaterialAccess
{
internal static int ReadMaterialRawRenderQueue(Material mat)
{
return mat.rawRenderQueue;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fc8990925d7874f13aba12a9ea9c2e1c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,436 @@
using UnityEngine;
using UnityEditorInternal;
using System.Linq;
using System.Collections.Generic;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
namespace UnityEditor.Rendering.Universal.ShaderGUI
{
public static class ParticleGUI
{
public enum ColorMode
{
Multiply,
Additive,
Subtractive,
Overlay,
Color,
Difference
}
public static class Styles
{
public static GUIContent colorMode = EditorGUIUtility.TrTextContent("Color Mode",
"Controls how the Particle color and the Material color blend together.");
public static GUIContent flipbookMode = EditorGUIUtility.TrTextContent("Flip-Book Blending",
"Blends the frames in a flip-book together in a smooth animation.");
public static GUIContent softParticlesEnabled = EditorGUIUtility.TrTextContent("Soft Particles",
"Makes particles fade out when they get close to intersecting with the surface of other geometry in the depth buffer.");
public static GUIContent softParticlesFadeText = EditorGUIUtility.TrTextContent("Surface Fade");
public static GUIContent softParticlesNearFadeDistanceText =
EditorGUIUtility.TrTextContent("Near",
"The distance from the other surface where the particle is completely transparent.");
public static GUIContent softParticlesFarFadeDistanceText =
EditorGUIUtility.TrTextContent("Far",
"The distance from the other surface where the particle is completely opaque.");
public static GUIContent cameraFadingEnabled = EditorGUIUtility.TrTextContent("Camera Fading",
"Makes particles fade out when they get close to the camera.");
public static GUIContent cameraFadingDistanceText = EditorGUIUtility.TrTextContent("Distance");
public static GUIContent cameraNearFadeDistanceText =
EditorGUIUtility.TrTextContent("Near",
"The distance from the camera where the particle is completely transparent.");
public static GUIContent cameraFarFadeDistanceText =
EditorGUIUtility.TrTextContent("Far", "The distance from the camera where the particle is completely opaque.");
public static GUIContent distortionEnabled = EditorGUIUtility.TrTextContent("Distortion",
"Creates a distortion effect by making particles perform refraction with the objects drawn before them.");
public static GUIContent distortionStrength = EditorGUIUtility.TrTextContent("Strength",
"Controls how much the Particle distorts the background. ");
public static GUIContent distortionBlend = EditorGUIUtility.TrTextContent("Blend",
"Controls how visible the distortion effect is. At 0, theres no visible distortion. At 1, only the distortion effect is visible, not the background.");
public static GUIContent VertexStreams = EditorGUIUtility.TrTextContent("Vertex Streams",
"List detailing the expected layout of data sent to the shader from the particle system.");
public static string streamPositionText = "Position (POSITION.xyz)";
public static string streamNormalText = "Normal (NORMAL.xyz)";
public static string streamColorText = "Color (COLOR.xyzw)";
public static string streamColorInstancedText = "Color (INSTANCED0.xyzw)";
public static string streamUVText = "UV (TEXCOORD0.xy)";
public static string streamUV2Text = "UV2 (TEXCOORD0.zw)";
public static string streamAnimBlendText = "AnimBlend (TEXCOORD1.x)";
public static string streamAnimFrameText = "AnimFrame (INSTANCED1.x)";
public static string streamTangentText = "Tangent (TANGENT.xyzw)";
public static GUIContent streamApplyToAllSystemsText = EditorGUIUtility.TrTextContent("Fix Now",
"Apply the vertex stream layout to all Particle Systems using this material");
public static string undoApplyCustomVertexStreams = L10n.Tr("Apply custom vertex streams from material");
public static GUIStyle vertexStreamIcon = new GUIStyle();
}
private static ReorderableList vertexStreamList;
public struct ParticleProperties
{
// Surface Option Props
public MaterialProperty colorMode;
// Advanced Props
public MaterialProperty flipbookMode;
public MaterialProperty softParticlesEnabled;
public MaterialProperty cameraFadingEnabled;
public MaterialProperty distortionEnabled;
public MaterialProperty softParticlesNearFadeDistance;
public MaterialProperty softParticlesFarFadeDistance;
public MaterialProperty cameraNearFadeDistance;
public MaterialProperty cameraFarFadeDistance;
public MaterialProperty distortionBlend;
public MaterialProperty distortionStrength;
public ParticleProperties(MaterialProperty[] properties)
{
// Surface Option Props
colorMode = BaseShaderGUI.FindProperty("_ColorMode", properties, false);
// Advanced Props
flipbookMode = BaseShaderGUI.FindProperty("_FlipbookBlending", properties);
softParticlesEnabled = BaseShaderGUI.FindProperty("_SoftParticlesEnabled", properties);
cameraFadingEnabled = BaseShaderGUI.FindProperty("_CameraFadingEnabled", properties);
distortionEnabled = BaseShaderGUI.FindProperty("_DistortionEnabled", properties, false);
softParticlesNearFadeDistance = BaseShaderGUI.FindProperty("_SoftParticlesNearFadeDistance", properties);
softParticlesFarFadeDistance = BaseShaderGUI.FindProperty("_SoftParticlesFarFadeDistance", properties);
cameraNearFadeDistance = BaseShaderGUI.FindProperty("_CameraNearFadeDistance", properties);
cameraFarFadeDistance = BaseShaderGUI.FindProperty("_CameraFarFadeDistance", properties);
distortionBlend = BaseShaderGUI.FindProperty("_DistortionBlend", properties, false);
distortionStrength = BaseShaderGUI.FindProperty("_DistortionStrength", properties, false);
}
}
public static void SetupMaterialWithColorMode(Material material)
{
var colorMode = (ColorMode)material.GetFloat("_ColorMode");
switch (colorMode)
{
case ColorMode.Multiply:
material.DisableKeyword("_COLOROVERLAY_ON");
material.DisableKeyword("_COLORCOLOR_ON");
material.DisableKeyword("_COLORADDSUBDIFF_ON");
break;
case ColorMode.Overlay:
material.DisableKeyword("_COLORCOLOR_ON");
material.DisableKeyword("_COLORADDSUBDIFF_ON");
material.EnableKeyword("_COLOROVERLAY_ON");
break;
case ColorMode.Color:
material.DisableKeyword("_COLOROVERLAY_ON");
material.DisableKeyword("_COLORADDSUBDIFF_ON");
material.EnableKeyword("_COLORCOLOR_ON");
break;
case ColorMode.Difference:
material.DisableKeyword("_COLOROVERLAY_ON");
material.DisableKeyword("_COLORCOLOR_ON");
material.EnableKeyword("_COLORADDSUBDIFF_ON");
material.SetVector("_BaseColorAddSubDiff", new Vector4(-1.0f, 1.0f, 0.0f, 0.0f));
break;
case ColorMode.Additive:
material.DisableKeyword("_COLOROVERLAY_ON");
material.DisableKeyword("_COLORCOLOR_ON");
material.EnableKeyword("_COLORADDSUBDIFF_ON");
material.SetVector("_BaseColorAddSubDiff", new Vector4(1.0f, 0.0f, 0.0f, 0.0f));
break;
case ColorMode.Subtractive:
material.DisableKeyword("_COLOROVERLAY_ON");
material.DisableKeyword("_COLORCOLOR_ON");
material.EnableKeyword("_COLORADDSUBDIFF_ON");
material.SetVector("_BaseColorAddSubDiff", new Vector4(-1.0f, 0.0f, 0.0f, 0.0f));
break;
}
}
public static void FadingOptions(Material material, MaterialEditor materialEditor, ParticleProperties properties)
{
// Z write doesn't work with fading
bool hasZWrite = (material.GetFloat("_ZWrite") > 0.0f);
if (!hasZWrite)
{
// Soft Particles
{
materialEditor.ShaderProperty(properties.softParticlesEnabled, Styles.softParticlesEnabled);
if (properties.softParticlesEnabled.floatValue >= 0.5f)
{
UniversalRenderPipelineAsset urpAsset = UniversalRenderPipeline.asset;
if (urpAsset != null && !urpAsset.supportsCameraDepthTexture)
{
GUIStyle warnStyle = new GUIStyle(GUI.skin.label);
warnStyle.fontStyle = FontStyle.BoldAndItalic;
warnStyle.wordWrap = true;
EditorGUILayout.HelpBox("Soft Particles require depth texture. Please enable \"Depth Texture\" in the Universal Render Pipeline settings.", MessageType.Warning);
}
EditorGUI.indentLevel++;
BaseShaderGUI.TwoFloatSingleLine(Styles.softParticlesFadeText,
properties.softParticlesNearFadeDistance,
Styles.softParticlesNearFadeDistanceText,
properties.softParticlesFarFadeDistance,
Styles.softParticlesFarFadeDistanceText,
materialEditor);
EditorGUI.indentLevel--;
}
}
// Camera Fading
{
materialEditor.ShaderProperty(properties.cameraFadingEnabled, Styles.cameraFadingEnabled);
if (properties.cameraFadingEnabled.floatValue >= 0.5f)
{
EditorGUI.indentLevel++;
BaseShaderGUI.TwoFloatSingleLine(Styles.cameraFadingDistanceText,
properties.cameraNearFadeDistance,
Styles.cameraNearFadeDistanceText,
properties.cameraFarFadeDistance,
Styles.cameraFarFadeDistanceText,
materialEditor);
EditorGUI.indentLevel--;
}
}
// Distortion
if (properties.distortionEnabled != null)
{
materialEditor.ShaderProperty(properties.distortionEnabled, Styles.distortionEnabled);
if (properties.distortionEnabled.floatValue >= 0.5f)
{
EditorGUI.indentLevel++;
materialEditor.ShaderProperty(properties.distortionStrength, Styles.distortionStrength);
materialEditor.ShaderProperty(properties.distortionBlend, Styles.distortionBlend);
EditorGUI.indentLevel--;
}
}
EditorGUI.showMixedValue = false;
}
}
public static void DoVertexStreamsArea(Material material, List<ParticleSystemRenderer> renderers, bool useLighting = false)
{
EditorGUILayout.Space();
// Display list of streams required to make this shader work
bool useNormalMap = false;
bool useFlipbookBlending = (material.GetFloat("_FlipbookBlending") > 0.0f);
if (material.HasProperty("_BumpMap"))
useNormalMap = material.GetTexture("_BumpMap");
bool useGPUInstancing = ShaderUtil.HasProceduralInstancing(material.shader);
if (useGPUInstancing && renderers.Count > 0)
{
if (!renderers[0].enableGPUInstancing || renderers[0].renderMode != ParticleSystemRenderMode.Mesh)
useGPUInstancing = false;
}
// Build the list of expected vertex streams
List<ParticleSystemVertexStream> streams = new List<ParticleSystemVertexStream>();
List<string> streamList = new List<string>();
streams.Add(ParticleSystemVertexStream.Position);
streamList.Add(Styles.streamPositionText);
if (useLighting || useNormalMap)
{
streams.Add(ParticleSystemVertexStream.Normal);
streamList.Add(Styles.streamNormalText);
if (useNormalMap)
{
streams.Add(ParticleSystemVertexStream.Tangent);
streamList.Add(Styles.streamTangentText);
}
}
streams.Add(ParticleSystemVertexStream.Color);
streamList.Add(useGPUInstancing ? Styles.streamColorInstancedText : Styles.streamColorText);
streams.Add(ParticleSystemVertexStream.UV);
streamList.Add(Styles.streamUVText);
List<ParticleSystemVertexStream> instancedStreams = new List<ParticleSystemVertexStream>(streams);
if (useGPUInstancing)
{
instancedStreams.Add(ParticleSystemVertexStream.AnimFrame);
streamList.Add(Styles.streamAnimFrameText);
}
else if (useFlipbookBlending && !useGPUInstancing)
{
streams.Add(ParticleSystemVertexStream.UV2);
streamList.Add(Styles.streamUV2Text);
streams.Add(ParticleSystemVertexStream.AnimBlend);
streamList.Add(Styles.streamAnimBlendText);
}
vertexStreamList = new ReorderableList(streamList, typeof(string), false, true, false, false);
vertexStreamList.drawHeaderCallback = (Rect rect) =>
{
EditorGUI.LabelField(rect, Styles.VertexStreams);
};
vertexStreamList.DoLayoutList();
// Display a warning if any renderers have incorrect vertex streams
string Warnings = "";
List<ParticleSystemVertexStream> rendererStreams = new List<ParticleSystemVertexStream>();
foreach (ParticleSystemRenderer renderer in renderers)
{
renderer.GetActiveVertexStreams(rendererStreams);
bool streamsValid;
if (useGPUInstancing && renderer.renderMode == ParticleSystemRenderMode.Mesh && renderer.supportsMeshInstancing)
streamsValid = CompareVertexStreams(rendererStreams, instancedStreams);
else
streamsValid = CompareVertexStreams(rendererStreams, instancedStreams);
if (!streamsValid)
Warnings += "-" + renderer.name + "\n";
}
if (!string.IsNullOrEmpty(Warnings))
{
EditorGUILayout.HelpBox(
"The following Particle System Renderers are using this material with incorrect Vertex Streams:\n" +
Warnings, MessageType.Error, true);
// Set the streams on all systems using this material
if (GUILayout.Button(Styles.streamApplyToAllSystemsText, EditorStyles.miniButton, GUILayout.ExpandWidth(true)))
{
Undo.RecordObjects(renderers.Where(r => r != null).ToArray(), Styles.undoApplyCustomVertexStreams);
foreach (ParticleSystemRenderer renderer in renderers)
{
if (useGPUInstancing && renderer.renderMode == ParticleSystemRenderMode.Mesh && renderer.supportsMeshInstancing)
renderer.SetActiveVertexStreams(instancedStreams);
else
renderer.SetActiveVertexStreams(streams);
}
}
}
}
private static bool CompareVertexStreams(IEnumerable<ParticleSystemVertexStream> a, IEnumerable<ParticleSystemVertexStream> b)
{
var differenceA = a.Except(b);
var differenceB = b.Except(a);
var difference = differenceA.Union(differenceB).Distinct();
if (!difference.Any())
return true;
// If normals are the only difference, ignore them, because the default particle streams include normals, to make it easy for users to switch between lit and unlit
if (difference.Count() == 1)
{
if (difference.First() == ParticleSystemVertexStream.Normal)
return true;
}
return false;
}
public static void SetMaterialKeywords(Material material)
{
// Setup particle + material color blending
SetupMaterialWithColorMode(material);
// Is the material transparent, this is set in BaseShaderGUI
bool isTransparent = material.GetTag("RenderType", false) == "Transparent";
// Z write doesn't work with distortion/fading
bool hasZWrite = (material.GetFloat("_ZWrite") > 0.0f);
// Flipbook blending
if (material.HasProperty("_FlipbookBlending"))
{
var useFlipbookBlending = (material.GetFloat("_FlipbookBlending") > 0.0f);
CoreUtils.SetKeyword(material, "_FLIPBOOKBLENDING_ON", useFlipbookBlending);
}
// Soft particles
var useSoftParticles = false;
if (material.HasProperty("_SoftParticlesEnabled"))
{
useSoftParticles = (material.GetFloat("_SoftParticlesEnabled") > 0.0f && isTransparent);
if (useSoftParticles)
{
var softParticlesNearFadeDistance = material.GetFloat("_SoftParticlesNearFadeDistance");
var softParticlesFarFadeDistance = material.GetFloat("_SoftParticlesFarFadeDistance");
// clamp values
if (softParticlesNearFadeDistance < 0.0f)
{
softParticlesNearFadeDistance = 0.0f;
material.SetFloat("_SoftParticlesNearFadeDistance", 0.0f);
}
if (softParticlesFarFadeDistance < 0.0f)
{
softParticlesFarFadeDistance = 0.0f;
material.SetFloat("_SoftParticlesFarFadeDistance", 0.0f);
}
// set keywords
material.SetVector("_SoftParticleFadeParams",
new Vector4(softParticlesNearFadeDistance,
1.0f / (softParticlesFarFadeDistance - softParticlesNearFadeDistance), 0.0f, 0.0f));
}
else
{
material.SetVector("_SoftParticleFadeParams", new Vector4(0.0f, 0.0f, 0.0f, 0.0f));
}
CoreUtils.SetKeyword(material, "_SOFTPARTICLES_ON", useSoftParticles);
}
// Camera fading
var useCameraFading = false;
if (material.HasProperty("_CameraFadingEnabled") && isTransparent)
{
useCameraFading = (material.GetFloat("_CameraFadingEnabled") > 0.0f);
if (useCameraFading)
{
var cameraNearFadeDistance = material.GetFloat("_CameraNearFadeDistance");
var cameraFarFadeDistance = material.GetFloat("_CameraFarFadeDistance");
// clamp values
if (cameraNearFadeDistance < 0.0f)
{
cameraNearFadeDistance = 0.0f;
material.SetFloat("_CameraNearFadeDistance", 0.0f);
}
if (cameraFarFadeDistance < 0.0f)
{
cameraFarFadeDistance = 0.0f;
material.SetFloat("_CameraFarFadeDistance", 0.0f);
}
// set keywords
material.SetVector("_CameraFadeParams",
new Vector4(cameraNearFadeDistance, 1.0f / (cameraFarFadeDistance - cameraNearFadeDistance),
0.0f, 0.0f));
}
else
{
material.SetVector("_CameraFadeParams", new Vector4(0.0f, Mathf.Infinity, 0.0f, 0.0f));
}
}
// Distortion
if (material.HasProperty("_DistortionEnabled"))
{
var useDistortion = (material.GetFloat("_DistortionEnabled") > 0.0f) && isTransparent;
CoreUtils.SetKeyword(material, "_DISTORTION_ON", useDistortion);
if (useDistortion)
material.SetFloat("_DistortionStrengthScaled", material.GetFloat("_DistortionStrength") * 0.1f);
}
var useFading = (useSoftParticles || useCameraFading) && !hasZWrite;
CoreUtils.SetKeyword(material, "_FADING_ON", useFading);
}
}
} // namespace UnityEditor

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2b54c0ca113574ce495f3b706648b6d0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,223 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEditor.Rendering;
using UnityEditor.Rendering.Universal;
using UnityEditor.Rendering.Universal.ShaderGUI;
using static Unity.Rendering.Universal.ShaderUtils;
namespace UnityEditor
{
class SLZUnlit_IMGUI : BaseShaderGUI
{
public MaterialProperty blendSrc;
public MaterialProperty blendDst;
MaterialProperty[] properties;
public enum UnlitBlendModes
{
Opaque = 0,
AlphaPremultiplied,
AlphaBlended,
Additive,
Multiplicative,
}
static string[] unlitBlendModeNames = Enum.GetNames(typeof(UnlitBlendModes));
// 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);
blendModeProp = BaseShaderGUI.FindProperty("_BlendMode", properties, false);
blendSrc = BaseShaderGUI.FindProperty("_BlendSrc", properties, false);
blendDst = BaseShaderGUI.FindProperty("_BlendDst", properties, false);
zwriteProp = BaseShaderGUI.FindProperty("_ZWrite", properties, 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)blendModeProp.floatValue;
EditorGUI.BeginChangeCheck();
EditorGUI.showMixedValue = blendModeProp.hasMixedValue;
int newValue = EditorGUILayout.Popup(Styles.blendingMode, val, unlitBlendModeNames);
EditorGUI.showMixedValue = false;
if (EditorGUI.EndChangeCheck() && (newValue != val || blendModeProp.hasMixedValue))
{
UnlitBlendModes enumVal = (UnlitBlendModes)newValue;
materialEditor.RegisterPropertyChangeUndo(Styles.blendingMode.text);
blendModeProp.floatValue = val = newValue;
switch (enumVal)
{
case UnlitBlendModes.Opaque:
blendSrc.floatValue = (float)UnityEngine.Rendering.BlendMode.One;
blendDst.floatValue = (float)UnityEngine.Rendering.BlendMode.Zero;
zwriteProp.floatValue = 1;
SetQueue(-1);
break;
case UnlitBlendModes.AlphaPremultiplied:
blendSrc.floatValue = (float)UnityEngine.Rendering.BlendMode.One;
blendDst.floatValue = (float)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha;
zwriteProp.floatValue = 0;
SetQueue(3000);
break;
case UnlitBlendModes.AlphaBlended:
blendSrc.floatValue = (float)UnityEngine.Rendering.BlendMode.SrcAlpha;
blendDst.floatValue = (float)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha;
zwriteProp.floatValue = 0;
SetQueue(3000);
break;
case UnlitBlendModes.Additive:
blendSrc.floatValue = (float)UnityEngine.Rendering.BlendMode.One;
blendDst.floatValue = (float)UnityEngine.Rendering.BlendMode.One;
zwriteProp.floatValue = 0;
SetQueue(3000);
break;
case UnlitBlendModes.Multiplicative:
blendSrc.floatValue = (float)UnityEngine.Rendering.BlendMode.DstColor;
blendDst.floatValue = (float)UnityEngine.Rendering.BlendMode.Zero;
zwriteProp.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);
}
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);
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f4531d6ebd8d69549954e73e74c5172d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,288 @@
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System;
using UnityEditor;
using UnityEngine;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Rendering;
using UnityEngine.UIElements;
using Unity.Collections;
using Unity.Mathematics;
using System.IO;
using Object = UnityEngine.Object;
namespace SLZ.SLZEditorTools
{
public static class ShaderGUIUtils
{
const string shaderGUIStylePath = "Packages/com.unity.render-pipelines.universal/Editor/ShaderGUI/Styles/ShaderGUIStyles.uss";
static StyleSheet s_ShaderGUISheet;
public static StyleSheet shaderGUISheet
{
get
{
if (s_ShaderGUISheet == null)
{
s_ShaderGUISheet = AssetDatabase.LoadAssetAtPath<StyleSheet>(shaderGUIStylePath);
if (s_ShaderGUISheet == null)
{
Debug.LogError("Failed to find Shader GUI Style Sheet at " + shaderGUIStylePath);
}
}
return s_ShaderGUISheet;
}
}
static FieldInfo s_InaccessibleToggle;
/// <summary>
/// Makes a foldout look like a unity inspector header.
/// </summary>
/// <param name="f"></param>
/// <param name="title"></param>
/// <param name="iconTex"></param>
public static void SetHeaderStyle(Foldout f, string title, Texture iconTex = null, Toggle headerToggle = null)
{
f.AddToClassList("headerRoot");
if (s_InaccessibleToggle == null)
{
s_InaccessibleToggle = typeof(Foldout).GetField("m_Toggle", BindingFlags.NonPublic | BindingFlags.Instance);
}
Toggle actualFuckingToggle = (Toggle)s_InaccessibleToggle.GetValue(f);
actualFuckingToggle.AddToClassList("headerTogglebar");
actualFuckingToggle.style.paddingBottom = 3;
actualFuckingToggle.style.paddingTop = 2;
actualFuckingToggle.style.marginBottom = 1;
VisualElement container = actualFuckingToggle.ElementAt(0);
container.style.marginRight = 0;
container.style.alignItems = Align.Center;
VisualElement dropdown = container.ElementAt(0);
dropdown.style.marginLeft = 5;
Label titleLabel = new Label(title);
titleLabel.style.unityFontStyleAndWeight = FontStyle.Bold;
titleLabel.style.marginLeft = 6;
titleLabel.style.unityTextAlign = TextAnchor.UpperLeft;
titleLabel.style.paddingTop = 0;
if (iconTex != null)
{
Image icon = new Image();
icon.image = iconTex;
icon.style.height = 16;
icon.style.width = 16;
icon.style.minWidth = 16;
icon.style.minHeight = 16;
icon.style.maxWidth = 16;
icon.style.maxHeight = 16;
icon.style.marginRight = 0;
icon.style.marginLeft = 0;
icon.style.marginTop = 0;
icon.style.marginBottom = 0;
// icon.style.ba
//icon.style.scale = new Vector2(1.1f, 1.1f);
container.Add(icon);
}
if (headerToggle == null)
{
headerToggle = new Toggle();
headerToggle.style.visibility = Visibility.Hidden;
}
headerToggle.style.marginLeft = 6;
headerToggle.style.marginRight = 0;
headerToggle.style.marginBottom = 1;
container.Add(headerToggle);
container.Add(titleLabel);
f.contentContainer.AddToClassList("headerContent");
}
// Gets the shader property index corresponding to each element of a material property array
public static int[] GetMaterialPropertyShaderIdx(MaterialProperty[] materialProperties, Shader shader)
{
int numMatProps = materialProperties.Length;
int[] propertyIdx = new int[numMatProps];
for (int i = 0; i < numMatProps; i++)
{
propertyIdx[i] = shader.FindPropertyIndex(materialProperties[i].name);
}
return propertyIdx;
}
public static int[] GetShaderIdxToMaterialProp(MaterialProperty[] materialProperties, Shader shader)
{
int numMatProps = materialProperties.Length;
int[] propertyIdx = new int[shader.GetPropertyCount()];
for (int i = 0; i < numMatProps; i++)
{
//propertyIdx[shader.FindPropertyIndex(materialProperties[i].name)] = i;
propertyIdx[i] = i;
}
return propertyIdx;
}
/// <summary>
/// Strip out unused texture references in materials to avoid unity bundling/loading them
/// </summary>
/// <param name="targets">target objects, assumed to all be materials</param>
/// <param name="materialProperties">Array of material properties retrieved from MaterialEditor.GetMaterialProperties</param>
/// <param name="propertyIdx">map from each element of materialProperties to the index of its shader property</param>
/// <param name="shader">Shader used by all the target materials</param>
public static void SanitizeMaterials(Object[] targets, MaterialProperty[] materialProperties, int[] propertyIdx, Shader shader)
{
int numMatProps = materialProperties.Length;
HashSet<string> validTextureNames = new HashSet<string>();
for (int i = 0; i < numMatProps; i++)
{
ShaderPropertyType type = shader.GetPropertyType(propertyIdx[i]);
switch (type)
{
case ShaderPropertyType.Texture:
validTextureNames.Add(materialProperties[i].name);
break;
}
}
int numMats = targets.Length;
for (int mat = 0; mat < numMats; mat++)
{
SerializedObject smat = new SerializedObject(targets[mat]);
SerializedProperty texEnv = smat.FindProperty("m_SavedProperties.m_TexEnvs");
bool removedProp = false;
string removedPropNames = "\n ";
if (texEnv != null)
{
int numTex = texEnv.arraySize;
for (int tIdx = numTex - 1; tIdx >= 0; tIdx--)
{
SerializedProperty nameProp = smat.FindProperty("m_SavedProperties.m_TexEnvs.Array.data[" + tIdx.ToString() + "].first");
string name = nameProp.stringValue;
if (!validTextureNames.Contains(name))
{
texEnv.DeleteArrayElementAtIndex(tIdx);
removedPropNames += name + "\n ";
removedProp = true;
}
}
}
if (removedProp)
{
Debug.LogWarning("LitMAS GUI: Removed the following unused texture properties from " + targets[mat].name + removedPropNames);
smat.ApplyModifiedProperties();
}
smat.Dispose();
}
}
static Dictionary<string, Texture2D> icon16px = new Dictionary<string, Texture2D>();
public static Texture2D GetClosestUnityIconMip(string textureName, int iconHeightInPts)
{
int closestPow2Res = (int)math.round(math.log2(iconHeightInPts * EditorGUIUtility.pixelsPerPoint));
int iconRes = 1 << closestPow2Res;
string key = textureName + "X" + iconRes.ToString();
if (icon16px.ContainsKey(key))
{
Texture2D storedIcon = icon16px[key];
if (storedIcon != null)
{
return icon16px[key];
}
else
{
icon16px.Remove(key);
}
}
GUIContent imguiIcon = EditorGUIUtility.IconContent(textureName);
if (imguiIcon == null)
{
return null;
}
Texture2D icon = imguiIcon.image as Texture2D;
if (icon == null)
{
return null;
}
if (icon.width < (iconRes + (iconRes / 2)))
{
return icon;
}
int numMips = icon.mipmapCount;
int desiredMip = numMips - (closestPow2Res + 1);
if (desiredMip < 1)
{
return icon;
}
Texture2D tex = new Texture2D(
Mathf.Max(icon.width >> desiredMip, 1),
Mathf.Max(icon.height >> desiredMip, 1),
icon.graphicsFormat,
TextureCreationFlags.MipChain);
tex.hideFlags = HideFlags.DontSaveInEditor | HideFlags.DontSaveInBuild;
tex.name = textureName;
int currentMip = 0;
NativeArray<byte> iconData = new NativeArray<byte>((int)GraphicsFormatUtility.ComputeMipmapSize(tex.width, tex.height, tex.graphicsFormat), Allocator.Persistent);
while (desiredMip < numMips && currentMip < tex.mipmapCount)
{
NativeArray<byte> texData = tex.GetPixelData<byte>(currentMip);
AsyncGPUReadbackRequest request = AsyncGPUReadback.RequestIntoNativeArray<byte>(ref iconData, icon, desiredMip);
request.WaitForCompletion();
NativeArray<byte>.Copy(iconData, texData, texData.Length);
currentMip++;
desiredMip++;
texData.Dispose();
}
iconData.Dispose();
tex.Apply(false, true);
icon16px.Add(key, tex);
return tex;
}
static Action<VisualElement, int> s_IncrementVersion;
public static void UpdateVisualElement(VisualElement v)
{
if (s_IncrementVersion == null)
{
MethodInfo mi = typeof(VisualElement).GetMethod("IncrementVersion", BindingFlags.NonPublic | BindingFlags.Instance);
s_IncrementVersion = (Action<VisualElement, int>) mi.CreateDelegate(typeof(Action<VisualElement, int>));
}
s_IncrementVersion.Invoke(v, 8 | 2048);
}
static MethodInfo getTracker;
static PropertyInfo s_PropertyViewer;
static void ReflectEditorTracker()
{
s_PropertyViewer = typeof(Editor).GetProperty("propertyViewer", BindingFlags.NonPublic | BindingFlags.Instance);
if (s_PropertyViewer == null) Debug.Log("NULL Property Viewer field");
Type viewerInterface = s_PropertyViewer.PropertyType;
if (viewerInterface == null) Debug.Log("NULL Property Viewer type");
getTracker = viewerInterface.GetProperty("tracker", BindingFlags.Public | BindingFlags.Instance).GetGetMethod();
}
public static void ForceRebuild(Editor e)
{
if (s_PropertyViewer == null)
{
ReflectEditorTracker();
}
object propertyViewer = s_PropertyViewer.GetValue(e);
if (propertyViewer != null)
{
var map = propertyViewer.GetType().GetInterfaceMap(getTracker.DeclaringType);
int index = Array.IndexOf(map.InterfaceMethods, getTracker);
if (index < 0) return;
object tracker = map.InterfaceMethods[index].Invoke(propertyViewer, null);
ActiveEditorTracker activeEditorTracker = (ActiveEditorTracker) tracker;
//activeEditorTracker.ForceRebuild();
}
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 47d498d37cb59c84a8f57a8004475463
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,82 @@
using System;
using UnityEditor.Rendering.Universal;
using UnityEditor.Rendering.Universal.ShaderGUI;
using UnityEngine;
using static Unity.Rendering.Universal.ShaderUtils;
namespace UnityEditor
{
// Used for ShaderGraph Lit shaders
class ShaderGraphLitGUI : BaseShaderGUI
{
public MaterialProperty workflowMode;
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);
}
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);
}
public override void DrawSurfaceOptions(Material material)
{
if (material == null)
throw new ArgumentNullException("material");
// Use default labelWidth
EditorGUIUtility.labelWidth = 0f;
// Detect any changes to the material
if (workflowMode != null)
DoPopup(LitGUI.Styles.workflowModeText, workflowMode, Enum.GetNames(typeof(LitGUI.WorkflowMode)));
base.DrawSurfaceOptions(material);
}
// 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)
materialEditor.RenderQueueField();
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

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1efcaa82db5b5604b861d10e36958714
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,49 @@
using System;
using UnityEngine;
using UnityEditor.Rendering.Universal;
using static Unity.Rendering.Universal.ShaderUtils;
namespace UnityEditor
{
// Used for ShaderGraph Unlit shaders
class ShaderGraphUnlitGUI : BaseShaderGUI
{
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;
base.FindProperties(properties);
}
public static void UpdateMaterial(Material material, MaterialUpdateType updateType)
{
bool automaticRenderQueue = GetAutomaticQueueControlSetting(material);
BaseShaderGUI.UpdateMaterialSurfaceOptions(material, automaticRenderQueue);
}
public override void ValidateMaterial(Material 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)
materialEditor.RenderQueueField();
base.DrawAdvancedOptions(material);
materialEditor.DoubleSidedGIField();
}
}
} // namespace UnityEditor

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5b95b9b576115ac4bbf3b1ea150ab3c0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 44979452441cd45d5a88ff530647528f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,92 @@
using System;
using UnityEngine;
using UnityEditor.Rendering.Universal;
namespace UnityEditor.Rendering.Universal.ShaderGUI
{
internal class BakedLitShader : BaseShaderGUI
{
// Properties
private BakedLitGUI.BakedLitProperties shadingModelProperties;
// collect properties from the material properties
public override void FindProperties(MaterialProperty[] properties)
{
base.FindProperties(properties);
shadingModelProperties = new BakedLitGUI.BakedLitProperties(properties);
}
// material changed check
public override void ValidateMaterial(Material material)
{
SetMaterialKeywords(material);
}
// material main surface options
public override void DrawSurfaceOptions(Material material)
{
if (material == null)
throw new ArgumentNullException("material");
// Use default labelWidth
EditorGUIUtility.labelWidth = 0f;
base.DrawSurfaceOptions(material);
}
// material main surface inputs
public override void DrawSurfaceInputs(Material material)
{
base.DrawSurfaceInputs(material);
BakedLitGUI.Inputs(shadingModelProperties, materialEditor);
DrawTileOffset(materialEditor, baseMapProp);
}
public override void AssignNewShaderToMaterial(Material material, Shader oldShader, Shader newShader)
{
if (material == null)
throw new ArgumentNullException("material");
// _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/"))
{
SetupMaterialBlendMode(material);
return;
}
SurfaceType surfaceType = SurfaceType.Opaque;
BlendMode blendMode = BlendMode.Alpha;
if (oldShader.name.Contains("/Transparent/Cutout/"))
{
surfaceType = SurfaceType.Opaque;
material.SetFloat("_AlphaClip", 1);
}
else if (oldShader.name.Contains("/Transparent/"))
{
// NOTE: legacy shaders did not provide physically based transparency
// therefore Fade mode
surfaceType = SurfaceType.Transparent;
blendMode = BlendMode.Alpha;
}
material.SetFloat("_Blend", (float)blendMode);
material.SetFloat("_Surface", (float)surfaceType);
if (surfaceType == SurfaceType.Opaque)
{
material.DisableKeyword("_SURFACE_TYPE_TRANSPARENT");
}
else
{
material.EnableKeyword("_SURFACE_TYPE_TRANSPARENT");
}
}
}
}

View file

@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 8176ef27c50d1485084b4ab6f1554353
timeCreated: 1504689095
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,128 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace UnityEditor.Rendering.Universal.ShaderGUI
{
internal class LitShader : BaseShaderGUI
{
static readonly string[] workflowModeNames = Enum.GetNames(typeof(LitGUI.WorkflowMode));
private LitGUI.LitProperties litProperties;
private LitDetailGUI.LitProperties litDetailProperties;
public override void FillAdditionalFoldouts(MaterialHeaderScopeList materialScopesList)
{
materialScopesList.RegisterHeaderScope(LitDetailGUI.Styles.detailInputs, Expandable.Details, _ => LitDetailGUI.DoDetailArea(litDetailProperties, materialEditor));
}
// collect properties from the material properties
public override void FindProperties(MaterialProperty[] properties)
{
base.FindProperties(properties);
litProperties = new LitGUI.LitProperties(properties);
litDetailProperties = new LitDetailGUI.LitProperties(properties);
}
// material changed check
public override void ValidateMaterial(Material material)
{
SetMaterialKeywords(material, LitGUI.SetMaterialKeywords, LitDetailGUI.SetMaterialKeywords);
}
// material main surface options
public override void DrawSurfaceOptions(Material material)
{
// Use default labelWidth
EditorGUIUtility.labelWidth = 0f;
if (litProperties.workflowMode != null)
DoPopup(LitGUI.Styles.workflowModeText, litProperties.workflowMode, workflowModeNames);
base.DrawSurfaceOptions(material);
}
// material main surface inputs
public override void DrawSurfaceInputs(Material material)
{
base.DrawSurfaceInputs(material);
LitGUI.Inputs(litProperties, materialEditor, material);
DrawEmissionProperties(material, true);
DrawTileOffset(materialEditor, baseMapProp);
}
// material main advanced options
public override void DrawAdvancedOptions(Material material)
{
if (litProperties.reflections != null && litProperties.highlights != null)
{
materialEditor.ShaderProperty(litProperties.highlights, LitGUI.Styles.highlightsText);
materialEditor.ShaderProperty(litProperties.reflections, LitGUI.Styles.reflectionsText);
}
base.DrawAdvancedOptions(material);
}
public override void AssignNewShaderToMaterial(Material material, Shader oldShader, Shader newShader)
{
if (material == null)
throw new ArgumentNullException("material");
// _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/"))
{
SetupMaterialBlendMode(material);
return;
}
SurfaceType surfaceType = SurfaceType.Opaque;
BlendMode blendMode = BlendMode.Alpha;
if (oldShader.name.Contains("/Transparent/Cutout/"))
{
surfaceType = SurfaceType.Opaque;
material.SetFloat("_AlphaClip", 1);
}
else if (oldShader.name.Contains("/Transparent/"))
{
// NOTE: legacy shaders did not provide physically based transparency
// therefore Fade mode
surfaceType = SurfaceType.Transparent;
blendMode = BlendMode.Alpha;
}
material.SetFloat("_Blend", (float)blendMode);
material.SetFloat("_Surface", (float)surfaceType);
if (surfaceType == SurfaceType.Opaque)
{
material.DisableKeyword("_SURFACE_TYPE_TRANSPARENT");
}
else
{
material.EnableKeyword("_SURFACE_TYPE_TRANSPARENT");
}
if (oldShader.name.Equals("Standard (Specular setup)"))
{
material.SetFloat("_WorkflowMode", (float)LitGUI.WorkflowMode.Specular);
Texture texture = material.GetTexture("_SpecGlossMap");
if (texture != null)
material.SetTexture("_MetallicSpecGlossMap", texture);
}
else
{
material.SetFloat("_WorkflowMode", (float)LitGUI.WorkflowMode.Metallic);
Texture texture = material.GetTexture("_MetallicGlossMap");
if (texture != null)
material.SetTexture("_MetallicSpecGlossMap", texture);
}
}
}
}

View file

@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: a72ab9c46e7987c40bcd48bcf9e7c0dd
timeCreated: 1504689095
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,68 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace UnityEditor.Rendering.Universal.ShaderGUI
{
internal class ParticlesLitShader : BaseShaderGUI
{
// Properties
private LitGUI.LitProperties litProperties;
private ParticleGUI.ParticleProperties particleProps;
// List of renderers using this material in the scene, used for validating vertex streams
List<ParticleSystemRenderer> m_RenderersUsingThisMaterial = new List<ParticleSystemRenderer>();
public override void FindProperties(MaterialProperty[] properties)
{
base.FindProperties(properties);
litProperties = new LitGUI.LitProperties(properties);
particleProps = new ParticleGUI.ParticleProperties(properties);
}
public override void ValidateMaterial(Material material)
{
SetMaterialKeywords(material, LitGUI.SetMaterialKeywords, ParticleGUI.SetMaterialKeywords);
}
public override void DrawSurfaceOptions(Material material)
{
base.DrawSurfaceOptions(material);
DoPopup(ParticleGUI.Styles.colorMode, particleProps.colorMode, Enum.GetNames(typeof(ParticleGUI.ColorMode)));
}
public override void DrawSurfaceInputs(Material material)
{
base.DrawSurfaceInputs(material);
LitGUI.Inputs(litProperties, materialEditor, material);
DrawEmissionProperties(material, true);
}
public override void DrawAdvancedOptions(Material material)
{
materialEditor.ShaderProperty(particleProps.flipbookMode, ParticleGUI.Styles.flipbookMode);
ParticleGUI.FadingOptions(material, materialEditor, particleProps);
ParticleGUI.DoVertexStreamsArea(material, m_RenderersUsingThisMaterial, true);
DrawQueueOffsetField();
}
public override void OnOpenGUI(Material material, MaterialEditor materialEditor)
{
CacheRenderersUsingThisMaterial(material);
base.OnOpenGUI(material, materialEditor);
}
void CacheRenderersUsingThisMaterial(Material material)
{
m_RenderersUsingThisMaterial.Clear();
ParticleSystemRenderer[] renderers = UnityEngine.Object.FindObjectsOfType(typeof(ParticleSystemRenderer)) as ParticleSystemRenderer[];
foreach (ParticleSystemRenderer renderer in renderers)
{
if (renderer.sharedMaterial == material)
m_RenderersUsingThisMaterial.Add(renderer);
}
}
}
} // namespace UnityEditor

View file

@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 9818dc043dbe84466a71ed6178bbffda
timeCreated: 1509367878
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,70 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace UnityEditor.Rendering.Universal.ShaderGUI
{
internal class ParticlesSimpleLitShader : BaseShaderGUI
{
// Properties
private SimpleLitGUI.SimpleLitProperties shadingModelProperties;
private ParticleGUI.ParticleProperties particleProps;
// List of renderers using this material in the scene, used for validating vertex streams
List<ParticleSystemRenderer> m_RenderersUsingThisMaterial = new List<ParticleSystemRenderer>();
public override void FindProperties(MaterialProperty[] properties)
{
base.FindProperties(properties);
shadingModelProperties = new SimpleLitGUI.SimpleLitProperties(properties);
particleProps = new ParticleGUI.ParticleProperties(properties);
}
public override void ValidateMaterial(Material material)
{
SetMaterialKeywords(material, SimpleLitGUI.SetMaterialKeywords, ParticleGUI.SetMaterialKeywords);
}
public override void DrawSurfaceOptions(Material material)
{
base.DrawSurfaceOptions(material);
DoPopup(ParticleGUI.Styles.colorMode, particleProps.colorMode, Enum.GetNames(typeof(ParticleGUI.ColorMode)));
}
public override void DrawSurfaceInputs(Material material)
{
base.DrawSurfaceInputs(material);
SimpleLitGUI.Inputs(shadingModelProperties, materialEditor, material);
DrawEmissionProperties(material, true);
}
public override void DrawAdvancedOptions(Material material)
{
SimpleLitGUI.Advanced(shadingModelProperties);
materialEditor.ShaderProperty(particleProps.flipbookMode, ParticleGUI.Styles.flipbookMode);
ParticleGUI.FadingOptions(material, materialEditor, particleProps);
ParticleGUI.DoVertexStreamsArea(material, m_RenderersUsingThisMaterial, true);
DrawQueueOffsetField();
}
public override void OnOpenGUI(Material material, MaterialEditor materialEditor)
{
CacheRenderersUsingThisMaterial(material);
base.OnOpenGUI(material, materialEditor);
}
void CacheRenderersUsingThisMaterial(Material material)
{
m_RenderersUsingThisMaterial.Clear();
ParticleSystemRenderer[] renderers = UnityEngine.Object.FindObjectsOfType(typeof(ParticleSystemRenderer)) as ParticleSystemRenderer[];
foreach (ParticleSystemRenderer renderer in renderers)
{
if (renderer.sharedMaterial == material)
m_RenderersUsingThisMaterial.Add(renderer);
}
}
}
} // namespace UnityEditor

View file

@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 3d80ff2d19402463c8a2a52558deaf43
timeCreated: 1509367878
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,68 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace UnityEditor.Rendering.Universal.ShaderGUI
{
internal class ParticlesUnlitShader : BaseShaderGUI
{
// Properties
private BakedLitGUI.BakedLitProperties shadingModelProperties;
private ParticleGUI.ParticleProperties particleProps;
// List of renderers using this material in the scene, used for validating vertex streams
List<ParticleSystemRenderer> m_RenderersUsingThisMaterial = new List<ParticleSystemRenderer>();
public override void FindProperties(MaterialProperty[] properties)
{
base.FindProperties(properties);
shadingModelProperties = new BakedLitGUI.BakedLitProperties(properties);
particleProps = new ParticleGUI.ParticleProperties(properties);
}
public override void ValidateMaterial(Material material)
{
SetMaterialKeywords(material, null, ParticleGUI.SetMaterialKeywords);
}
public override void DrawSurfaceOptions(Material material)
{
base.DrawSurfaceOptions(material);
DoPopup(ParticleGUI.Styles.colorMode, particleProps.colorMode, Enum.GetNames(typeof(ParticleGUI.ColorMode)));
}
public override void DrawSurfaceInputs(Material material)
{
base.DrawSurfaceInputs(material);
BakedLitGUI.Inputs(shadingModelProperties, materialEditor);
DrawEmissionProperties(material, true);
}
public override void DrawAdvancedOptions(Material material)
{
materialEditor.ShaderProperty(particleProps.flipbookMode, ParticleGUI.Styles.flipbookMode);
ParticleGUI.FadingOptions(material, materialEditor, particleProps);
ParticleGUI.DoVertexStreamsArea(material, m_RenderersUsingThisMaterial);
DrawQueueOffsetField();
}
public override void OnOpenGUI(Material material, MaterialEditor materialEditor)
{
CacheRenderersUsingThisMaterial(material);
base.OnOpenGUI(material, materialEditor);
}
void CacheRenderersUsingThisMaterial(Material material)
{
m_RenderersUsingThisMaterial.Clear();
ParticleSystemRenderer[] renderers = UnityEngine.Object.FindObjectsOfType(typeof(ParticleSystemRenderer)) as ParticleSystemRenderer[];
foreach (ParticleSystemRenderer renderer in renderers)
{
if (renderer.sharedMaterial == material)
m_RenderersUsingThisMaterial.Add(renderer);
}
}
}
} // namespace UnityEditor

View file

@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 84e6c97ce450449128b4f193da9c0263
timeCreated: 1509367878
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,89 @@
using System;
using UnityEngine;
namespace UnityEditor.Rendering.Universal.ShaderGUI
{
internal class SimpleLitShader : BaseShaderGUI
{
// Properties
private SimpleLitGUI.SimpleLitProperties shadingModelProperties;
// collect properties from the material properties
public override void FindProperties(MaterialProperty[] properties)
{
base.FindProperties(properties);
shadingModelProperties = new SimpleLitGUI.SimpleLitProperties(properties);
}
// material changed check
public override void ValidateMaterial(Material material)
{
SetMaterialKeywords(material, SimpleLitGUI.SetMaterialKeywords);
}
// material main surface options
public override void DrawSurfaceOptions(Material material)
{
if (material == null)
throw new ArgumentNullException("material");
// Use default labelWidth
EditorGUIUtility.labelWidth = 0f;
base.DrawSurfaceOptions(material);
}
// material main surface inputs
public override void DrawSurfaceInputs(Material material)
{
base.DrawSurfaceInputs(material);
SimpleLitGUI.Inputs(shadingModelProperties, materialEditor, material);
DrawEmissionProperties(material, true);
DrawTileOffset(materialEditor, baseMapProp);
}
public override void DrawAdvancedOptions(Material material)
{
SimpleLitGUI.Advanced(shadingModelProperties);
base.DrawAdvancedOptions(material);
}
public override void AssignNewShaderToMaterial(Material material, Shader oldShader, Shader newShader)
{
if (material == null)
throw new ArgumentNullException("material");
// _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/"))
{
SetupMaterialBlendMode(material);
return;
}
SurfaceType surfaceType = SurfaceType.Opaque;
BlendMode blendMode = BlendMode.Alpha;
if (oldShader.name.Contains("/Transparent/Cutout/"))
{
surfaceType = SurfaceType.Opaque;
material.SetFloat("_AlphaClip", 1);
}
else if (oldShader.name.Contains("/Transparent/"))
{
// NOTE: legacy shaders did not provide physically based transparency
// therefore Fade mode
surfaceType = SurfaceType.Transparent;
blendMode = BlendMode.Alpha;
}
material.SetFloat("_Surface", (float)surfaceType);
material.SetFloat("_Blend", (float)blendMode);
}
}
}

View file

@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: b31b6386794884dfbb8513e510144b19
timeCreated: 1504689095
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,80 @@
using System;
using UnityEngine;
namespace UnityEditor.Rendering.Universal.ShaderGUI
{
internal class UnlitShader : BaseShaderGUI
{
// material changed check
public override void ValidateMaterial(Material material)
{
SetMaterialKeywords(material);
}
// material main surface options
public override void DrawSurfaceOptions(Material material)
{
if (material == null)
throw new ArgumentNullException("material");
// Use default labelWidth
EditorGUIUtility.labelWidth = 0f;
base.DrawSurfaceOptions(material);
}
// material main surface inputs
public override void DrawSurfaceInputs(Material material)
{
base.DrawSurfaceInputs(material);
DrawTileOffset(materialEditor, baseMapProp);
}
public override void AssignNewShaderToMaterial(Material material, Shader oldShader, Shader newShader)
{
if (material == null)
throw new ArgumentNullException("material");
// _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/"))
{
SetupMaterialBlendMode(material);
return;
}
SurfaceType surfaceType = SurfaceType.Opaque;
BlendMode blendMode = BlendMode.Alpha;
if (oldShader.name.Contains("/Transparent/Cutout/"))
{
surfaceType = SurfaceType.Opaque;
material.SetFloat("_AlphaClip", 1);
}
else if (oldShader.name.Contains("/Transparent/"))
{
// NOTE: legacy shaders did not provide physically based transparency
// therefore Fade mode
surfaceType = SurfaceType.Transparent;
blendMode = BlendMode.Alpha;
}
material.SetFloat("_Blend", (float)blendMode);
material.SetFloat("_Surface", (float)surfaceType);
if (surfaceType == SurfaceType.Opaque)
{
material.DisableKeyword("_SURFACE_TYPE_TRANSPARENT");
}
else
{
material.EnableKeyword("_SURFACE_TYPE_TRANSPARENT");
}
}
}
}

View file

@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 8ed8ed178d5584da0874d4c69e3624a9
timeCreated: 1504689095
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a22c22fb536604167866c59ce9a780d2
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,26 @@
using System;
using UnityEngine;
using UnityEngine.Rendering;
namespace UnityEditor.Rendering.Universal.ShaderGUI
{
public static class BakedLitGUI
{
public struct BakedLitProperties
{
// Surface Input Props
public MaterialProperty bumpMapProp;
public BakedLitProperties(MaterialProperty[] properties)
{
// Surface Input Props
bumpMapProp = BaseShaderGUI.FindProperty("_BumpMap", properties, false);
}
}
public static void Inputs(BakedLitProperties properties, MaterialEditor materialEditor)
{
BaseShaderGUI.DrawNormalArea(materialEditor, properties.bumpMapProp);
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 795fde47942374005bbe56e3879983db
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,80 @@
using UnityEngine;
using UnityEngine.Rendering;
namespace UnityEditor.Rendering.Universal.ShaderGUI
{
internal class LitDetailGUI
{
public static class Styles
{
public static readonly GUIContent detailInputs = EditorGUIUtility.TrTextContent("Detail Inputs",
"These settings define the surface details by tiling and overlaying additional maps on the surface.");
public static readonly GUIContent detailMaskText = EditorGUIUtility.TrTextContent("Mask",
"Select a mask for the Detail map. The mask uses the alpha channel of the selected texture. The Tiling and Offset settings have no effect on the mask.");
public static readonly GUIContent detailAlbedoMapText = EditorGUIUtility.TrTextContent("Detail Map",
"(R) Desaturated albedo, (G) Normal Y, (B) Smoothness, (A) Normal X.");
// "Select the surface detail texture.The alpha of your texture determines surface hue and intensity.");
public static readonly GUIContent detailNormalMapText = EditorGUIUtility.TrTextContent("Normal Map",
"Designates a Normal Map to create the illusion of bumps and dents in the details of this Material's surface.");
//public static readonly GUIContent detailAlbedoMapScaleInfo = EditorGUIUtility.TrTextContent("Setting the scaling factor to a value other than 1 results in a less performant shader variant.");
}
public struct LitProperties
{
// public MaterialProperty detailMask;
public MaterialProperty detailMap;
//public MaterialProperty detailAlbedoMapScale;
//public MaterialProperty detailAlbedoMap;
public MaterialProperty detailNormalMapScale;
public MaterialProperty detailSmoothnessMapScale;
//public MaterialProperty detailNormalMap;
public LitProperties(MaterialProperty[] properties)
{
// detailMask = BaseShaderGUI.FindProperty("_DetailMask", properties, false);
detailMap = BaseShaderGUI.FindProperty("_DetailMap", properties, false);
//detailAlbedoMapScale = BaseShaderGUI.FindProperty("_DetailAlbedoMapScale", properties, false);
// detailAlbedoMap = BaseShaderGUI.FindProperty("_DetailAlbedoMap", properties, false);
detailNormalMapScale = BaseShaderGUI.FindProperty("_DetailNormalMapScale", properties, false);
detailSmoothnessMapScale = BaseShaderGUI.FindProperty("_DetailSmoothnessMapScale", properties, false);
// detailNormalMap = BaseShaderGUI.FindProperty("_DetailNormalMap", properties, false);
}
}
public static void DoDetailArea(LitProperties properties, MaterialEditor materialEditor)
{
// materialEditor.TexturePropertySingleLine(Styles.detailMaskText, properties.detailMask);
materialEditor.TexturePropertySingleLine(Styles.detailAlbedoMapText, properties.detailMap);
//,properties.detailMap.textureValue != null ? properties.detailAlbedoMapScale : null);
// if (properties.detailAlbedoMapScale.floatValue != 1.0f)
// {
// EditorGUILayout.HelpBox(Styles.detailAlbedoMapScaleInfo.text, MessageType.Info, true);
// }
if (properties.detailMap.textureValue != null)
{
// materialEditor.TexturePropertySingleLine(Styles.detailNormalMapText, properties.detailNormalMap,
// properties.detailNormalMap.textureValue != null ? properties.detailNormalMapScale : null);
materialEditor.RangeProperty(properties.detailNormalMapScale, "Bump Scale");
materialEditor.RangeProperty(properties.detailSmoothnessMapScale, "Smoothness Scale");
materialEditor.TextureScaleOffsetProperty(properties.detailMap);
// materialEditor.TextureScaleOffsetProperty(properties.detailAlbedoMap);
}
}
public static void SetMaterialKeywords(Material material)
{
if (material.HasProperty("_DetailMap") )//&& material.HasProperty("_DetailAlbedoMapScale"))
{
bool isScaled = false;//material.GetFloat("_DetailAlbedoMapScale") != 1.0f;
bool hasDetailMap = material.GetTexture("_DetailMap");
CoreUtils.SetKeyword(material, "_DETAIL_MULX2", !isScaled && hasDetailMap);
if (hasDetailMap) CoreUtils.SetKeyword(material, "_NORMALMAP", true); //Forcing on normalmap to avoid a darkening bug with mixed directional lights :/
// CoreUtils.SetKeyword(material, "_DETAIL_SCALED", isScaled && hasDetailMap);
}
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7645809b8de779942be231eecf635c5b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,320 @@
using UnityEngine;
using UnityEngine.Rendering;
namespace UnityEditor.Rendering.Universal.ShaderGUI
{
public static class LitGUI
{
public enum WorkflowMode
{
Specular = 0,
Metallic
}
public enum SmoothnessMapChannel
{
SpecularMetallicAlpha,
AlbedoAlpha,
}
public static class Styles
{
public static GUIContent workflowModeText = EditorGUIUtility.TrTextContent("Workflow Mode",
"Select a workflow that fits your textures. Choose between Metallic or Specular.");
public static GUIContent specularMapText =
EditorGUIUtility.TrTextContent("Specular Map", "Designates a Specular Map and specular color determining the apperance of reflections on this Material's surface.");
public static GUIContent metallicMapText =
EditorGUIUtility.TrTextContent("Mask Map", "Metallic (R), AO (G), Detail Mask (B), Smoothness (A)"); //Using HDRP's packing to free up some texture channels
public static GUIContent smoothnessText = EditorGUIUtility.TrTextContent("Smoothness",
"Controls the spread of highlights and reflections on the surface.");
public static GUIContent smoothnessMapChannelText =
EditorGUIUtility.TrTextContent("Source",
"Specifies where to sample a smoothness map from. By default, uses the alpha channel for your map.");
public static GUIContent highlightsText = EditorGUIUtility.TrTextContent("Specular Highlights",
"When enabled, the Material reflects the shine from direct lighting.");
public static GUIContent reflectionsText =
EditorGUIUtility.TrTextContent("Environment Reflections",
"When enabled, the Material samples reflections from the nearest Reflection Probes or Lighting Probe.");
public static GUIContent heightMapText = EditorGUIUtility.TrTextContent("Height Map",
"Defines a Height Map that will drive a parallax effect in the shader making the surface seem displaced.");
public static GUIContent occlusionText = EditorGUIUtility.TrTextContent("Occlusion Map",
"Sets an occlusion map to simulate shadowing from ambient lighting (G).");
public static readonly string[] metallicSmoothnessChannelNames = { "Metallic Alpha", "Albedo Alpha" };
public static readonly string[] specularSmoothnessChannelNames = { "Specular Alpha", "Albedo Alpha" };
public static GUIContent clearCoatText = EditorGUIUtility.TrTextContent("Clear Coat",
"A multi-layer material feature which simulates a thin layer of coating on top of the surface material." +
"\nPerformance cost is considerable as the specular component is evaluated twice, once per layer.");
public static GUIContent clearCoatMaskText = EditorGUIUtility.TrTextContent("Mask",
"Specifies the amount of the coat blending." +
"\nActs as a multiplier of the clear coat map mask value or as a direct mask value if no map is specified." +
"\nThe map specifies clear coat mask in the red channel and clear coat smoothness in the green channel.");
public static GUIContent clearCoatSmoothnessText = EditorGUIUtility.TrTextContent("Smoothness",
"Specifies the smoothness of the coating." +
"\nActs as a multiplier of the clear coat map smoothness value or as a direct smoothness value if no map is specified.");
}
public struct LitProperties
{
// Surface Option Props
public MaterialProperty workflowMode;
// Surface Input Props
public MaterialProperty metallic;
public MaterialProperty specColor;
public MaterialProperty metallicGlossMap;
public MaterialProperty specGlossMap;
public MaterialProperty smoothness;
public MaterialProperty smoothnessMapChannel;
public MaterialProperty bumpMapProp;
public MaterialProperty bumpScaleProp;
public MaterialProperty parallaxMapProp;
public MaterialProperty parallaxScaleProp;
public MaterialProperty occlusionStrength;
public MaterialProperty occlusionMap;
// Advanced Props
public MaterialProperty highlights;
public MaterialProperty reflections;
public MaterialProperty clearCoat; // Enable/Disable dummy property
public MaterialProperty clearCoatMap;
public MaterialProperty clearCoatMask;
public MaterialProperty clearCoatSmoothness;
public LitProperties(MaterialProperty[] properties)
{
// Surface Option Props
workflowMode = BaseShaderGUI.FindProperty("_WorkflowMode", properties, false);
// Surface Input Props
metallic = BaseShaderGUI.FindProperty("_Metallic", properties);
specColor = BaseShaderGUI.FindProperty("_SpecColor", properties, false);
metallicGlossMap = BaseShaderGUI.FindProperty("_MetallicGlossMap", properties);
specGlossMap = BaseShaderGUI.FindProperty("_SpecGlossMap", properties, false);
smoothness = BaseShaderGUI.FindProperty("_Smoothness", properties, false);
smoothnessMapChannel = BaseShaderGUI.FindProperty("_SmoothnessTextureChannel", properties, false);
bumpMapProp = BaseShaderGUI.FindProperty("_BumpMap", properties, false);
bumpScaleProp = BaseShaderGUI.FindProperty("_BumpScale", properties, false);
parallaxMapProp = BaseShaderGUI.FindProperty("_ParallaxMap", properties, false);
parallaxScaleProp = BaseShaderGUI.FindProperty("_Parallax", properties, false);
occlusionStrength = BaseShaderGUI.FindProperty("_OcclusionStrength", properties, false);
occlusionMap = BaseShaderGUI.FindProperty("_OcclusionMap", properties, false);
// Advanced Props
highlights = BaseShaderGUI.FindProperty("_SpecularHighlights", properties, false);
reflections = BaseShaderGUI.FindProperty("_EnvironmentReflections", properties, false);
clearCoat = BaseShaderGUI.FindProperty("_ClearCoat", properties, false);
clearCoatMap = BaseShaderGUI.FindProperty("_ClearCoatMap", properties, false);
clearCoatMask = BaseShaderGUI.FindProperty("_ClearCoatMask", properties, false);
clearCoatSmoothness = BaseShaderGUI.FindProperty("_ClearCoatSmoothness", properties, false);
}
}
public static void Inputs(LitProperties properties, MaterialEditor materialEditor, Material material)
{
DoMetallicSpecularArea(properties, materialEditor, material);
BaseShaderGUI.DrawNormalArea(materialEditor, properties.bumpMapProp, properties.bumpScaleProp);
if (HeightmapAvailable(material))
DoHeightmapArea(properties, materialEditor);
if (properties.occlusionMap != null)
{
materialEditor.TexturePropertySingleLine(Styles.occlusionText, properties.occlusionMap,
properties.occlusionMap.textureValue != null ? properties.occlusionStrength : null);
}
// Check that we have all the required properties for clear coat,
// otherwise we will get null ref exception from MaterialEditor GUI helpers.
if (ClearCoatAvailable(material))
DoClearCoat(properties, materialEditor, material);
}
private static bool ClearCoatAvailable(Material material)
{
return material.HasProperty("_ClearCoat")
&& material.HasProperty("_ClearCoatMap")
&& material.HasProperty("_ClearCoatMask")
&& material.HasProperty("_ClearCoatSmoothness");
}
private static bool HeightmapAvailable(Material material)
{
return material.HasProperty("_Parallax")
&& material.HasProperty("_ParallaxMap");
}
private static void DoHeightmapArea(LitProperties properties, MaterialEditor materialEditor)
{
materialEditor.TexturePropertySingleLine(Styles.heightMapText, properties.parallaxMapProp,
properties.parallaxMapProp.textureValue != null ? properties.parallaxScaleProp : null);
}
private static bool ClearCoatEnabled(Material material)
{
return material.HasProperty("_ClearCoat") && material.GetFloat("_ClearCoat") > 0.0;
}
public static void DoClearCoat(LitProperties properties, MaterialEditor materialEditor, Material material)
{
materialEditor.ShaderProperty(properties.clearCoat, Styles.clearCoatText);
var coatEnabled = material.GetFloat("_ClearCoat") > 0.0;
EditorGUI.BeginDisabledGroup(!coatEnabled);
{
materialEditor.TexturePropertySingleLine(Styles.clearCoatMaskText, properties.clearCoatMap, properties.clearCoatMask);
EditorGUI.indentLevel += 2;
// Texture and HDR color controls
materialEditor.ShaderProperty(properties.clearCoatSmoothness, Styles.clearCoatSmoothnessText);
EditorGUI.indentLevel -= 2;
}
EditorGUI.EndDisabledGroup();
}
public static void DoMetallicSpecularArea(LitProperties properties, MaterialEditor materialEditor, Material material)
{
string[] smoothnessChannelNames;
bool hasGlossMap = false;
if (properties.workflowMode == null ||
(WorkflowMode)properties.workflowMode.floatValue == WorkflowMode.Metallic)
{
hasGlossMap = properties.metallicGlossMap.textureValue != null;
smoothnessChannelNames = Styles.metallicSmoothnessChannelNames;
materialEditor.TexturePropertySingleLine(Styles.metallicMapText, properties.metallicGlossMap,
hasGlossMap ? null : properties.metallic);
}
else
{
hasGlossMap = properties.specGlossMap.textureValue != null;
smoothnessChannelNames = Styles.specularSmoothnessChannelNames;
BaseShaderGUI.TextureColorProps(materialEditor, Styles.specularMapText, properties.specGlossMap,
hasGlossMap ? null : properties.specColor);
}
DoSmoothness(materialEditor, material, properties.smoothness, properties.smoothnessMapChannel, smoothnessChannelNames);
}
internal static bool IsOpaque(Material material)
{
bool opaque = true;
if (material.HasProperty(Property.SurfaceType))
opaque = ((BaseShaderGUI.SurfaceType)material.GetFloat(Property.SurfaceType) == BaseShaderGUI.SurfaceType.Opaque);
return opaque;
}
public static void DoSmoothness(MaterialEditor materialEditor, Material material, MaterialProperty smoothness, MaterialProperty smoothnessMapChannel, string[] smoothnessChannelNames)
{
EditorGUI.indentLevel += 2;
materialEditor.ShaderProperty(smoothness, Styles.smoothnessText);
if (smoothnessMapChannel != null) // smoothness channel
{
var opaque = IsOpaque(material);
EditorGUI.indentLevel++;
EditorGUI.showMixedValue = smoothnessMapChannel.hasMixedValue;
if (opaque)
{
EditorGUI.BeginChangeCheck();
var smoothnessSource = (int)smoothnessMapChannel.floatValue;
smoothnessSource = EditorGUILayout.Popup(Styles.smoothnessMapChannelText, smoothnessSource, smoothnessChannelNames);
if (EditorGUI.EndChangeCheck())
smoothnessMapChannel.floatValue = smoothnessSource;
}
else
{
EditorGUI.BeginDisabledGroup(true);
EditorGUILayout.Popup(Styles.smoothnessMapChannelText, 0, smoothnessChannelNames);
EditorGUI.EndDisabledGroup();
}
EditorGUI.showMixedValue = false;
EditorGUI.indentLevel--;
}
EditorGUI.indentLevel -= 2;
}
public static SmoothnessMapChannel GetSmoothnessMapChannel(Material material)
{
int ch = (int)material.GetFloat("_SmoothnessTextureChannel");
if (ch == (int)SmoothnessMapChannel.AlbedoAlpha)
return SmoothnessMapChannel.AlbedoAlpha;
return SmoothnessMapChannel.SpecularMetallicAlpha;
}
// (shared by all lit shaders, including shadergraph Lit Target and Lit.shader)
internal static void SetupSpecularWorkflowKeyword(Material material, out bool isSpecularWorkflow)
{
isSpecularWorkflow = false; // default is metallic workflow
if (material.HasProperty(Property.SpecularWorkflowMode))
isSpecularWorkflow = ((WorkflowMode)material.GetFloat(Property.SpecularWorkflowMode)) == WorkflowMode.Specular;
CoreUtils.SetKeyword(material, "_SPECULAR_SETUP", isSpecularWorkflow);
}
// setup keywords for Lit.shader
public static void SetMaterialKeywords(Material material)
{
SetupSpecularWorkflowKeyword(material, out bool isSpecularWorkFlow);
// 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)
var specularGlossMap = isSpecularWorkFlow ? "_SpecGlossMap" : "_MetallicGlossMap";
var hasGlossMap = material.GetTexture(specularGlossMap) != null;
CoreUtils.SetKeyword(material, "_METALLICSPECGLOSSMAP", hasGlossMap);
//if (material.HasProperty("_SpecularHighlights"))
// CoreUtils.SetKeyword(material, "_SPECULARHIGHLIGHTS_OFF",
// material.GetFloat("_SpecularHighlights") == 0.0f);
//if (material.HasProperty("_EnvironmentReflections"))
// CoreUtils.SetKeyword(material, "_ENVIRONMENTREFLECTIONS_OFF",
// material.GetFloat("_EnvironmentReflections") == 0.0f);
//if (material.HasProperty("_OcclusionMap"))
// CoreUtils.SetKeyword(material, "_OCCLUSIONMAP", material.GetTexture("_OcclusionMap"));
if (material.HasProperty("_ParallaxMap"))
CoreUtils.SetKeyword(material, "_PARALLAXMAP", material.GetTexture("_ParallaxMap"));
if (material.HasProperty("_SmoothnessTextureChannel"))
{
var opaque = IsOpaque(material);
CoreUtils.SetKeyword(material, "_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A",
GetSmoothnessMapChannel(material) == SmoothnessMapChannel.AlbedoAlpha && opaque);
}
// Clear coat keywords are independent to remove possiblity of invalid combinations.
if (ClearCoatEnabled(material))
{
var hasMap = material.HasProperty("_ClearCoatMap") && material.GetTexture("_ClearCoatMap") != null;
if (hasMap)
{
CoreUtils.SetKeyword(material, "_CLEARCOAT", false);
CoreUtils.SetKeyword(material, "_CLEARCOATMAP", true);
}
else
{
CoreUtils.SetKeyword(material, "_CLEARCOAT", true);
CoreUtils.SetKeyword(material, "_CLEARCOATMAP", false);
}
}
else
{
CoreUtils.SetKeyword(material, "_CLEARCOAT", false);
CoreUtils.SetKeyword(material, "_CLEARCOATMAP", false);
}
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b33851187d4324530b9f7abfe14d0137
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,119 @@
using System;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Scripting.APIUpdating;
namespace UnityEditor.Rendering.Universal.ShaderGUI
{
public static class SimpleLitGUI
{
public enum SpecularSource
{
SpecularTextureAndColor,
NoSpecular
}
public enum SmoothnessMapChannel
{
SpecularAlpha,
AlbedoAlpha,
}
public static class Styles
{
public static GUIContent specularMapText =
EditorGUIUtility.TrTextContent("Specular Map", "Designates a Specular Map and specular color determining the apperance of reflections on this Material's surface.");
}
public struct SimpleLitProperties
{
// Surface Input Props
public MaterialProperty specColor;
public MaterialProperty specGlossMap;
public MaterialProperty specHighlights;
public MaterialProperty smoothnessMapChannel;
public MaterialProperty smoothness;
public MaterialProperty bumpMapProp;
public SimpleLitProperties(MaterialProperty[] properties)
{
// Surface Input Props
specColor = BaseShaderGUI.FindProperty("_SpecColor", properties);
specGlossMap = BaseShaderGUI.FindProperty("_SpecGlossMap", properties, false);
specHighlights = BaseShaderGUI.FindProperty("_SpecularHighlights", properties, false);
smoothnessMapChannel = BaseShaderGUI.FindProperty("_SmoothnessSource", properties, false);
smoothness = BaseShaderGUI.FindProperty("_Smoothness", properties, false);
bumpMapProp = BaseShaderGUI.FindProperty("_BumpMap", properties, false);
}
}
public static void Inputs(SimpleLitProperties properties, MaterialEditor materialEditor, Material material)
{
DoSpecularArea(properties, materialEditor, material);
BaseShaderGUI.DrawNormalArea(materialEditor, properties.bumpMapProp);
}
public static void Advanced(SimpleLitProperties properties)
{
//SpecularSource specularSource = (SpecularSource)properties.specHighlights.floatValue;
//EditorGUI.BeginChangeCheck();
//EditorGUI.showMixedValue = properties.specHighlights.hasMixedValue;
//bool enabled = EditorGUILayout.Toggle(LitGUI.Styles.highlightsText, specularSource == SpecularSource.SpecularTextureAndColor);
//if (EditorGUI.EndChangeCheck())
// properties.specHighlights.floatValue = enabled ? (float)SpecularSource.SpecularTextureAndColor : (float)SpecularSource.NoSpecular;
//EditorGUI.showMixedValue = false;
}
public static void DoSpecularArea(SimpleLitProperties properties, MaterialEditor materialEditor, Material material)
{
//SpecularSource specSource = (SpecularSource)properties.specHighlights.floatValue;
//EditorGUI.BeginDisabledGroup(specSource == SpecularSource.NoSpecular);
BaseShaderGUI.TextureColorProps(materialEditor, Styles.specularMapText, properties.specGlossMap, properties.specColor, true);
LitGUI.DoSmoothness(materialEditor, material, properties.smoothness, properties.smoothnessMapChannel, LitGUI.Styles.specularSmoothnessChannelNames);
EditorGUI.EndDisabledGroup();
}
public static void SetMaterialKeywords(Material material)
{
UpdateMaterialSpecularSource(material);
}
private static void UpdateMaterialSpecularSource(Material material)
{
var opaque = ((BaseShaderGUI.SurfaceType)material.GetFloat("_Surface") ==
BaseShaderGUI.SurfaceType.Opaque);
//SpecularSource specSource = (SpecularSource)material.GetFloat("_SpecularHighlights");
//if (specSource == SpecularSource.NoSpecular)
//{
// CoreUtils.SetKeyword(material, "_SPECGLOSSMAP", false);
// CoreUtils.SetKeyword(material, "_SPECULAR_COLOR", false);
// CoreUtils.SetKeyword(material, "_GLOSSINESS_FROM_BASE_ALPHA", false);
//}
//else
{
//var smoothnessSource = (SmoothnessMapChannel)material.GetFloat("_SmoothnessSource");
bool hasMap = material.GetTexture("_SpecGlossMap");
CoreUtils.SetKeyword(material, "_SPECGLOSSMAP", hasMap);
CoreUtils.SetKeyword(material, "_SPECULAR_COLOR", !hasMap);
// if (opaque)
// CoreUtils.SetKeyword(material, "_GLOSSINESS_FROM_BASE_ALPHA", smoothnessSource == SmoothnessMapChannel.AlbedoAlpha);
// else
// CoreUtils.SetKeyword(material, "_GLOSSINESS_FROM_BASE_ALPHA", false);
string color;
// if (smoothnessSource != SmoothnessMapChannel.AlbedoAlpha || !opaque)
color = "_SpecColor";
//else
// color = "_BaseColor";
var col = material.GetColor(color);
float smoothness = material.GetFloat("_Smoothness");
if (smoothness != col.a)
{
col.a = smoothness;
material.SetColor(color, col);
}
}
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5f2b965a0132c42a4b52332918ed154a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 05b7540662f400d4aadac0c9efc5161b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,90 @@
.headerTogglebar {
height: var(--unity-metrics-single_line_large-height);
background-color: var(--unity-colors-inspector_titlebar-background);
margin-left: 0px;
margin-right: 0px;
margin-bottom: 0px;
padding-bottom: 3px;
}
.headerContent {
border-top-color: var(--unity-colors-inspector_titlebar-border_accent);
border-top-width: 1px;
margin-left: 0px;
margin-right: 0px;
margin-top: 0px;
margin-bottom: 0px;
padding-left: 20px;
padding-right: 5px;
padding-top: 5px;
padding-bottom: 5px;
}
.headerRoot {
border-bottom-color: var(--unity-colors-inspector_titlebar-border);
border-bottom-width: 1px;
margin-left: 0px;
margin-right: 0px;
padding-bottom: 0px;
}
.textureFieldThumb {
border-bottom-color: var(--unity-colors-button-border_accent);
border-bottom-width: 1px;
border-top-color: var(--unity-colors-button-border_accent);
border-top-width: 1px;
border-left-color: var(--unity-colors-button-border_accent);
border-left-width: 1px;
border-right-color: var(--unity-colors-button-border_accent);
border-right-width: 1px;
min-width: 26px;
min-height: 26px;
max-width: 26px;
max-height: 26px;
padding-left: 0px;
padding-right: 0px;
padding-top: 0px;
padding-bottom: 0px;
margin-left: 0px;
margin-right: 0px;
margin-top: 0px;
margin-bottom: 0px;
}
.textureFieldThumbOld {
border-bottom-width: 0px;
border-top-width: 0px;
border-left-width: 0px;
border-right-width: 0px;
width: 18px;
height: 18px;
padding-left: 0px;
padding-right: 0px;
padding-top: 0px;
padding-bottom: 0px;
margin-left: 0px;
margin-right: 0px;
margin-top: 0px;
margin-bottom: 0px;
}
.materialGUILeftBox
{
flex-basis: 40%;
flex-direction: row;
flex-shrink: 0.4;
flex-grow: 0.4;
text-overflow: ellipsis;
overflow: hidden;
min-width: 0;
}
.materialGUIRightBox
{
flex-basis: 60%;
flex-direction: row;
flex-shrink: 0.6;
flex-grow: 0.6;
text-overflow: ellipsis;
overflow: hidden;
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 23abfcaed80d7fa4e899c53d2b3a1a39
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0}
disableValidation: 0

View file

@ -0,0 +1,324 @@
using System;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEditor;
using UnityEngine.Experimental.Rendering;
namespace UnityEditor.Rendering.Universal
{
internal class TerrainLitShaderGUI : UnityEditor.ShaderGUI, ITerrainLayerCustomUI
{
private class StylesLayer
{
public readonly GUIContent warningHeightBasedBlending = new GUIContent("Height-based blending is disabled if you have more than four TerrainLayer materials!");
public readonly GUIContent enableHeightBlend = new GUIContent("Enable Height-based Blend", "Blend terrain layers based on height values.");
public readonly GUIContent heightTransition = new GUIContent("Height Transition", "Size in world units of the smooth transition between layers.");
public readonly GUIContent enableInstancedPerPixelNormal = new GUIContent("Enable Per-pixel Normal", "Enable per-pixel normal when the terrain uses instanced rendering.");
public readonly GUIContent diffuseTexture = new GUIContent("Diffuse");
public readonly GUIContent colorTint = new GUIContent("Color Tint");
public readonly GUIContent opacityAsDensity = new GUIContent("Opacity as Density", "Enable Density Blend (if unchecked, opacity is used as Smoothness)");
public readonly GUIContent normalMapTexture = new GUIContent("Normal Map");
public readonly GUIContent normalScale = new GUIContent("Normal Scale");
public readonly GUIContent maskMapTexture = new GUIContent("Mask", "R: Metallic\nG: AO\nB: Height\nA: Smoothness");
public readonly GUIContent maskMapTextureWithoutHeight = new GUIContent("Mask Map", "R: Metallic\nG: AO\nA: Smoothness");
public readonly GUIContent channelRemapping = new GUIContent("Channel Remapping");
public readonly GUIContent defaultValues = new GUIContent("Channel Default Values");
public readonly GUIContent metallic = new GUIContent("R: Metallic");
public readonly GUIContent ao = new GUIContent("G: AO");
public readonly GUIContent height = new GUIContent("B: Height");
public readonly GUIContent heightParametrization = new GUIContent("Parametrization");
public readonly GUIContent heightAmplitude = new GUIContent("Amplitude (cm)");
public readonly GUIContent heightBase = new GUIContent("Base (cm)");
public readonly GUIContent heightMin = new GUIContent("Min (cm)");
public readonly GUIContent heightMax = new GUIContent("Max (cm)");
public readonly GUIContent heightCm = new GUIContent("B: Height (cm)");
public readonly GUIContent smoothness = new GUIContent("A: Smoothness");
}
static StylesLayer s_Styles = null;
private static StylesLayer styles { get { if (s_Styles == null) s_Styles = new StylesLayer(); return s_Styles; } }
public TerrainLitShaderGUI()
{
}
// Height blend params
MaterialProperty enableHeightBlend = null;
const string kEnableHeightBlend = "_EnableHeightBlend";
MaterialProperty heightTransition = null;
const string kHeightTransition = "_HeightTransition";
// Per-pixel Normal (while instancing)
MaterialProperty enableInstancedPerPixelNormal = null;
const string kEnableInstancedPerPixelNormal = "_EnableInstancedPerPixelNormal";
private bool m_ShowChannelRemapping = false;
enum HeightParametrization
{
Amplitude,
MinMax
};
private HeightParametrization m_HeightParametrization = HeightParametrization.Amplitude;
private static bool DoesTerrainUseMaskMaps(TerrainLayer[] terrainLayers)
{
for (int i = 0; i < terrainLayers.Length; ++i)
{
if (terrainLayers[i].maskMapTexture != null)
return true;
}
return false;
}
protected void FindMaterialProperties(MaterialProperty[] props)
{
enableHeightBlend = FindProperty(kEnableHeightBlend, props, false);
heightTransition = FindProperty(kHeightTransition, props, false);
enableInstancedPerPixelNormal = FindProperty(kEnableInstancedPerPixelNormal, props, false);
}
static public void SetupMaterialKeywords(Material material)
{
bool enableHeightBlend = (material.HasProperty(kEnableHeightBlend) && material.GetFloat(kEnableHeightBlend) > 0);
CoreUtils.SetKeyword(material, "_TERRAIN_BLEND_HEIGHT", enableHeightBlend);
bool enableInstancedPerPixelNormal = material.GetFloat(kEnableInstancedPerPixelNormal) > 0.0f;
CoreUtils.SetKeyword(material, "_TERRAIN_INSTANCED_PERPIXEL_NORMAL", enableInstancedPerPixelNormal);
}
static public bool TextureHasAlpha(Texture2D inTex)
{
if (inTex != null)
{
return GraphicsFormatUtility.HasAlphaChannel(GraphicsFormatUtility.GetGraphicsFormat(inTex.format, true));
}
return false;
}
public override void OnGUI(MaterialEditor materialEditorIn, MaterialProperty[] properties)
{
if (materialEditorIn == null)
throw new ArgumentNullException("materialEditorIn");
FindMaterialProperties(properties);
bool optionsChanged = false;
EditorGUI.BeginChangeCheck();
{
if (enableHeightBlend != null)
{
EditorGUI.indentLevel++;
materialEditorIn.ShaderProperty(enableHeightBlend, styles.enableHeightBlend);
if (enableHeightBlend.floatValue > 0)
{
EditorGUI.indentLevel++;
EditorGUILayout.HelpBox(styles.warningHeightBasedBlending.text, MessageType.Info);
materialEditorIn.ShaderProperty(heightTransition, styles.heightTransition);
EditorGUI.indentLevel--;
}
EditorGUI.indentLevel--;
}
EditorGUILayout.Space();
}
if (EditorGUI.EndChangeCheck())
{
optionsChanged = true;
}
bool enablePerPixelNormalChanged = false;
// Since Instanced Per-pixel normal is actually dependent on instancing enabled or not, it is not
// important to check it in the GUI. The shader will make sure it is enabled/disabled properly.s
if (enableInstancedPerPixelNormal != null)
{
EditorGUI.indentLevel++;
EditorGUI.BeginChangeCheck();
materialEditorIn.ShaderProperty(enableInstancedPerPixelNormal, styles.enableInstancedPerPixelNormal);
enablePerPixelNormalChanged = EditorGUI.EndChangeCheck();
EditorGUI.indentLevel--;
}
if (optionsChanged || enablePerPixelNormalChanged)
{
foreach (var obj in materialEditorIn.targets)
{
SetupMaterialKeywords((Material)obj);
}
}
// We should always do this call at the end
materialEditorIn.serializedObject.ApplyModifiedProperties();
}
bool ITerrainLayerCustomUI.OnTerrainLayerGUI(TerrainLayer terrainLayer, Terrain terrain)
{
var terrainLayers = terrain.terrainData.terrainLayers;
// Don't use the member field enableHeightBlend as ShaderGUI.OnGUI might not be called if the material UI is folded.
// heightblend shouldn't be available if we are in multi-pass mode, because it is guaranteed to be broken.
bool heightBlendAvailable = (terrainLayers.Length <= 4);
bool heightBlend = heightBlendAvailable && terrain.materialTemplate.HasProperty(kEnableHeightBlend) && (terrain.materialTemplate.GetFloat(kEnableHeightBlend) > 0);
terrainLayer.diffuseTexture = EditorGUILayout.ObjectField(styles.diffuseTexture, terrainLayer.diffuseTexture, typeof(Texture2D), false) as Texture2D;
TerrainLayerUtility.ValidateDiffuseTextureUI(terrainLayer.diffuseTexture);
var diffuseRemapMin = terrainLayer.diffuseRemapMin;
var diffuseRemapMax = terrainLayer.diffuseRemapMax;
EditorGUI.BeginChangeCheck();
bool enableDensity = false;
if (terrainLayer.diffuseTexture != null)
{
var rect = GUILayoutUtility.GetLastRect();
rect.y += 16 + 4;
rect.width = EditorGUIUtility.labelWidth + 64;
rect.height = 16;
++EditorGUI.indentLevel;
var diffuseTint = new Color(diffuseRemapMax.x, diffuseRemapMax.y, diffuseRemapMax.z);
diffuseTint = EditorGUI.ColorField(rect, styles.colorTint, diffuseTint, true, false, false);
diffuseRemapMax.x = diffuseTint.r;
diffuseRemapMax.y = diffuseTint.g;
diffuseRemapMax.z = diffuseTint.b;
diffuseRemapMin.x = diffuseRemapMin.y = diffuseRemapMin.z = 0;
if (!heightBlend)
{
rect.y = rect.yMax + 2;
enableDensity = EditorGUI.Toggle(rect, styles.opacityAsDensity, diffuseRemapMin.w > 0);
}
--EditorGUI.indentLevel;
}
diffuseRemapMax.w = 1;
diffuseRemapMin.w = enableDensity ? 1 : 0;
if (EditorGUI.EndChangeCheck())
{
terrainLayer.diffuseRemapMin = diffuseRemapMin;
terrainLayer.diffuseRemapMax = diffuseRemapMax;
}
// Display normal map UI
terrainLayer.normalMapTexture = EditorGUILayout.ObjectField(styles.normalMapTexture, terrainLayer.normalMapTexture, typeof(Texture2D), false) as Texture2D;
TerrainLayerUtility.ValidateNormalMapTextureUI(terrainLayer.normalMapTexture, TerrainLayerUtility.CheckNormalMapTextureType(terrainLayer.normalMapTexture));
if (terrainLayer.normalMapTexture != null)
{
var rect = GUILayoutUtility.GetLastRect();
rect.y += 16 + 4;
rect.width = EditorGUIUtility.labelWidth + 64;
rect.height = 16;
++EditorGUI.indentLevel;
terrainLayer.normalScale = EditorGUI.FloatField(rect, styles.normalScale, terrainLayer.normalScale);
--EditorGUI.indentLevel;
}
// Display the mask map UI and the remap controls
terrainLayer.maskMapTexture = EditorGUILayout.ObjectField(heightBlend ? styles.maskMapTexture : styles.maskMapTextureWithoutHeight, terrainLayer.maskMapTexture, typeof(Texture2D), false) as Texture2D;
TerrainLayerUtility.ValidateMaskMapTextureUI(terrainLayer.maskMapTexture);
var maskMapRemapMin = terrainLayer.maskMapRemapMin;
var maskMapRemapMax = terrainLayer.maskMapRemapMax;
var smoothness = terrainLayer.smoothness;
var metallic = terrainLayer.metallic;
++EditorGUI.indentLevel;
EditorGUI.BeginChangeCheck();
m_ShowChannelRemapping = EditorGUILayout.Foldout(m_ShowChannelRemapping, terrainLayer.maskMapTexture != null ? s_Styles.channelRemapping : s_Styles.defaultValues);
if (m_ShowChannelRemapping)
{
if (terrainLayer.maskMapTexture != null)
{
float min, max;
min = maskMapRemapMin.x; max = maskMapRemapMax.x;
EditorGUILayout.MinMaxSlider(s_Styles.metallic, ref min, ref max, 0, 1);
maskMapRemapMin.x = min; maskMapRemapMax.x = max;
min = maskMapRemapMin.y; max = maskMapRemapMax.y;
EditorGUILayout.MinMaxSlider(s_Styles.ao, ref min, ref max, 0, 1);
maskMapRemapMin.y = min; maskMapRemapMax.y = max;
if (heightBlend)
{
EditorGUILayout.LabelField(styles.height);
++EditorGUI.indentLevel;
m_HeightParametrization = (HeightParametrization)EditorGUILayout.EnumPopup(styles.heightParametrization, m_HeightParametrization);
if (m_HeightParametrization == HeightParametrization.Amplitude)
{
// (height - heightBase) * amplitude
float amplitude = Mathf.Max(maskMapRemapMax.z - maskMapRemapMin.z, Mathf.Epsilon); // to avoid divide by zero
float heightBase = maskMapRemapMin.z / amplitude;
amplitude = EditorGUILayout.FloatField(styles.heightAmplitude, amplitude * 100) / 100;
heightBase = EditorGUILayout.FloatField(styles.heightBase, heightBase * 100) / 100;
maskMapRemapMin.z = heightBase * amplitude;
maskMapRemapMax.z = (1.0f - heightBase) * amplitude;
}
else
{
maskMapRemapMin.z = EditorGUILayout.FloatField(styles.heightMin, maskMapRemapMin.z * 100) / 100;
maskMapRemapMax.z = EditorGUILayout.FloatField(styles.heightMax, maskMapRemapMax.z * 100) / 100;
}
--EditorGUI.indentLevel;
}
min = maskMapRemapMin.w; max = maskMapRemapMax.w;
EditorGUILayout.MinMaxSlider(s_Styles.smoothness, ref min, ref max, 0, 1);
maskMapRemapMin.w = min; maskMapRemapMax.w = max;
}
else
{
metallic = EditorGUILayout.Slider(s_Styles.metallic, metallic, 0, 1);
// AO and Height are still exclusively controlled via the maskRemap controls
// metallic and smoothness have their own values as fields within the LayerData.
maskMapRemapMax.y = EditorGUILayout.Slider(s_Styles.ao, maskMapRemapMax.y, 0, 1);
if (heightBlend)
{
maskMapRemapMax.z = EditorGUILayout.FloatField(s_Styles.heightCm, maskMapRemapMax.z * 100) / 100;
}
// There's a possibility that someone could slide max below the existing min value
// so we'll just protect against that by locking the min value down a little bit.
// In the case of height (Z), we are trying to set min to no lower than zero value unless
// max goes negative. Zero is a good sensible value for the minimum. For AO (Y), we
// don't need this extra protection step because the UI blocks us from going negative
// anyway. In both cases, pushing the slider below the min value will lock them together,
// but min will be "left behind" if you go back up.
maskMapRemapMin.y = Mathf.Min(maskMapRemapMin.y, maskMapRemapMax.y);
maskMapRemapMin.z = Mathf.Min(Mathf.Max(0, maskMapRemapMin.z), maskMapRemapMax.z);
if (TextureHasAlpha(terrainLayer.diffuseTexture))
{
GUIStyle warnStyle = new GUIStyle(GUI.skin.label);
warnStyle.wordWrap = true;
GUILayout.Label("Smoothness is controlled by diffuse alpha channel", warnStyle);
}
else
smoothness = EditorGUILayout.Slider(s_Styles.smoothness, smoothness, 0, 1);
}
}
if (EditorGUI.EndChangeCheck())
{
terrainLayer.maskMapRemapMin = maskMapRemapMin;
terrainLayer.maskMapRemapMax = maskMapRemapMax;
terrainLayer.smoothness = smoothness;
terrainLayer.metallic = metallic;
}
--EditorGUI.indentLevel;
EditorGUILayout.Space();
TerrainLayerUtility.TilingSettingsUI(terrainLayer);
return true;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f2216b7cb5772784daf9ad851edda832
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: cb896df09ac2a2c4a8b8227a11cdb5c0
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,15 @@
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
using UnityEditor.UIElements;
namespace UnityEditor.SLZMaterialUI
{
public interface BaseMaterialField
{
public int GetShaderPropIdx();
public abstract void UpdateMaterialProperty(MaterialProperty boundProp);
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: da9d9cf7353fd9e42b955b549e395b8b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,133 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.UIElements;
using UnityEditor.UIElements;
namespace UnityEditor.SLZMaterialUI
{
public class EmissionToggleField : Toggle, BaseMaterialField
{
public int shaderPropertyIdx;
public int GetShaderPropIdx() { return shaderPropertyIdx; }
public MaterialProperty materialProperty;
bool isIntField = false;
string keyword;
public delegate void BeforeChangeEvent(ChangeEvent<bool> evt);
public void Initialize(MaterialProperty materialProperty, int shaderPropertyIdx, string keyword, bool isIntField, bool noStyle = false)
{
this.materialProperty = materialProperty;
this.shaderPropertyIdx = shaderPropertyIdx;
this.isIntField = isIntField;
this.keyword = keyword;
this.RegisterValueChangedCallback(OnChangedEvent);
bool state = false;
if (isIntField)
{
state = materialProperty.intValue != 0 ? true : false;
}
else
{
state = materialProperty.floatValue > 0 ? true : false;
}
this.SetValueWithoutNotify(state);
style.marginRight = 3;
if (materialProperty.hasMixedValue)
{
this.showMixedValue = true;
}
if (!noStyle)
{
label = materialProperty.displayName;
SetFullLineStyle();
}
}
public void SetFullLineStyle()
{
VisualElement label = this.ElementAt(0);
label.AddToClassList("materialGUILeftBox");
label.style.overflow = Overflow.Hidden;
label.style.minWidth = 0;
VisualElement color = this.ElementAt(1);
color.AddToClassList("materialGUIRightBox");
style.justifyContent = Justify.FlexStart;
}
public void OnChangedEvent(ChangeEvent<bool> evt)
{
if (isIntField)
{
materialProperty.intValue = evt.newValue ? 1 : 0;
}
else
{
materialProperty.floatValue = evt.newValue ? 1 : 0;
}
Object[] targets = materialProperty.targets;
int numMats = targets.Length;
// Setting the value through the materialProperty already recorded an undo, append to that
Undo.RecordObjects(targets, Undo.GetCurrentGroupName());
SetKeywordOnTargets(evt.newValue);
SetGIFlagsOnTargets(evt.newValue);
Undo.CollapseUndoOperations(Undo.GetCurrentGroup());
Undo.IncrementCurrentGroup();
this.showMixedValue = false;
}
void SetKeywordOnTargets(bool value)
{
if (keyword != null)
{
Object[] materials = materialProperty.targets;
int numMaterials = materials.Length;
Shader s = (materials[0] as Material).shader;
LocalKeyword kw = new LocalKeyword(s, keyword);
for (int i = 0; i < numMaterials; i++)
{
(materials[0] as Material).SetKeyword(kw, value);
}
}
}
void SetGIFlagsOnTargets(bool state)
{
Object[] materials = materialProperty.targets;
int numMaterials = materials.Length;
for (int i = 0; i < numMaterials; i++)
{
(materials[0] as Material).globalIlluminationFlags = state ? MaterialGlobalIlluminationFlags.BakedEmissive : MaterialGlobalIlluminationFlags.EmissiveIsBlack;
}
}
public void UpdateMaterialProperty(MaterialProperty boundProp)
{
materialProperty = boundProp;
bool state = false;
if (isIntField)
{
state = materialProperty.intValue != 0 ? true : false;
}
else
{
state = materialProperty.floatValue > 0 ? true : false;
}
if (value != state)
{
this.SetValueWithoutNotify(state);
}
this.showMixedValue = materialProperty.hasMixedValue;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 08421d46ab7f7614eadd68e4e7aca77c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,75 @@
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using UnityEngine;
using UnityEngine.UIElements;
using UnityEditor.UIElements;
using static UnityEngine.Rendering.DebugUI.MessageBox;
namespace UnityEditor.UIElements
{
public class GIFlagsPopup : PopupField<int>
{
static Dictionary<int, string> flagLabels = new Dictionary<int, string>()
{
{0, "None" },
{1, "Realtime" },
{2, "Baked" },
};
public GIFlagsPopup(SerializedObject serializedMaterial)
{
List<int> flags = new List<int>() { 0, 1, 2 };
this.choices = flags;
this.index = 2;
this.formatSelectedValueCallback = GetCurrentFlagName;
this.formatListItemCallback = GetValidFlagName;
this.bindingPath = "m_LightmapFlags";
this.label = "Global Illumination";
VisualElement label = ElementAt(0);
label.AddToClassList("materialGUILeftBox");
label.style.overflow = Overflow.Hidden;
label.style.minWidth = 0;
VisualElement dropdown = ElementAt(1);
dropdown.AddToClassList("materialGUIRightBox");
style.justifyContent = Justify.FlexStart;
style.marginRight = 3;
}
static string GetCurrentFlagName(int flag)
{
string label;
if (flagLabels.TryGetValue(flag, out label))
{
return label;
}
else
{
return "-";
}
}
static string GetValidFlagName(int flag)
{
return flagLabels[flag];
}
class RenderQueueIntField : IntegerField
{
public int defaultQueue = 2000;
protected override string ValueToString(int v)
{
if (v == -1)
{
return defaultQueue.ToString();
}
return v.ToString(base.formatString, CultureInfo.InvariantCulture.NumberFormat);
}
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6a738a0b3f474af46bd9cf980c7b0627
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,65 @@
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEditor.SLZMaterialUI;
using UnityEditor.UIElements;
using UnityEngine;
using UnityEngine.UIElements;
namespace UnityEditor.SLZMaterialUI
{
public class MaterialColorField : ColorField, BaseMaterialField
{
public int shaderPropertyIdx;
public int GetShaderPropIdx() { return shaderPropertyIdx; }
public MaterialProperty materialProperty;
public void Initialize(MaterialProperty materialProperty, int shaderPropertyIdx, bool isPartOfTexField)
{
this.materialProperty = materialProperty;
this.shaderPropertyIdx = shaderPropertyIdx;
this.RegisterValueChangedCallback(OnChangedEvent);
this.SetValueWithoutNotify(materialProperty.colorValue);
style.marginRight = 3;
if (materialProperty.hasMixedValue)
{
//this.SetValueWithoutNotify(Color.gray);
this.showMixedValue = true;
}
if (isPartOfTexField)
{
style.alignSelf = Align.Center;
style.flexGrow = 1;
style.flexShrink = 1;
}
else
{
label = materialProperty.displayName;
SetFullLineStyle();
}
}
public void SetFullLineStyle()
{
VisualElement label = this.ElementAt(0);
label.AddToClassList("materialGUILeftBox");
label.style.overflow = Overflow.Hidden;
label.style.minWidth = 0;
VisualElement color = this.ElementAt(1);
color.AddToClassList("materialGUIRightBox");
style.justifyContent = Justify.FlexStart;
}
public void OnChangedEvent(ChangeEvent<Color> evt)
{
materialProperty.colorValue = evt.newValue;
this.showMixedValue = false;
}
public void UpdateMaterialProperty(MaterialProperty boundProp)
{
if (value != boundProp.colorValue)
{
this.SetValueWithoutNotify(boundProp.colorValue);
}
this.showMixedValue = boundProp.hasMixedValue;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b97e041999f2d4a43ad1f83584415ce1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,47 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor.UIElements;
using UnityEngine.UIElements;
namespace UnityEditor.SLZMaterialUI
{
public class MaterialDummyField : INotifyValueChanged<float>, BaseMaterialField
{
public int shaderPropertyIdx;
public int GetShaderPropIdx() { return shaderPropertyIdx; }
public MaterialProperty materialProperty;
float m_value;
public float value
{
get { return m_value; }
set {
if (m_value != value)
{
m_value = value;
materialProperty.floatValue = m_value;
}
}
}
public MaterialDummyField(MaterialProperty materialProperty, int shaderPropertyIdx)
{
this.materialProperty = materialProperty;
this.shaderPropertyIdx = shaderPropertyIdx;
SetValueWithoutNotify(materialProperty.floatValue);
}
public void UpdateMaterialProperty(MaterialProperty boundProp)
{
materialProperty = boundProp;
if (value != boundProp.floatValue)
{
this.SetValueWithoutNotify(boundProp.floatValue);
}
}
public void SetValueWithoutNotify(float value)
{
m_value = value;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0a5fccb07f24f1146b93d089e493e007
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,92 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using Unity.Collections.LowLevel.Unsafe;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEditor.UIElements;
using UnityEngine.UIElements;
namespace UnityEditor.SLZMaterialUI
{
public class MaterialEmissionFlagsField : VisualElement
{
static EnumFieldUtils.EnumData s_EmissionFlags;
static EnumFieldUtils.EnumData emissionFlags
{
get
{
if (s_EmissionFlags == null)
{
s_EmissionFlags = new EnumFieldUtils.EnumData()
{
values = new Enum[] { MaterialGlobalIlluminationFlags.EmissiveIsBlack, MaterialGlobalIlluminationFlags.RealtimeEmissive, MaterialGlobalIlluminationFlags.BakedEmissive },
flagValues = new int[] { 0, 1, 2 },
displayNames = new string[] { "None", "Realtime", "Baked" },
names = new string[] { "EmissiveIsBlack", "RealtimeEmissive", "BakedEmissive" },
tooltip = new string[] { "Emission will not emit light during light baking", "Emission will be treated as a real-time source when baking realtime GI", "Emission will emit light when baking lighting" },
flags = true,
underlyingType = typeof(MaterialGlobalIlluminationFlags),
unsigned = false,
serializable = true,
};
}
return s_EmissionFlags;
}
}
static object s_BoxedEnumData;
static object boxedEnumData
{
get
{
if (s_BoxedEnumData == null)
{
s_BoxedEnumData = EnumFieldUtils.GetBoxedEnumData(emissionFlags);
}
return s_BoxedEnumData;
}
}
static Action<EnumField, Enum> s_UpdateValueLabelAction;
static Action<EnumField, Enum> UpdateValueLabelAction
{
get
{
if (s_UpdateValueLabelAction == null)
{
MethodInfo updateValueInfo = typeof(EnumField).GetMethod("UpdateValueLabel", BindingFlags.Instance | BindingFlags.NonPublic);
s_UpdateValueLabelAction = (Action<EnumField, Enum>) updateValueInfo.CreateDelegate(typeof(Action<EnumField, Enum>));
}
return s_UpdateValueLabelAction;
}
}
public EnumField internalField;
public MaterialEmissionFlagsField(string label, MaterialGlobalIlluminationFlags defaultValue)
{
internalField = new EnumField(label, defaultValue);
SetEnumData(internalField);
EnumFieldUtils.UpdateValueLabelAction(internalField, defaultValue);
VisualElement labelElement = internalField.ElementAt(0);
labelElement.AddToClassList("materialGUILeftBox");
labelElement.style.overflow = Overflow.Hidden;
labelElement.style.minWidth = 0;
VisualElement dropdownElement = internalField.ElementAt(1);
dropdownElement.AddToClassList("materialGUIRightBox");
style.justifyContent = Justify.FlexStart;
Add(internalField);
}
public void SetEnumData(EnumField field)
{
EnumFieldUtils.enumDataField.SetValue(field, boxedEnumData);
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1d6b65ddfa2dcdb459c9ebc448986435
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,55 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor.UIElements;
using UnityEngine.UIElements;
namespace UnityEditor.SLZMaterialUI
{
public class MaterialFloatField : FloatField, BaseMaterialField
{
public int shaderPropertyIdx;
public int GetShaderPropIdx() { return shaderPropertyIdx; }
public MaterialProperty materialProperty;
public void Initialize(MaterialProperty materialProperty, int shaderPropertyIdx)
{
this.materialProperty = materialProperty;
this.shaderPropertyIdx = shaderPropertyIdx;
this.RegisterValueChangedCallback(OnChangedEvent);
this.SetValueWithoutNotify(materialProperty.floatValue);
style.marginRight = 3;
if (materialProperty.hasMixedValue)
{
//this.SetValueWithoutNotify(Color.gray);
this.showMixedValue = true;
}
label = materialProperty.displayName;
SetFullLineStyle();
}
public void SetFullLineStyle()
{
VisualElement label = this.ElementAt(0);
label.AddToClassList("materialGUILeftBox");
label.style.overflow = Overflow.Hidden;
label.style.minWidth = 0;
VisualElement color = this.ElementAt(1);
color.AddToClassList("materialGUIRightBox");
style.justifyContent = Justify.FlexStart;
}
public void OnChangedEvent(ChangeEvent<float> evt)
{
materialProperty.floatValue = evt.newValue;
this.showMixedValue = false;
}
public void UpdateMaterialProperty(MaterialProperty boundProp)
{
materialProperty = boundProp;
if (value != boundProp.floatValue)
{
this.SetValueWithoutNotify(boundProp.floatValue);
}
this.showMixedValue = boundProp.hasMixedValue;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8d3da44cdff624d4ebb0c6b43ad59f8a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,55 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
using UnityEditor.UIElements;
namespace UnityEditor.SLZMaterialUI
{
public class MaterialIntField : IntegerField, BaseMaterialField
{
public int shaderPropertyIdx;
public int GetShaderPropIdx() { return shaderPropertyIdx; }
public MaterialProperty materialProperty;
public void Initialize(MaterialProperty materialProperty, int shaderPropertyIdx)
{
this.materialProperty = materialProperty;
this.shaderPropertyIdx = shaderPropertyIdx;
this.RegisterValueChangedCallback(OnChangedEvent);
this.SetValueWithoutNotify(materialProperty.intValue);
style.marginRight = 3;
if (materialProperty.hasMixedValue)
{
//this.SetValueWithoutNotify(Color.gray);
this.showMixedValue = true;
}
label = materialProperty.displayName;
SetFullLineStyle();
}
public void SetFullLineStyle()
{
VisualElement label = this.ElementAt(0);
label.AddToClassList("materialGUILeftBox");
label.style.overflow = Overflow.Hidden;
label.style.minWidth = 0;
VisualElement color = this.ElementAt(1);
color.AddToClassList("materialGUIRightBox");
style.justifyContent = Justify.FlexStart;
}
public void OnChangedEvent(ChangeEvent<int> evt)
{
materialProperty.intValue = evt.newValue;
this.showMixedValue = false;
}
public void UpdateMaterialProperty(MaterialProperty boundProp)
{
materialProperty = boundProp;
if (value != boundProp.intValue)
{
this.SetValueWithoutNotify(boundProp.intValue);
}
this.showMixedValue = boundProp.hasMixedValue;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7fa327141ed044147b9a2efea174b00c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,82 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.UIElements;
namespace UnityEditor.SLZMaterialUI
{
public class MaterialIntPopup : PopupField<int>, BaseMaterialField
{
public int shaderPropertyIdx;
public int GetShaderPropIdx() { return shaderPropertyIdx; }
public MaterialProperty materialProperty;
Dictionary<int, string> choiceLabels;
public void Initialize(MaterialProperty materialProperty, int shaderPropertyIdx, List<int> choices, Dictionary<int, string> choiceLabels)
{
this.materialProperty = materialProperty;
this.shaderPropertyIdx = shaderPropertyIdx;
this.choices = choices;
this.choiceLabels = choiceLabels;
this.formatSelectedValueCallback = GetCurrentFlagName;
this.formatListItemCallback = GetValidFlagName;
VisualElement label = ElementAt(0);
label.AddToClassList("materialGUILeftBox");
label.style.overflow = Overflow.Hidden;
label.style.minWidth = 0;
VisualElement dropdown = ElementAt(1);
dropdown.AddToClassList("materialGUIRightBox");
style.justifyContent = Justify.FlexStart;
style.marginRight = 3;
RegisterCallback<ChangeEvent<int>>(evt =>
{
materialProperty.floatValue = (float)evt.newValue;
}
);
this.SetValueWithoutNotify((int)materialProperty.floatValue);
}
public void UpdateMaterialProperty(MaterialProperty boundProp)
{
materialProperty = boundProp;
int newVal = (int)boundProp.floatValue;
if (this.value != newVal)
{
this.SetValueWithoutNotify(newVal);
}
this.showMixedValue = boundProp.hasMixedValue;
}
string GetCurrentFlagName(int type)
{
string label;
if (choiceLabels.TryGetValue(type, out label))
{
return label;
}
else
{
return "-";
}
}
string GetValidFlagName(int type)
{
return choiceLabels[type];
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2a265e5d4ddf6f44c9f8c719875f1428
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,60 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
using UnityEditor.UIElements;
namespace UnityEditor.SLZMaterialUI
{
public class MaterialIntRangeField : SliderInt, BaseMaterialField
{
public int shaderPropertyIdx;
public int GetShaderPropIdx() { return shaderPropertyIdx; }
public MaterialProperty materialProperty;
public void Initialize(MaterialProperty materialProperty, int shaderPropertyIdx)
{
this.materialProperty = materialProperty;
this.shaderPropertyIdx = shaderPropertyIdx;
this.RegisterValueChangedCallback(OnChangedEvent);
this.SetValueWithoutNotify((int)materialProperty.floatValue);
this.lowValue = (int)materialProperty.rangeLimits.x;
this.highValue = (int)materialProperty.rangeLimits.y;
this.showInputField = true;
style.marginRight = 3;
if (materialProperty.hasMixedValue)
{
//this.SetValueWithoutNotify(Color.gray);
this.showMixedValue = true;
}
label = materialProperty.displayName;
SetFullLineStyle();
}
public void SetFullLineStyle()
{
VisualElement label = this.ElementAt(0);
label.AddToClassList("materialGUILeftBox");
label.style.overflow = Overflow.Hidden;
label.style.minWidth = 0;
VisualElement color = this.ElementAt(1);
color.AddToClassList("materialGUIRightBox");
style.justifyContent = Justify.FlexStart;
}
public void OnChangedEvent(ChangeEvent<int> evt)
{
materialProperty.floatValue = evt.newValue; // Int ranges are still floats...
this.showMixedValue = false;
}
public void UpdateMaterialProperty(MaterialProperty boundProp)
{
materialProperty = boundProp;
if (value != boundProp.floatValue)
{
this.SetValueWithoutNotify((int)boundProp.floatValue);
this.lowValue = (int)boundProp.rangeLimits.x;
this.highValue = (int)boundProp.rangeLimits.y;
}
this.showMixedValue = boundProp.hasMixedValue;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d75b03261072c5d458af914c4ed8d432
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,61 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
using UnityEditor.UIElements;
namespace UnityEditor.SLZMaterialUI
{
public class MaterialRangeField : Slider, BaseMaterialField
{
public int shaderPropertyIdx;
public int GetShaderPropIdx() { return shaderPropertyIdx; }
public MaterialProperty materialProperty;
public void Initialize(MaterialProperty materialProperty, int shaderPropertyIdx)
{
this.materialProperty = materialProperty;
this.shaderPropertyIdx = shaderPropertyIdx;
this.RegisterValueChangedCallback(OnChangedEvent);
this.SetValueWithoutNotify(materialProperty.floatValue);
this.lowValue = materialProperty.rangeLimits.x;
this.highValue = materialProperty.rangeLimits.y;
this.showInputField = true;
style.marginRight = 3;
if (materialProperty.hasMixedValue)
{
//this.SetValueWithoutNotify(Color.gray);
this.showMixedValue = true;
}
label = materialProperty.displayName;
SetFullLineStyle();
}
public void SetFullLineStyle()
{
VisualElement label = this.ElementAt(0);
label.AddToClassList("materialGUILeftBox");
label.style.overflow = Overflow.Hidden;
label.style.minWidth = 0;
VisualElement color = this.ElementAt(1);
color.AddToClassList("materialGUIRightBox");
style.justifyContent = Justify.FlexStart;
}
public void OnChangedEvent(ChangeEvent<float> evt)
{
materialProperty.floatValue = evt.newValue;
this.showMixedValue = false;
}
public void UpdateMaterialProperty(MaterialProperty boundProp)
{
materialProperty = boundProp;
if (value != boundProp.floatValue)
{
this.SetValueWithoutNotify(boundProp.floatValue);
this.lowValue = boundProp.rangeLimits.x;
this.highValue = boundProp.rangeLimits.y;
}
this.showMixedValue = boundProp.hasMixedValue;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8774bd78aca1ca1438a7328c4e7691a0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,82 @@
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEditor.SLZMaterialUI;
using UnityEngine;
using UnityEngine.UIElements;
using UnityEditor.UIElements;
namespace UnityEditor.SLZMaterialUI
{
public class MaterialScaleOffsetField : VisualElement, BaseMaterialField
{
public int shaderPropertyIdx;
public int GetShaderPropIdx() { return shaderPropertyIdx; }
public MaterialProperty materialProperty;
Vector2Field tilingField;
Vector2Field offsetField;
public Vector4 value;
public MaterialScaleOffsetField(MaterialProperty boundProp, int shaderPropertyIdx)
{
this.materialProperty = boundProp;
this.shaderPropertyIdx = shaderPropertyIdx;
value = boundProp.textureScaleAndOffset;
tilingField = new Vector2Field();
tilingField.style.marginRight = 4;
tilingField.label = "Tiling";
VisualElement tilingLabel = tilingField.ElementAt(0);
VisualElement tilingInput = tilingField.ElementAt(1);
tilingInput.RemoveAt(2);
tilingLabel.AddToClassList("materialGUILeftBox");
tilingInput.AddToClassList("materialGUIRightBox");
tilingField.SetValueWithoutNotify(new Vector2(value.x, value.y));
tilingField.RegisterValueChangedCallback(OnChangedEventTiling);
offsetField = new Vector2Field();
offsetField.style.marginRight = 4;
offsetField.label = "Offset";
VisualElement offsetLabel = offsetField.ElementAt(0);
VisualElement offsetInput = offsetField.ElementAt(1);
offsetInput.RemoveAt(2);
offsetLabel.AddToClassList("materialGUILeftBox");
offsetInput.AddToClassList("materialGUIRightBox");
offsetField.SetValueWithoutNotify(new Vector2(value.z, value.w));
offsetField.RegisterValueChangedCallback(OnChangedEventOffset);
Add(tilingField);
Add(offsetField);
}
public void OnChangedEventTiling(ChangeEvent<Vector2> evt)
{
Vector4 scaleOffset = new Vector4(evt.newValue.x, evt.newValue.y, value.z, value.w);
value = scaleOffset;
materialProperty.textureScaleAndOffset = scaleOffset;
tilingField.showMixedValue = false;
}
public void OnChangedEventOffset(ChangeEvent<Vector2> evt)
{
Vector4 scaleOffset = new Vector4(value.x, value.y, evt.newValue.x, evt.newValue.y);
value = scaleOffset;
materialProperty.textureScaleAndOffset = scaleOffset;
tilingField.showMixedValue = false;
}
public void UpdateMaterialProperty(MaterialProperty boundProp)
{
materialProperty = boundProp;
if (value != boundProp.textureScaleAndOffset)
{
value = boundProp.textureScaleAndOffset;
Vector2 scale = new Vector2(value.x, value.y);
Vector2 offset = new Vector2(value.z, value.w);
tilingField.SetValueWithoutNotify(scale);
offsetField.SetValueWithoutNotify(offset);
}
tilingField.showMixedValue = materialProperty.hasMixedValue;
offsetField.showMixedValue = materialProperty.hasMixedValue;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2f7b4173acb2fca4999ffa4a8b1ad615
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,125 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.UIElements;
using UnityEditor.UIElements;
namespace UnityEditor.SLZMaterialUI
{
public class MaterialToggleField : Toggle, BaseMaterialField
{
public int shaderPropertyIdx;
public int GetShaderPropIdx() { return shaderPropertyIdx; }
public MaterialProperty materialProperty;
bool isIntField = false;
string keyword;
public delegate void BeforeChangeEvent(ChangeEvent<bool> evt);
//public BeforeChangeEvent BeforeChange;
public void Initialize(MaterialProperty materialProperty, int shaderPropertyIdx, string keyword, bool isIntField, bool noStyle = false)
{
this.materialProperty = materialProperty;
this.shaderPropertyIdx = shaderPropertyIdx;
this.isIntField = isIntField;
this.keyword = keyword;
this.RegisterValueChangedCallback(OnChangedEvent);
bool state = false;
if (isIntField)
{
state = materialProperty.intValue != 0 ? true : false;
}
else
{
state = materialProperty.floatValue > 0 ? true : false;
}
this.SetValueWithoutNotify(state);
style.marginRight = 3;
if (materialProperty.hasMixedValue)
{
this.showMixedValue = true;
}
if (!noStyle)
{
label = materialProperty.displayName;
SetFullLineStyle();
}
}
public void SetFullLineStyle()
{
VisualElement label = this.ElementAt(0);
label.AddToClassList("materialGUILeftBox");
label.style.overflow = Overflow.Hidden;
label.style.minWidth = 0;
VisualElement color = this.ElementAt(1);
color.AddToClassList("materialGUIRightBox");
style.justifyContent = Justify.FlexStart;
}
public void OnChangedEvent(ChangeEvent<bool> evt)
{
//BeforeChange.Invoke(evt);
if (isIntField)
{
materialProperty.intValue = evt.newValue ? 1 : 0;
}
else
{
materialProperty.floatValue = evt.newValue ? 1 : 0;
}
if (keyword != null)
{
Object[] targets = materialProperty.targets;
int numMats = targets.Length;
// Setting the value through the materialProperty already recorded an undo, append to that
Undo.RecordObjects(targets, Undo.GetCurrentGroupName());
}
SetKeywordOnTargets(evt.newValue);
if (keyword != null)
{
Undo.CollapseUndoOperations(Undo.GetCurrentGroup());
Undo.IncrementCurrentGroup();
}
this.showMixedValue = false;
}
void SetKeywordOnTargets(bool value)
{
if (keyword != null)
{
Object[] materials = materialProperty.targets;
int numMaterials = materials.Length;
Shader s = (materials[0] as Material).shader;
LocalKeyword kw = new LocalKeyword(s, keyword);
for (int i = 0; i < numMaterials; i++)
{
(materials[0] as Material).SetKeyword(kw, value);
}
}
}
public void UpdateMaterialProperty(MaterialProperty boundProp)
{
materialProperty = boundProp;
bool state = false;
if (isIntField)
{
state = materialProperty.intValue != 0 ? true : false;
}
else
{
state = materialProperty.floatValue > 0 ? true : false;
}
if (this.value != state)
{
this.SetValueWithoutNotify(state);
}
this.showMixedValue = materialProperty.hasMixedValue;
//MarkDirtyRepaint();
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fbe8648b2f113f641a3c1a49f43dcfcd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,58 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
using UnityEditor.UIElements;
namespace UnityEditor.SLZMaterialUI
{
public class MaterialVectorField : Vector4Field, BaseMaterialField
{
public int shaderPropertyIdx;
public int GetShaderPropIdx() { return shaderPropertyIdx; }
public MaterialProperty materialProperty;
public void Initialize(MaterialProperty materialProperty, int shaderPropertyIdx)
{
this.materialProperty = materialProperty;
this.shaderPropertyIdx = shaderPropertyIdx;
this.RegisterValueChangedCallback(OnChangedEvent);
this.SetValueWithoutNotify(materialProperty.vectorValue);
style.marginRight = 3;
if (materialProperty.hasMixedValue)
{
//this.SetValueWithoutNotify(Color.gray);
this.showMixedValue = true;
}
label = materialProperty.displayName;
SetFullLineStyle();
}
public void SetFullLineStyle()
{
VisualElement label = this.ElementAt(0);
label.AddToClassList("materialGUILeftBox");
label.style.overflow = Overflow.Hidden;
label.style.minWidth = 0;
VisualElement color = this.ElementAt(1);
color.AddToClassList("materialGUIRightBox");
style.justifyContent = Justify.FlexStart;
}
public void OnChangedEvent(ChangeEvent<Vector4> evt)
{
materialProperty.vectorValue = evt.newValue;
this.showMixedValue = false;
}
public void UpdateMaterialProperty(MaterialProperty boundProp)
{
materialProperty = boundProp;
if (this.value != boundProp.vectorValue)
{
this.SetValueWithoutNotify(boundProp.vectorValue);
}
this.showMixedValue = boundProp.hasMixedValue;
//MarkDirtyRepaint();
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ba3f18a26aea39a48851c4f24b173f72
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,125 @@
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using UnityEngine;
using UnityEngine.UIElements;
using UnityEditor.UIElements;
namespace UnityEditor.UIElements
{
public class RenderQueueDropdown : VisualElement, INotifyValueChanged<int>
{
public PopupField<int> renderQueuePresets;
RenderQueueIntField renderQueueCustom;
int m_value;
public int value
{
get { return m_value; }
set {
if (value == defaultRenderQueue)
SetValue(-1);
else
SetValue(value);
}
}
int defaultRenderQueue;
Dictionary<int, string> queueLabels = new Dictionary<int, string>()
{
{-1, " From Shader " },
{1000, " Background " },
{2000, " Geometry " },
{2450, " Alpha Test " },
{3000, " Transparent " }
};
public RenderQueueDropdown(SerializedObject serializedMaterial, Shader shader)
{
this.style.flexDirection = FlexDirection.Row;
//this.style.
this.style.alignSelf = Align.Stretch;
this.style.alignItems = Align.Stretch;
this.style.flexWrap = Wrap.NoWrap;
this.style.justifyContent = Justify.SpaceBetween;
this.defaultRenderQueue = shader.renderQueue;
this.AddToClassList("unity-base-field");
List<int> queues = new List<int>() { -1, 1000, 2000, 2450, 3000 };
//SerializedProperty renderQueueProp = serializedMaterial.FindProperty("m_CustomRenderQueue");
renderQueuePresets = new PopupField<int>(queues, -1, GetCurrentQueueName, GetValidQueueName);
//renderQueuePresets.style.minWidth = 9 * 12;
renderQueuePresets.bindingPath = "m_CustomRenderQueue";
//renderQueuePresets.Bind(serializedMaterial);
renderQueuePresets.style.width = 100;
renderQueueCustom = new RenderQueueIntField();
renderQueueCustom.defaultQueue = shader.renderQueue;
renderQueueCustom.style.width = 48;
renderQueueCustom.bindingPath = "m_CustomRenderQueue";
//renderQueueCustom.Bind(serializedMaterial);
renderQueueCustom.style.unityTextAlign = TextAnchor.MiddleRight;
VisualElement renderQueueGroup = new VisualElement();
renderQueueGroup.style.flexDirection = FlexDirection.Row;
renderQueueGroup.style.flexShrink = 0;
renderQueueGroup.style.marginRight = 4;
renderQueueGroup.Add(renderQueuePresets);
renderQueueGroup.Add(renderQueueCustom);
Label label = new Label("Render Queue");
label.style.alignSelf = Align.Center;
label.style.textOverflow = TextOverflow.Ellipsis;
label.style.flexShrink = 1;
Add(label);
Add(renderQueueGroup);
}
string GetCurrentQueueName(int queue)
{
string label;
if (queueLabels.TryGetValue(queue, out label))
{
return label;
}
else
{
return "Custom";
}
}
string GetValidQueueName(int queue)
{
return queueLabels[queue];
}
class RenderQueueIntField : IntegerField
{
public int defaultQueue = 2000;
protected override string ValueToString(int v)
{
if (v == -1)
{
return defaultQueue.ToString();
}
return v.ToString(base.formatString, CultureInfo.InvariantCulture.NumberFormat);
}
}
public void SetValue(int value)
{
if (value == defaultRenderQueue) value = -1;
m_value = value;
renderQueuePresets.value = value;
renderQueueCustom.SetValueWithoutNotify(value);
}
public void SetValueWithoutNotify(int value)
{
if (value == defaultRenderQueue) value = -1;
m_value = value;
renderQueuePresets.SetValueWithoutNotify(value);
renderQueueCustom.SetValueWithoutNotify(value);
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a93dcfdc27a47f54c8409794026ed59a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,138 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.UIElements;
namespace UnityEditor.SLZMaterialUI
{
public class SurfaceTypeField : PopupField<int>, BaseMaterialField
{
public int shaderPropertyIdx;
public int GetShaderPropIdx() { return shaderPropertyIdx; }
public MaterialProperty materialProperty;
MaterialProperty MaterialProperty { get { return materialProperty; } }
public INotifyValueChanged<float> blendSrc;
public INotifyValueChanged<float> blendDst;
public INotifyValueChanged<float> zWrite;
public INotifyValueChanged<int> renderQueue;
enum SurfaceTypes
{
Opaque = 0,
Transparent = 1,
Fade = 2,
}
static Dictionary<int, string> surfaceLabels = new Dictionary<int, string>()
{
{0, "Opaque" },
{1, "Transparent" },
{2, "Fade" },
};
static Span<int> SurfaceQueue => new int[] { 2000, 3000, 3000 };
static Span<int> SurfaceBlendSrc => new int[] { (int)BlendMode.One, (int)BlendMode.One, (int)BlendMode.SrcAlpha };
static Span<int> SurfaceBlendDst => new int[] { (int)BlendMode.Zero, (int)BlendMode.OneMinusSrcAlpha, (int)BlendMode.OneMinusSrcAlpha };
static Span<int> SurfaceZWrite => new int[] { 1, 0, 0 };
public void Initialize(MaterialProperty materialProperty, int shaderPropertyIdx,
INotifyValueChanged<float> blendSrc,
INotifyValueChanged<float> blendDst,
INotifyValueChanged<float> zWrite,
INotifyValueChanged<int> queueField)
{
this.formatSelectedValueCallback = GetCurrentFlagName;
this.formatListItemCallback = GetValidFlagName;
this.materialProperty = materialProperty;
this.shaderPropertyIdx = shaderPropertyIdx;
this.blendSrc = blendSrc;
this.blendDst = blendDst;
this.zWrite = zWrite;
this.renderQueue = queueField;
this.label = "Surface Type";
this.choices = new List<int>() { 0, 1, 2 };
VisualElement label = ElementAt(0);
label.AddToClassList("materialGUILeftBox");
label.style.overflow = Overflow.Hidden;
label.style.minWidth = 0;
VisualElement dropdown = ElementAt(1);
dropdown.AddToClassList("materialGUIRightBox");
style.justifyContent = Justify.FlexStart;
style.marginRight = 3;
RegisterCallback<ChangeEvent<int>>(evt =>
{
int newVal = evt.newValue;
Debug.Log("Trying to set surface to " + newVal);
UnityEngine.Object[] targets = MaterialProperty.targets;
//MaterialProperty.floatValue = newVal;
int numTargets = targets.Length;
Undo.IncrementCurrentGroup();
Undo.RecordObjects(targets, "Set Surface Type");
Shader s = ((Material)targets[0]).shader;
int surfIdx = s.FindPropertyIndex("_Surface");
int blendSrcIdx = s.FindPropertyIndex("_BlendSrc");
int blendDstIdx = s.FindPropertyIndex("_BlendDst");
int zWriteIdx = s.FindPropertyIndex("_ZWrite");
Debug.Log(string.Format("Num Targets: {4}, _Surface: {0}, _BlendSrc:{1}, _BlendDst:{2}, _ZWrite:{3} ", surfIdx, blendSrcIdx, blendDstIdx, zWriteIdx, numTargets));
int queue = SurfaceQueue[newVal];
queue = queue == s.renderQueue ? -1 : queue;
for (int i = 0; i < numTargets; i++)
{
Material mat = (Material)targets[i];
mat.SetFloat("_Surface", newVal);
mat.SetFloat("_BlendSrc", SurfaceBlendSrc[newVal]);
mat.SetFloat("_BlendDst", SurfaceBlendDst[newVal]);
mat.SetFloat("_ZWrite", SurfaceZWrite[newVal]);
mat.renderQueue = queue;
}
queueField.SetValueWithoutNotify(SurfaceQueue[newVal]);
Undo.CollapseUndoOperations(Undo.GetCurrentGroup());
}
);
this.SetValueWithoutNotify((int)materialProperty.floatValue);
}
public void UpdateMaterialProperty(MaterialProperty boundProp)
{
materialProperty = boundProp;
int newVal = (int)boundProp.floatValue;
if (this.value != newVal)
{
this.SetValueWithoutNotify(newVal);
}
this.showMixedValue = boundProp.hasMixedValue;
}
static string GetCurrentFlagName(int type)
{
string label;
if (surfaceLabels.TryGetValue(type, out label))
{
return label;
}
else
{
return "-";
}
}
static string GetValidFlagName(int type)
{
return surfaceLabels[type];
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6e24e45408716b14ca04c507eff19c04
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,365 @@
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.UIElements;
using UnityEditor.UIElements;
using static UnityEngine.UI.InputField;
using Object = UnityEngine.Object;
using System;
using SLZ.SLZEditorTools;
using UnityEngine.Rendering;
namespace UnityEditor.SLZMaterialUI
{
public class TextureField : VisualElement, BaseMaterialField
{
public MaterialProperty textureProperty;
public VisualElement leftAlignBox { get; private set; }
public VisualElement rightAlignBox { get; private set; }
public string tooltip2 { get { return texObjField.tooltip; } set { texObjField.tooltip = value; } }
public Texture defaultTexture;
public UnityEditor.UIElements.ObjectField texObjField;
Texture currentValue;
Image thumbnail;
bool isNormalMap;
RenderTexture thumbnailRT;
UnityEngine.Rendering.TextureDimension textureType;
public int shaderPropertyIdx;
public int GetShaderPropIdx() { return shaderPropertyIdx; }
static Action<ObjectField> s_updateObjDelegate;
static Action<ObjectField> UpdateObjDelegate
{
get {
if (s_updateObjDelegate == null)
{
MethodInfo m = typeof(UnityEditor.UIElements.ObjectField).GetMethod("UpdateDisplay", BindingFlags.Instance | BindingFlags.NonPublic);
if (m == null)
{
Debug.LogError("Missing UpdateDisplay method");
}
s_updateObjDelegate = (Action<ObjectField>)m.CreateDelegate(typeof(Action<ObjectField>));
}
return s_updateObjDelegate;
}
}
public TextureField(MaterialProperty textureProperty, int texturePropertyIdx, bool isNormalMap, Texture defaultTexture = null)
{
this.textureProperty = textureProperty;
this.currentValue = textureProperty.textureValue;
this.shaderPropertyIdx = texturePropertyIdx;
this.isNormalMap = isNormalMap;
this.defaultTexture = defaultTexture;
RegisterCallback<DetachFromPanelEvent>(evt => Dispose());
leftAlignBox = new VisualElement();
leftAlignBox.AddToClassList("materialGUILeftBox");
rightAlignBox = new VisualElement();
rightAlignBox.AddToClassList("materialGUIRightBox");
style.flexDirection = FlexDirection.Row;
texObjField = new UnityEditor.UIElements.ObjectField();
//List<SearchProvider> providers = new List<SearchProvider>() { new SearchProvider("sfklahlkjhsa", "hello") };
//textureField.searchContext = new SearchContext(providers, "t:Texture2D", SearchFlags.Default);
//textureField.bindingPath = "m_SavedProperties.m_TexEnvs.Array.data[0].second.m_Texture";
textureType = textureProperty.textureDimension;
switch (textureProperty.textureDimension)
{
case (UnityEngine.Rendering.TextureDimension.Tex2D):
texObjField.objectType = typeof(Texture2D);
break;
case (UnityEngine.Rendering.TextureDimension.Tex3D):
texObjField.objectType = typeof(Texture3D);
break;
case (UnityEngine.Rendering.TextureDimension.Tex2DArray):
texObjField.objectType = typeof(Texture2DArray);
break;
case (UnityEngine.Rendering.TextureDimension.Cube):
texObjField.objectType = typeof(Cubemap);
break;
case (UnityEngine.Rendering.TextureDimension.CubeArray):
texObjField.objectType = typeof(CubemapArray);
break;
}
VisualElement background = texObjField.ElementAt(0);
background.style.backgroundColor = StyleKeyword.None;
background.style.borderBottomColor = StyleKeyword.None;
background.style.borderLeftColor = StyleKeyword.None;
background.style.borderRightColor = StyleKeyword.None;
background.style.borderTopColor = StyleKeyword.None;
background.style.borderBottomWidth = StyleKeyword.None;
background.style.borderLeftWidth = StyleKeyword.None;
background.style.borderRightWidth = StyleKeyword.None;
background.style.borderTopWidth = StyleKeyword.None;
background.style.borderTopLeftRadius = StyleKeyword.None;
background.style.borderTopRightRadius = StyleKeyword.None;
background.style.borderBottomLeftRadius = StyleKeyword.None;
background.style.borderBottomRightRadius = StyleKeyword.None;
background.style.justifyContent = Justify.FlexStart;
background.style.flexWrap = Wrap.NoWrap;
background.style.overflow = Overflow.Hidden;
VisualElement contents = background.ElementAt(0);
contents.style.flexShrink = 0;
contents.style.flexGrow = 1;
contents.style.overflow = Overflow.Hidden;
contents.style.flexBasis = StyleKeyword.Auto;
VisualElement oldlabel = contents.ElementAt(1);
oldlabel.style.display = DisplayStyle.None;
VisualElement searchButton = background.ElementAt(1);
searchButton.style.width = StyleKeyword.Auto;
searchButton.style.backgroundImage = StyleKeyword.None;
searchButton.style.flexDirection = FlexDirection.Row;
searchButton.style.overflow = Overflow.Hidden;
searchButton.style.flexBasis = StyleKeyword.Auto;
VisualElement fakeRadial = new VisualElement();
fakeRadial.AddToClassList("unity-object-field__selector");
fakeRadial.pickingMode = PickingMode.Ignore;
fakeRadial.style.backgroundColor = Color.clear;
Label label = new Label(textureProperty.displayName);
label.pickingMode = PickingMode.Ignore;
label.style.textOverflow = TextOverflow.Ellipsis;
searchButton.Add(fakeRadial);
searchButton.Add(label);
Image oldThumbnail = contents.ElementAt(0) as Image;
oldThumbnail.style.display = DisplayStyle.None;
thumbnail = new Image();
thumbnail.AddToClassList("textureFieldThumb");
thumbnail.AddToClassList("unity-object-field-display__icon");
thumbnail.pickingMode = PickingMode.Ignore;
thumbnail.scaleMode = ScaleMode.StretchToFill;
thumbnail.tintColor = Color.white;
thumbnailRT = new RenderTexture((int)(32.0f * EditorGUIUtility.pixelsPerPoint), (int)(32.0f * EditorGUIUtility.pixelsPerPoint), 1, RenderTextureFormat.ARGB32, 1);
thumbnailRT.depth = 0;
thumbnailRT.name = textureProperty.name + "_icon";
thumbnailRT.Create();
thumbnail.image = thumbnailRT;
contents.Insert(0, thumbnail);
texObjField.RegisterValueChangedCallback(OnObjectFieldChanged);
if (textureProperty.hasMixedValue)
{
currentValue = null;
texObjField.showMixedValue = true;
}
else
{
//if (textureProperty.textureValue == null && defaultTexture != null)
//{
// textureProperty.textureValue = defaultTexture;
// currentValue = defaultTexture;
//}
texObjField.showMixedValue = false;
}
texObjField.SetValueWithoutNotify(currentValue);
UpdateThumbnail();
leftAlignBox.Add(texObjField);
Add(leftAlignBox);
Add(rightAlignBox);
}
void OnObjectFieldChanged(ChangeEvent<Object> evt)
{
value = evt.newValue;
}
public void SetValueWithoutNotify(Object newValue)
{
if (newValue == null || newValue is Texture)
{
currentValue = (Texture) newValue;
if (currentValue == null && defaultTexture != null)
{
currentValue = defaultTexture;
}
UpdateThumbnail();
textureProperty.textureValue = currentValue;
texObjField.SetValueWithoutNotify(currentValue);
UpdateObjDelegate.Invoke(texObjField);
texObjField.showMixedValue = newValue == null;
}
else throw new System.ArgumentException($"Expected object of type {typeof(Texture2D)}");
}
public Object value
{
get => currentValue;
set
{
if (value == currentValue)
return;
Object previous = currentValue;
SetValueWithoutNotify(value);
}
}
void UpdateThumbnail()
{
BlitTextureIcon(thumbnailRT, currentValue, textureType);
}
public void UpdateMaterialProperty(MaterialProperty boundProp)
{
bool valueChanged = currentValue != boundProp.textureValue;
textureProperty = boundProp;
if (valueChanged)
{
currentValue = boundProp.textureValue;
texObjField.SetValueWithoutNotify(currentValue);
UpdateThumbnail();
}
texObjField.showMixedValue = boundProp.hasMixedValue;
}
void Dispose()
{
if (thumbnailRT != null)
{
thumbnailRT.Clear();
}
}
static Material s_blitMaterial;
static LocalKeyword[] dimKeywords;
static LocalKeyword normalMapKeyword;
static int prop_Blit2D = Shader.PropertyToID("_Blit2D");
static int prop_Blit2DArray = Shader.PropertyToID("_Blit2DArray");
static int prop_BlitCube = Shader.PropertyToID("_BlitCube");
static int prop_BlitCubeArray = Shader.PropertyToID("_BlitCubeArray");
static int prop_Blit3D = Shader.PropertyToID("_Blit3D");
static int prop_BlitDim = Shader.PropertyToID("_BlitDim");
static void UpdateKeywords()
{
Shader blitShader = s_blitMaterial.shader;
dimKeywords[(int)TextureDimension.Tex2D - 2] = new LocalKeyword(blitShader, "DIM_2D");
dimKeywords[(int)TextureDimension.Tex2DArray - 2] = new LocalKeyword(blitShader, "DIM_2DARRAY");
dimKeywords[(int)TextureDimension.Cube - 2] = new LocalKeyword(blitShader, "DIM_CUBE");
dimKeywords[(int)TextureDimension.CubeArray - 2] = new LocalKeyword(blitShader, "DIM_CUBEARRAY");
dimKeywords[(int)TextureDimension.Tex3D - 2] = new LocalKeyword(blitShader, "DIM_3D");
normalMapKeyword = new LocalKeyword(blitShader, "NORMAL_MAP");
}
void BlitTextureIcon(RenderTexture icon, Texture tex, TextureDimension texType)
{
if (icon == null) return;
RenderTexture active = RenderTexture.active;
if (tex == null)
{
RenderTexture.active = icon;
GL.Clear(false, true, Color.clear, 0);
RenderTexture.active = active;
return;
}
if (s_blitMaterial == null || s_blitMaterial.shader == null || dimKeywords == null)
{
Shader blitShader = Shader.Find("Hidden/ShaderGUITextureIconBlit");
if (blitShader == null)
{
Debug.LogError("Could not find Blit_ShaderGUI.shader (Hidden/ShaderGUITextureIconBlit), cannot generate material thumbnails");
return;
}
s_blitMaterial = new Material(blitShader);
dimKeywords = new LocalKeyword[5];
}
UpdateKeywords();
int offsetDimEnum = (int)texType - 2;
for (int i = 0; i < 5; i++)
{
if (i == offsetDimEnum)
s_blitMaterial.EnableKeyword(dimKeywords[i]);
else
s_blitMaterial.DisableKeyword(dimKeywords[i]);
}
switch (texType)
{
case TextureDimension.Tex2D:
s_blitMaterial.SetTexture(prop_Blit2D, tex);
break;
case TextureDimension.Tex2DArray:
s_blitMaterial.SetTexture(prop_Blit2DArray, tex);
break;
case TextureDimension.Cube:
s_blitMaterial.SetTexture(prop_BlitCube, tex);
s_blitMaterial.SetVector(prop_BlitDim, new Vector4(tex.width, tex.height, 0, 0));
break;
case TextureDimension.CubeArray:
s_blitMaterial.SetTexture(prop_BlitCubeArray, tex);
s_blitMaterial.SetVector(prop_BlitDim, new Vector4(tex.width, tex.height, 0, 0));
break;
case TextureDimension.Tex3D:
s_blitMaterial.SetTexture(prop_Blit3D, tex);
s_blitMaterial.SetVector(prop_BlitDim, new Vector4(tex.width, tex.height, 0, 0));
break;
default:
Debug.LogError("Shader GUI Icon Blitter: Unknown texture dimension " + texType);
return;
}
if (isNormalMap)
{
s_blitMaterial.EnableKeyword(normalMapKeyword);
}
Graphics.Blit(tex, icon, s_blitMaterial);
RenderTexture.active = active;
if (isNormalMap)
{
s_blitMaterial.DisableKeyword(normalMapKeyword);
}
switch (texType)
{
case TextureDimension.Tex2D:
s_blitMaterial.SetTexture(prop_Blit2D, null);
break;
case TextureDimension.Tex2DArray:
s_blitMaterial.SetTexture(prop_Blit2DArray, null);
break;
case TextureDimension.Cube:
s_blitMaterial.SetTexture(prop_BlitCube, null);
break;
case TextureDimension.CubeArray:
s_blitMaterial.SetTexture(prop_BlitCubeArray, null);
break;
case TextureDimension.Tex3D:
s_blitMaterial.SetTexture(prop_Blit3D, null);
break;
}
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 38c312bdff088324b93a4ff922600f48
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,115 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Unity.Rendering.Universal;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine;
using UnityEngine.UIElements;
using SLZ.SLZEditorTools;
using UnityEditor.Graphing.Util;
using System.Reflection;
using Unity.Profiling;
namespace UnityEditor.SLZMaterialUI
{
public abstract class UIElementsMaterialEditor : MaterialEditor
{
static ProfilerMarker UpdateProfiler = new ProfilerMarker("UIElementsUpdateUI");
static ProfilerMarker PrepareForAnim = new ProfilerMarker("UIElementsUpdateUI_PrepareForAnim");
public Shader shader;
public List<BaseMaterialField> materialFields;
public MaterialProperty[] materialProperties;
public virtual void UpdateUI()
{
UpdateProfiler.Begin();
//Debug.Log("Called Update UI");
materialProperties = MaterialEditor.GetMaterialProperties(this.targets);
PrepareMaterialPropertiesForAnimationMode(materialProperties, true);
int[] shaderProp2MatProp = ShaderGUIUtils.GetShaderIdxToMaterialProp(materialProperties, shader);
if (materialFields == null)
{
return;
}
int numFields = materialFields.Count;
for (int fIdx = 0; fIdx < numFields; fIdx++)
{
int propIndex = shaderProp2MatProp[materialFields[fIdx].GetShaderPropIdx()];
//Debug.Log("Updating with indices: " + materialFields[fIdx].GetShaderPropIdx() + " " + propIndex);
materialFields[fIdx].UpdateMaterialProperty(materialProperties[propIndex]);
}
UpdateProfiler.End();
}
public override bool UseDefaultMargins()
{
return false;
}
/// <summary>
/// Initialize the material inspector, getting the shader used by the materials and assigning it to the shader field.
/// In a sane world, unity would only attempt to create the material editor when all materials share the same shader.
/// But I don't trust unity, so check to make sure that they're all the same and not null.
/// </summary>
/// <returns>true on success, false on failure</returns>
public bool Initialize(VisualElement root, VisualElement window)
{
materialProperties = MaterialEditor.GetMaterialProperties(this.targets);
PrepareMaterialPropertiesForAnimationMode(materialProperties, true);
SerializedProperty serializedShader = serializedObject.FindProperty("m_Shader");
if (serializedShader.hasMultipleDifferentValues || serializedShader.objectReferenceValue == null)
{
Debug.LogError("SLZ Material Inspector: attempted to draw custom inspector for materials with different shaders");
return false;
}
this.shader = (Shader)serializedShader.objectReferenceValue;
if (shader == null)
{
Debug.LogError("SLZ Material Inspector: attempted to draw custom inspector for material with null shader");
return false;
}
IMGUIContainer OnUpdate = new IMGUIContainer(() => {
bool isDisplay = window.style.display != DisplayStyle.None;
if (base.isVisible != isDisplay)
{
window.style.display = base.isVisible ? DisplayStyle.Flex : DisplayStyle.None;
root.MarkDirtyRepaint();
}
OnIMGUITick();
});
root.Add(OnUpdate);
root.RegisterCallback<AttachToPanelEvent>(evt => Undo.undoRedoPerformed += UpdateUI);
root.RegisterCallback<DetachFromPanelEvent>(evt => Undo.undoRedoPerformed -= UpdateUI);
return true;
}
static MethodInfo s_RefreshInspectors;
protected override void OnShaderChanged()
{
ShaderGUIUtils.ForceRebuild(this);
}
void OnIMGUITick()
{
if ((target as Material).shader != shader)
{
ShaderGUIUtils.ForceRebuild(this);
return;
}
if (base.isVisible && AnimationMode.InAnimationMode())
{
PrepareMaterialPropertiesForAnimationMode(materialProperties, true);
UpdateUI();
}
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 31b3f9a51f0228e47aa6afcd959ea3b8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: