// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.Rendering;
namespace Microsoft.MixedReality.GraphicsTools.Editor
{
///
/// How to treat the alpha channel of the albedo texture.
///
public enum AlbedoAlphaMode
{
Transparency = 0,
Metallic = 1,
Smoothness = 2
}
///
/// What type of direct light affects the surface.
///
public enum LightMode
{
Unlit = 0,
LitDirectional = 1,
LitDistant = 2
}
///
/// What type of gradient to generate.
///
public enum GradientMode
{
None = 0,
Iridescence = 1,
FourPoint = 2,
Linear = 3
}
///
/// How the border color should be calculated.
///
public enum BorderColorMode
{
Brightness = 0,
HoverColor = 1,
Color = 2,
Gradient = 3
}
///
/// Is edge smoothing controlled by a user defined value or programmatically.
///
public enum EdgeSmoothingMode
{
Manual = 0,
Automatic = 1
}
///
/// How to sample the blur texture.
///
public enum BlurMode
{
None = 0,
Layer1 = 1,
Layer2 = 2,
PrebakedBackground = 3
}
///
/// A custom shader inspector for the "Graphics Tools/Standard" and "Graphics Tools/Standard Canvas" shaders.
///
public class StandardShaderGUI : BaseShaderGUI
{
///
/// Common names, keywords, and tooltips.
///
protected static class Styles
{
public static readonly string primaryMapsTitle = "Main Maps";
public static readonly string renderingOptionsTitle = "Rendering Options";
public static readonly string advancedOptionsTitle = "Advanced Options";
public static readonly string fluentOptionsTitle = "Fluent Options";
public static readonly string stencilComparisonName = "_StencilComparison";
public static readonly string stencilOperationName = "_StencilOperation";
public static readonly string disableAlbedoMapName = "_DISABLE_ALBEDO_MAP";
public static readonly string albedoMapAlphaMetallicName = "_METALLIC_TEXTURE_ALBEDO_CHANNEL_A";
public static readonly string albedoMapAlphaSmoothnessName = "_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A";
public static readonly string propertiesComponentHelp = "Use the {0} component(s) to control {1} properties.";
public static readonly GUIContent albedo = new GUIContent("Albedo", "Albedo (RGB) and Transparency (Alpha)");
public static readonly GUIContent albedoAssignedAtRuntime = new GUIContent("Assigned at Runtime", "As an optimization albedo operations are disabled when no albedo texture is specified. If a albedo texture will be specified at runtime enable this option.");
public static readonly GUIContent alphaCutoff = new GUIContent("Alpha Cutoff", "Threshold for Alpha Cutoff");
public static readonly GUIContent alphaFade = new GUIContent("Alpha Fade", "Fade value which can be altered separately from the albedo color.");
public static readonly GUIContent metallic = new GUIContent("Metallic", "Metallic Value");
public static readonly GUIContent smoothness = new GUIContent("Smoothness", "Smoothness Value");
public static readonly GUIContent enableChannelMap = new GUIContent("Channel Map", "Enable Channel Map, a Channel Packing Texture That Follows Unity's Standard Channel Setup");
public static readonly GUIContent channelMap = new GUIContent("Channel Map", "Metallic (Red), Occlusion (Green), Emission (Blue), Smoothness (Alpha)");
public static readonly GUIContent enableNormalMap = new GUIContent("Normal Map", "Enable Normal Map");
public static readonly GUIContent normalMap = new GUIContent("Normal Map");
public static readonly GUIContent enableEmission = new GUIContent("Emission", "Enable Emission");
public static readonly GUIContent emissiveColor = new GUIContent("Color");
public static readonly GUIContent emissiveMap = new GUIContent("EmissionMap");
public static readonly GUIContent enableTriplanarMapping = new GUIContent("Triplanar Mapping", "Enable Triplanar Mapping, a technique which programmatically generates UV coordinates");
public static readonly GUIContent enableLocalSpaceTriplanarMapping = new GUIContent("Local Space", "If True Triplanar Mapping is Calculated in Local Space");
public static readonly GUIContent triplanarMappingBlendSharpness = new GUIContent("Blend Sharpness", "The Power of the Blend with the Normal");
public static readonly GUIContent enableSSAA = new GUIContent("Super Sample Anti-Aliasing", "Enable Super Sample Anti-Aliasing, a technique improves texture clarity at long distances");
public static readonly GUIContent mipmapBias = new GUIContent("Mipmap Bias", "Degree to bias the mip map. A larger negative value reduces aliasing and improves clarity, but may decrease performance");
public static readonly GUIContent lightMode = new GUIContent("Light Mode", "What Type of Direct Light Affects the Surface");
public static readonly string[] lightModeNames = new string[] { "Unlit", "Lit - Directional", "Lit - Distant" };
public static readonly string lightModeLitDirectional = "_DIRECTIONAL_LIGHT";
public static readonly string lightModeLitDistant = "_DISTANT_LIGHT";
public static readonly GUIContent nonPhotorealisticRendering = new GUIContent("Non-Photorealistic Rendering","Non-Photorealistic Rendering");
public static readonly GUIContent specularHighlights = new GUIContent("Specular Highlights", "Calculate Specular Highlights");
public static readonly GUIContent sphericalHarmonics = new GUIContent("Spherical Harmonics", "Read From Spherical Harmonics Data for Ambient Light");
public static readonly GUIContent reflections = new GUIContent("Reflections", "Calculate Glossy Reflections");
public static readonly GUIContent rimLight = new GUIContent("Rim Light", "Enable Rim (Fresnel) Lighting");
public static readonly GUIContent rimColor = new GUIContent("Color", "Rim Highlight Color");
public static readonly GUIContent rimPower = new GUIContent("Power", "Rim Highlight Saturation");
public static readonly GUIContent vertexColors = new GUIContent("Vertex Colors", "Enable Vertex Color Tinting");
public static readonly GUIContent vertexExtrusion = new GUIContent("Vertex Extrusion", "Enable Vertex Extrusion Along the Vertex Normal");
public static readonly GUIContent vertexExtrusionValue = new GUIContent("Extrusion Value", "How Far to Extrude the Vertex Along the Vertex Normal");
public static readonly GUIContent vertexExtrusionSmoothNormals = new GUIContent("Use Smooth Normals", "Should Vertex Extrusion use the Smooth Normals in UV3, or Default Normals");
public static readonly GUIContent vertexExtrusionConstantWidth = new GUIContent("Constant Width", "Should the Extrusion Value be scaled by the pixels distance from the camera?");
public static readonly GUIContent blendedClippingWidth = new GUIContent("Clipping Alpha Falloff", "Controls The Width of the Fade Region on Alpha Blended Materials. 0 Equals No Falloff.");
public static readonly GUIContent clippingBorder = new GUIContent("Clipping Border", "Enable a Border Along the Clipping Primitive's Edge");
public static readonly GUIContent clippingBorderWidth = new GUIContent("Width", "Width of the Clipping Border");
public static readonly GUIContent clippingBorderColor = new GUIContent("Color", "Interpolated Color of the Clipping Border");
public static readonly GUIContent nearPlaneFade = new GUIContent("Near Fade", "Objects Disappear (Turn to Black/Transparent) as the Camera (or Hover/Proximity Light) Nears Them");
public static readonly GUIContent nearLightFade = new GUIContent("Use Light", "A Hover or Proximity Light (Rather Than the Camera) Determines Near Fade Distance");
public static readonly GUIContent fadeBeginDistance = new GUIContent("Fade Begin", "Distance From Camera (or Hover/Proximity Light) to Begin Fade In");
public static readonly GUIContent fadeCompleteDistance = new GUIContent("Fade Complete", "Distance From Camera (or Hover/Proximity Light) When Fade is Fully In");
public static readonly GUIContent fadeMinValue = new GUIContent("Fade Min Value", "Clamps the Fade Amount to a Minimum Value");
public static readonly GUIContent hoverLight = new GUIContent("Hover Light", "Enable utilization of Hover Light(s)");
public static readonly GUIContent enableHoverColorOverride = new GUIContent("Override Color", "Override Global Hover Light Color for this Material");
public static readonly GUIContent hoverColorOverride = new GUIContent("Color", "Override Hover Light Color");
public static readonly GUIContent proximityLight = new GUIContent("Proximity Light", "Enable utilization of Proximity Light(s)");
public static readonly GUIContent enableProximityLightColorOverride = new GUIContent("Override Color", "Override Global Proximity Light Color for this Material");
public static readonly GUIContent proximityLightCenterColorOverride = new GUIContent("Center Color", "The Override Color of the ProximityLight Gradient at the Center (RGB) and (A) is Gradient Extent");
public static readonly GUIContent proximityLightMiddleColorOverride = new GUIContent("Middle Color", "The Override Color of the ProximityLight Gradient at the Middle (RGB) and (A) is Gradient Extent");
public static readonly GUIContent proximityLightOuterColorOverride = new GUIContent("Outer Color", "The Override Color of the ProximityLight Gradient at the Outer Edge (RGB) and (A) is Gradient Extent");
public static readonly GUIContent proximityLightSubtractive = new GUIContent("Subtractive", "Proximity Lights Remove Light from a Surface, Used to Mimic a Shadow");
public static readonly GUIContent proximityLightTwoSided = new GUIContent("Two Sided", "Proximity Lights Apply to Both Sides of a Surface");
public static readonly GUIContent fluentLightIntensity = new GUIContent("Light Intensity", "Intensity Scaler for All Hover and Proximity Lights");
public static readonly GUIContent roundCorners = new GUIContent("Round Corners", "(Assumes UVs Specify Borders of Surface, Works Best on Unity Cube, Quad, and Plane)");
public static readonly GUIContent roundCornerRadius = new GUIContent("Unit Radius", "Rounded Rectangle Corner Unit Sphere Radius");
public static readonly GUIContent roundCornerRadiusWorldScale = new GUIContent("Radius", "Rounded Rectangle Corner Sphere Radius in World Units");
public static readonly GUIContent roundCornersRadius = new GUIContent("Corners Radius", "UpLeft-UpRight-BottomRight-BottomLeft");
public static readonly GUIContent roundCornerMargin = new GUIContent("Margin %", "Distance From Geometry Edge");
public static readonly GUIContent roundCornerMarginWorldScale = new GUIContent("Margin", "Distance From Geometry Edge in World Units");
public static readonly GUIContent independentCorners = new GUIContent("Independent Corners", "Manage Each Corner Separately");
public static readonly GUIContent roundCornersHideInterior = new GUIContent("Hide Interior", "Pixels Within the Rounded Rect Should be Discarded");
public static readonly GUIContent borderLight = new GUIContent("Border Light", "Enable Border Lighting (Assumes UVs Specify Borders of Surface, Works Best on Unity Cube, Quad, and Plane)");
public static readonly GUIContent borderLightReplacesAlbedo = new GUIContent("Replace Albedo", "Border Light Replaces Albedo (Replacement Rather Than Additive)");
public static readonly GUIContent borderLightOpaque = new GUIContent("Opaque Borders", "Borders Override Alpha Value to Appear Opaque");
public static readonly GUIContent borderWidth = new GUIContent("Width %", "Uniform Width Along Border as a % of the Smallest XYZ Dimension");
public static readonly GUIContent borderWidthWorldScale = new GUIContent("Width", "Uniform Width Along Border in World Units");
public static readonly GUIContent borderColorMode = new GUIContent("Color Mode", "How the Border is Colored");
public static readonly string borderColorModeHoverColorName = "_BORDER_LIGHT_USES_HOVER_COLOR";
public static readonly string borderColorModeColorName = "_BORDER_LIGHT_USES_COLOR";
public static readonly string borderColorModeGradientName = "_BORDER_LIGHT_USES_GRADIENT";
public static readonly GUIContent borderMinValue = new GUIContent("Brightness", "Brightness Scaler");
public static readonly GUIContent borderColor = new GUIContent("Border Color", "Border Color");
public static readonly GUIContent edgeSmoothingMode = new GUIContent("Edge Smoothing Mode", "Manual, specified anti aliasing value will be used. Automatic, the shader will calculate a anti aliasing value.");
public static readonly string edgeSmoothingModeAutomaticName = "_EDGE_SMOOTHING_AUTOMATIC";
public static readonly GUIContent edgeSmoothingValue = new GUIContent("Value", "Smoothing Factor Applied to SDF Edges");
public static readonly GUIContent borderLightOpaqueAlpha = new GUIContent("Alpha", "Alpha value of \"opaque\" borders.");
public static readonly GUIContent innerGlow = new GUIContent("Inner Glow", "Enable Inner Glow (Assumes UVs Specify Borders of Surface, Works Best on Unity Cube, Quad, and Plane)");
public static readonly GUIContent innerGlowColor = new GUIContent("Color", "Inner Glow Color (RGB) and Intensity (A)");
public static readonly GUIContent innerGlowPower = new GUIContent("Power", "Power Exponent to Control Glow");
public static readonly GUIContent gradientMode = new GUIContent("Gradient Mode", "Specifies the Type of Color Gradient to Apply in UV Space");
public static readonly string gradientModeIridescence = "_IRIDESCENCE";
public static readonly string gradientModeFourPoint = "_GRADIENT_FOUR_POINT";
public static readonly string gradientModeLinear = "_GRADIENT_LINEAR";
public static readonly GUIContent iridescentSpectrumMap = new GUIContent("Spectrum Map", "Spectrum of Colors to Apply (Usually a Texture with ROYGBIV from Left to Right)");
public static readonly GUIContent iridescenceIntensity = new GUIContent("Intensity", "Intensity of Iridescence");
public static readonly GUIContent iridescenceThreshold = new GUIContent("Threshold", "Threshold Window to Sample From the Spectrum Map");
public static readonly GUIContent iridescenceAngle = new GUIContent("Angle", "Surface Angle");
public static readonly GUIContent fourPointGradientTopLeftColor = new GUIContent("Top Left", "Top Left Color at UV (0, 0)");
public static readonly GUIContent fourPointGradientTopRightColor = new GUIContent("Top Right", "Top Right Color at UV (1, 0)");
public static readonly GUIContent fourPointGradientBottomLeftColor = new GUIContent("Bottom Left", "Bottom Left Color at UV (0, 1)");
public static readonly GUIContent fourPointGradientBottomRightColor = new GUIContent("Bottom Right", "Bottom Right Color at UV (1, 1)");
public static readonly GUIContent fourPointGradientAutoFillButton = new GUIContent("Auto Fill", "Generates a Visually Pleasing Gradient Based on the Top Left Color");
public static readonly GUIContent linearGradientHelp = new GUIContent("Note: Only the first 4 color (and first 4 alpha) keys will be used from the gradient editor.");
public static readonly GUIContent linearGradientColor = new GUIContent("Color Keys", "Specify up to 4 Colors and 4 Alpha Values to Evaluate.");
public static readonly GUIContent linearGradientAngle = new GUIContent("Angle", "By Default Gradients Go Top to Bottom the Angle Adjusts That Direction");
public static readonly GUIContent linearCssGradient = new GUIContent("Import From CSS Gradient", "For Example Type: linear-gradient(red, yellow);");
public static readonly GUIContent environmentColoring = new GUIContent("Environment Coloring", "Change Color Based on View");
public static readonly GUIContent environmentColorThreshold = new GUIContent("Threshold", "Threshold When Environment Coloring Should Appear Based on Surface Normal");
public static readonly GUIContent environmentColorIntensity = new GUIContent("Intensity", "Intensity (or Brightness) of the Environment Coloring");
public static readonly GUIContent environmentColorX = new GUIContent("X-Axis Color", "Color Along the World Space X-Axis");
public static readonly GUIContent environmentColorY = new GUIContent("Y-Axis Color", "Color Along the World Space Y-Axis");
public static readonly GUIContent environmentColorZ = new GUIContent("Z-Axis Color", "Color Along the World Space Z-Axis");
public static readonly GUIContent blurMode = new GUIContent("Blur Mode", "None, no blur texture is sampled. Layer1, _blurTexture is sampled from the AcrylicLayerManager. Layer2, _blurTexture2 is sampled from the AcrylicLayerManager.");
public static readonly string blurModeLayer1Name = "_BLUR_TEXTURE";
public static readonly string blurModeLayer2Name = "_BLUR_TEXTURE_2";
public static readonly string blurModePrebakedBackgroundName = "_BLUR_TEXTURE_PREBAKED_BACKGROUND";
public static readonly GUIContent blurTextureIntensity = new GUIContent("Blur Texture Intensity", "Scaler applied to the blur texture.");
public static readonly GUIContent blurBorderIntensity = new GUIContent("Blur Border Intensity", "Scaler applied to the blur texture in conjunction with the Border Light feature.");
public static readonly GUIContent blurBackgroundRect = new GUIContent("Blur Background Rect", "The rect specified by the CanvasRectProvider component to calculate adjusted texture coordinates.");
public static readonly GUIContent stencil = new GUIContent("Enable Stencil Testing", "Enabled Stencil Testing Operations");
public static readonly GUIContent stencilReference = new GUIContent("Stencil Reference", "Value to Compared Against (if Comparison is Anything but Always) and/or the Value to be Written to the Buffer (if Either Pass, Fail or ZFail is Set to Replace)");
public static readonly GUIContent stencilComparison = new GUIContent("Stencil Comparison", "Function to Compare the Reference Value to");
public static readonly GUIContent stencilOperation = new GUIContent("Stencil Operation", "What to do When the Stencil Test Passes");
public static readonly GUIContent stencilWriteMask = new GUIContent("Stencil Write Mask", "Specifies Which Bits are Included in the Write Operation");
public static readonly GUIContent stencilReadMask = new GUIContent("Stencil Read Mask", "Specifies Which Bits are Included in the Read Operation");
public static readonly GUIContent useWorldScale = new GUIContent("Absolute Size", "Features That Require Object Scale (Round Corners, Border Light, etc.), Default to Using Absolute (World) Scale when Enabled");
}
protected MaterialProperty albedoMap;
protected MaterialProperty albedoColor;
protected MaterialProperty albedoAlphaMode;
protected MaterialProperty albedoAssignedAtRuntime;
protected MaterialProperty alphaCutoff;
protected MaterialProperty alphaFade;
protected MaterialProperty enableChannelMap;
protected MaterialProperty channelMap;
protected MaterialProperty enableNormalMap;
protected MaterialProperty normalMap;
protected MaterialProperty normalMapScale;
protected MaterialProperty enableEmission;
protected MaterialProperty emissiveColor;
protected MaterialProperty emissiveMap;
protected MaterialProperty enableTriplanarMapping;
protected MaterialProperty enableLocalSpaceTriplanarMapping;
protected MaterialProperty triplanarMappingBlendSharpness;
protected MaterialProperty enableSSAA;
protected MaterialProperty mipmapBias;
protected MaterialProperty metallic;
protected MaterialProperty smoothness;
protected MaterialProperty lightMode;
protected MaterialProperty specularHighlights;
protected MaterialProperty sphericalHarmonics;
protected MaterialProperty nonPhotorealisticRendering;
protected MaterialProperty reflections;
protected MaterialProperty rimLight;
protected MaterialProperty rimColor;
protected MaterialProperty rimPower;
protected MaterialProperty vertexColors;
protected MaterialProperty vertexExtrusion;
protected MaterialProperty vertexExtrusionValue;
protected MaterialProperty vertexExtrusionSmoothNormals;
protected MaterialProperty vertexExtrusionConstantWidth;
protected MaterialProperty blendedClippingWidth;
protected MaterialProperty clippingBorder;
protected MaterialProperty clippingBorderWidth;
protected MaterialProperty clippingBorderColor;
protected MaterialProperty nearPlaneFade;
protected MaterialProperty nearLightFade;
protected MaterialProperty fadeBeginDistance;
protected MaterialProperty fadeCompleteDistance;
protected MaterialProperty fadeMinValue;
protected MaterialProperty hoverLight;
protected MaterialProperty enableHoverColorOverride;
protected MaterialProperty hoverColorOverride;
protected MaterialProperty proximityLight;
protected MaterialProperty enableProximityLightColorOverride;
protected MaterialProperty proximityLightCenterColorOverride;
protected MaterialProperty proximityLightMiddleColorOverride;
protected MaterialProperty proximityLightOuterColorOverride;
protected MaterialProperty proximityLightSubtractive;
protected MaterialProperty proximityLightTwoSided;
protected MaterialProperty fluentLightIntensity;
protected MaterialProperty roundCorners;
protected MaterialProperty roundCornerRadius;
protected MaterialProperty roundCornerMargin;
protected MaterialProperty independentCorners;
protected MaterialProperty roundCornersRadius;
protected MaterialProperty roundCornersHideInterior;
protected MaterialProperty borderLight;
protected MaterialProperty borderLightReplacesAlbedo;
protected MaterialProperty borderLightOpaque;
protected MaterialProperty borderWidth;
protected MaterialProperty borderColorMode;
protected MaterialProperty borderMinValue;
protected MaterialProperty borderColor;
protected MaterialProperty edgeSmoothingMode;
protected MaterialProperty edgeSmoothingValue;
protected MaterialProperty borderLightOpaqueAlpha;
protected MaterialProperty innerGlow;
protected MaterialProperty innerGlowColor;
protected MaterialProperty innerGlowPower;
protected MaterialProperty gradientMode;
protected MaterialProperty iridescentSpectrumMap;
protected MaterialProperty iridescenceIntensity;
protected MaterialProperty iridescenceThreshold;
protected MaterialProperty iridescenceAngle;
protected MaterialProperty gradientAngle;
protected MaterialProperty gradientColor0;
protected MaterialProperty gradientColor1;
protected MaterialProperty gradientColor2;
protected MaterialProperty gradientColor3;
protected MaterialProperty gradientColor4;
protected MaterialProperty gradientAlpha;
protected MaterialProperty gradientAlphaTime;
protected MaterialProperty environmentColoring;
protected MaterialProperty environmentColorThreshold;
protected MaterialProperty environmentColorIntensity;
protected MaterialProperty environmentColorX;
protected MaterialProperty environmentColorY;
protected MaterialProperty environmentColorZ;
protected MaterialProperty blurMode;
protected MaterialProperty blurTextureIntensity;
protected MaterialProperty blurBorderIntensity;
protected MaterialProperty blurBackgroundRect;
protected MaterialProperty enableStencil;
protected MaterialProperty stencilReference;
protected MaterialProperty stencilComparison;
protected MaterialProperty stencilOperation;
protected MaterialProperty stencilWriteMask;
protected MaterialProperty stencilReadMask;
protected MaterialProperty useWorldScale;
protected string cssGradient = string.Empty;
protected bool cssGradientValid = false;
///
/// Looks for properties associated with various render features.
///
/// Material properties to search.
protected override void FindProperties(MaterialProperty[] props)
{
base.FindProperties(props);
albedoMap = FindProperty("_MainTex", props);
albedoColor = FindProperty("_Color", props);
albedoAlphaMode = FindProperty("_AlbedoAlphaMode", props);
albedoAssignedAtRuntime = FindProperty("_AlbedoAssignedAtRuntime", props);
alphaCutoff = FindProperty("_Cutoff", props);
alphaFade = FindProperty("_Fade", props);
metallic = FindProperty("_Metallic", props);
smoothness = FindProperty("_Smoothness", props);
enableChannelMap = FindProperty("_EnableChannelMap", props);
channelMap = FindProperty("_ChannelMap", props);
enableNormalMap = FindProperty("_EnableNormalMap", props);
normalMap = FindProperty("_NormalMap", props);
normalMapScale = FindProperty("_NormalMapScale", props);
enableEmission = FindProperty("_EnableEmission", props);
emissiveMap = FindProperty("_EmissiveMap", props);
emissiveColor = FindProperty("_EmissiveColor", props);
enableTriplanarMapping = FindProperty("_EnableTriplanarMapping", props);
enableLocalSpaceTriplanarMapping = FindProperty("_EnableLocalSpaceTriplanarMapping", props);
triplanarMappingBlendSharpness = FindProperty("_TriplanarMappingBlendSharpness", props);
enableSSAA = FindProperty("_EnableSSAA", props);
mipmapBias = FindProperty("_MipmapBias", props);
lightMode = FindProperty("_DirectionalLight", props);
specularHighlights = FindProperty("_SpecularHighlights", props);
sphericalHarmonics = FindProperty("_SphericalHarmonics", props);
nonPhotorealisticRendering = FindProperty("_NPR", props);
reflections = FindProperty("_Reflections", props);
rimLight = FindProperty("_RimLight", props);
rimColor = FindProperty("_RimColor", props);
rimPower = FindProperty("_RimPower", props);
vertexColors = FindProperty("_VertexColors", props);
vertexExtrusion = FindProperty("_VertexExtrusion", props);
vertexExtrusionValue = FindProperty("_VertexExtrusionValue", props);
vertexExtrusionSmoothNormals = FindProperty("_VertexExtrusionSmoothNormals", props);
vertexExtrusionConstantWidth = FindProperty("_VertexExtrusionConstantWidth", props);
blendedClippingWidth = FindProperty("_BlendedClippingWidth", props);
clippingBorder = FindProperty("_ClippingBorder", props);
clippingBorderWidth = FindProperty("_ClippingBorderWidth", props);
clippingBorderColor = FindProperty("_ClippingBorderColor", props);
nearPlaneFade = FindProperty("_NearPlaneFade", props);
nearLightFade = FindProperty("_NearLightFade", props);
fadeBeginDistance = FindProperty("_FadeBeginDistance", props);
fadeCompleteDistance = FindProperty("_FadeCompleteDistance", props);
fadeMinValue = FindProperty("_FadeMinValue", props);
hoverLight = FindProperty("_HoverLight", props);
enableHoverColorOverride = FindProperty("_EnableHoverColorOverride", props);
hoverColorOverride = FindProperty("_HoverColorOverride", props);
proximityLight = FindProperty("_ProximityLight", props);
enableProximityLightColorOverride = FindProperty("_EnableProximityLightColorOverride", props);
proximityLightCenterColorOverride = FindProperty("_ProximityLightCenterColorOverride", props);
proximityLightMiddleColorOverride = FindProperty("_ProximityLightMiddleColorOverride", props);
proximityLightOuterColorOverride = FindProperty("_ProximityLightOuterColorOverride", props);
proximityLightSubtractive = FindProperty("_ProximityLightSubtractive", props);
proximityLightTwoSided = FindProperty("_ProximityLightTwoSided", props);
fluentLightIntensity = FindProperty("_FluentLightIntensity", props);
roundCorners = FindProperty("_RoundCorners", props);
roundCornerRadius = FindProperty("_RoundCornerRadius", props);
roundCornersRadius = FindProperty("_RoundCornersRadius", props);
roundCornerMargin = FindProperty("_RoundCornerMargin", props);
independentCorners = FindProperty("_IndependentCorners", props);
roundCornersHideInterior = FindProperty("_RoundCornersHideInterior", props);
borderLight = FindProperty("_BorderLight", props);
borderLightReplacesAlbedo = FindProperty("_BorderLightReplacesAlbedo", props);
borderLightOpaque = FindProperty("_BorderLightOpaque", props);
borderWidth = FindProperty("_BorderWidth", props);
borderColorMode = FindProperty("_BorderColorMode", props);
borderMinValue = FindProperty("_BorderMinValue", props);
borderColor = FindProperty("_BorderColor", props);
edgeSmoothingMode = FindProperty("_EdgeSmoothingMode", props);
edgeSmoothingValue = FindProperty("_EdgeSmoothingValue", props);
borderLightOpaqueAlpha = FindProperty("_BorderLightOpaqueAlpha", props);
innerGlow = FindProperty("_InnerGlow", props);
innerGlowColor = FindProperty("_InnerGlowColor", props);
innerGlowPower = FindProperty("_InnerGlowPower", props);
gradientMode = FindProperty("_GradientMode", props);
iridescentSpectrumMap = FindProperty("_IridescentSpectrumMap", props);
iridescenceIntensity = FindProperty("_IridescenceIntensity", props);
iridescenceThreshold = FindProperty("_IridescenceThreshold", props);
iridescenceAngle = FindProperty("_IridescenceAngle", props);
gradientAngle = FindProperty("_GradientAngle", props);
gradientColor0 = FindProperty("_GradientColor0", props);
gradientColor1 = FindProperty("_GradientColor1", props);
gradientColor2 = FindProperty("_GradientColor2", props);
gradientColor3 = FindProperty("_GradientColor3", props);
gradientColor4 = FindProperty("_GradientColor4", props);
gradientAlpha = FindProperty("_GradientAlpha", props);
gradientAlphaTime = FindProperty("_GradientAlphaTime", props);
environmentColoring = FindProperty("_EnvironmentColoring", props);
environmentColorThreshold = FindProperty("_EnvironmentColorThreshold", props);
environmentColorIntensity = FindProperty("_EnvironmentColorIntensity", props);
environmentColorX = FindProperty("_EnvironmentColorX", props);
environmentColorY = FindProperty("_EnvironmentColorY", props);
environmentColorZ = FindProperty("_EnvironmentColorZ", props);
blurMode = FindProperty("_BlurMode", props);
blurTextureIntensity = FindProperty("_BlurTextureIntensity", props);
blurBorderIntensity = FindProperty("_BlurBorderIntensity", props);
blurBackgroundRect = FindProperty("_BlurBackgroundRect", props);
enableStencil = FindProperty("_EnableStencil", props);
stencilReference = FindProperty("_StencilReference", props, false);
stencilComparison = FindProperty(Styles.stencilComparisonName, props, false);
stencilOperation = FindProperty(Styles.stencilOperationName, props, false);
// Handle Standard Canvas naming.
stencilReference = stencilReference == null ? FindProperty("_Stencil", props) : stencilReference;
stencilComparison = stencilComparison == null ? FindProperty("_StencilComp", props) : stencilComparison;
stencilOperation = stencilOperation == null ? FindProperty("_StencilOp", props) : stencilOperation;
stencilWriteMask = FindProperty("_StencilWriteMask", props);
stencilReadMask = FindProperty("_StencilReadMask", props);
useWorldScale = FindProperty("_UseWorldScale", props);
}
///
/// Renders the material inspector in a few different categories.
///
/// Current material editor in use.
/// Material properties to search.
public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] props)
{
Material material = (Material)materialEditor.target;
base.OnGUI(materialEditor, props);
MainMapOptions(materialEditor, material);
RenderingOptions(materialEditor, material);
FluentOptions(materialEditor, material);
AdvancedOptions(materialEditor, material);
}
///
/// Attempts to copy material properties from other shaders to the Graphics Tools/Standard and Graphics Tools/Standard Canvas shaders.
///
/// Current material.
/// Previous shader.
/// Current shader.
public override void AssignNewShaderToMaterial(Material material, Shader oldShader, Shader newShader)
{
// Cache old shader properties with potentially different names than the new shader.
float? smoothness = GetFloatProperty(material, "_Glossiness");
float? diffuse = GetFloatProperty(material, "_UseDiffuse");
float? specularHighlights = GetFloatProperty(material, "_SpecularHighlights");
float? normalMap = null;
Texture normalMapTexture = material.HasProperty("_BumpMap") ? material.GetTexture("_BumpMap") : null;
float? normalMapScale = GetFloatProperty(material, "_BumpScale");
float? emission = null;
Color? emissionColor = GetColorProperty(material, "_EmissionColor");
Texture emissionMapTexture = material.HasProperty("_EmissionMap") ? material.GetTexture("_EmissionMap") : null;
float? reflections = null;
float? rimLighting = null;
Vector4? textureScaleOffset = null;
float? cullMode = GetFloatProperty(material, "_Cull");
bool newShaderIsStandardCanvas = newShader.name == StandardShaderUtility.GraphicsToolsStandardCanvasShaderName;
if (oldShader)
{
if (oldShader.name.Contains("Standard"))
{
normalMap = material.IsKeywordEnabled("_NORMALMAP") ? 1.0f : 0.0f;
emission = material.IsKeywordEnabled("_EMISSION") ? 1.0f : 0.0f;
reflections = GetFloatProperty(material, "_GlossyReflections");
}
else if (oldShader.name.Contains("Fast Configurable"))
{
normalMap = material.IsKeywordEnabled("_USEBUMPMAP_ON") ? 1.0f : 0.0f;
emission = GetFloatProperty(material, "_UseEmissionColor");
reflections = GetFloatProperty(material, "_UseReflections");
rimLighting = GetFloatProperty(material, "_UseRimLighting");
textureScaleOffset = GetVectorProperty(material, "_TextureScaleOffset");
}
}
base.AssignNewShaderToMaterial(material, oldShader, newShader);
// Apply old shader properties to the new shader.
SetShaderFeatureActive(material, null, "_Smoothness", smoothness);
if (!newShaderIsStandardCanvas)
{
SetShaderFeatureActive(material, "_DIRECTIONAL_LIGHT", "_DirectionalLight", diffuse);
SetShaderFeatureActive(material, "_SPECULAR_HIGHLIGHTS", "_SpecularHighlights", specularHighlights);
}
SetShaderFeatureActive(material, "_NORMAL_MAP", "_EnableNormalMap", normalMap);
if (normalMapTexture)
{
material.SetTexture("_NormalMap", normalMapTexture);
}
SetShaderFeatureActive(material, null, "_NormalMapScale", normalMapScale);
if (emissionMapTexture)
{
material.SetTexture("_EmissiveMap", emissionMapTexture);
}
SetShaderFeatureActive(material, "_EMISSION", "_EnableEmission", emission);
SetColorProperty(material, "_EmissiveColor", emissionColor);
if (!newShaderIsStandardCanvas)
{
SetShaderFeatureActive(material, "_REFLECTIONS", "_Reflections", reflections);
}
SetShaderFeatureActive(material, "_RIM_LIGHT", "_RimLight", rimLighting);
SetVectorProperty(material, "_MainTex_ST", textureScaleOffset);
SetShaderFeatureActive(material, null, "_CullMode", cullMode);
// Setup the rendering mode based on the old shader.
if (oldShader == null || !oldShader.name.Contains(LegacyShadersPath))
{
SetupMaterialWithRenderingMode(material, (RenderingMode)material.GetFloat(BaseStyles.renderingModeName), RenderingMode.Opaque, -1);
}
else
{
RenderingMode mode = RenderingMode.Opaque;
if (oldShader.name.Contains(TransparentCutoutShadersPath))
{
mode = RenderingMode.Cutout;
}
else if (oldShader.name.Contains(TransparentShadersPath))
{
mode = RenderingMode.Fade;
}
material.SetFloat(BaseStyles.renderingModeName, (float)mode);
MaterialChanged(material);
}
// Clear the main texture when going to the Standard Canvas shader since this will be specified by an image component.
if (newShaderIsStandardCanvas)
{
material.SetTexture("_MainTex", null);
}
}
///
protected override void MaterialChanged(Material material)
{
SetupMaterialWithAlbedo(material, albedoMap, albedoAlphaMode, albedoAssignedAtRuntime);
// Ensure old materials with "_IRIDESCENCE" enabled also turn on the Iridescence gradient mode.
if (material.IsKeywordEnabled("_IRIDESCENCE"))
{
SetShaderFeatureActive(material, Styles.gradientModeIridescence, "_GradientMode", (float)GradientMode.Iridescence);
}
base.MaterialChanged(material);
}
///
/// Displays inspectors settings that deal with texture sampling.
///
/// Current material editor in use.
/// Current material in use.
protected void MainMapOptions(MaterialEditor materialEditor, Material material)
{
GUILayout.Label(Styles.primaryMapsTitle, EditorStyles.boldLabel);
materialEditor.TexturePropertySingleLine(Styles.albedo, albedoMap, albedoColor);
if (albedoMap.textureValue == null)
{
materialEditor.ShaderProperty(albedoAssignedAtRuntime, Styles.albedoAssignedAtRuntime, 2);
}
RenderingMode mode = (RenderingMode)renderingMode.floatValue;
RenderingMode customMode = (RenderingMode)customRenderingMode.floatValue;
if (mode == RenderingMode.Cutout || (mode == RenderingMode.Custom && customMode == RenderingMode.Cutout))
{
materialEditor.ShaderProperty(alphaCutoff, Styles.alphaCutoff);
}
if (mode != RenderingMode.Opaque && mode != RenderingMode.Cutout)
{
materialEditor.ShaderProperty(alphaFade, Styles.alphaFade);
}
materialEditor.ShaderProperty(enableChannelMap, Styles.enableChannelMap);
if (PropertyEnabled(enableChannelMap))
{
EditorGUI.indentLevel += 2;
materialEditor.TexturePropertySingleLine(Styles.channelMap, channelMap);
GUILayout.Box("Metallic (Red), Occlusion (Green), Emission (Blue), Smoothness (Alpha)", EditorStyles.helpBox, Array.Empty());
EditorGUI.indentLevel -= 2;
}
if (!PropertyEnabled(enableChannelMap))
{
EditorGUI.indentLevel += 2;
materialEditor.ShaderProperty(albedoAlphaMode, albedoAlphaMode.displayName);
if ((AlbedoAlphaMode)albedoAlphaMode.floatValue != AlbedoAlphaMode.Metallic)
{
materialEditor.ShaderProperty(metallic, Styles.metallic);
}
if ((AlbedoAlphaMode)albedoAlphaMode.floatValue != AlbedoAlphaMode.Smoothness)
{
materialEditor.ShaderProperty(smoothness, Styles.smoothness);
}
SetupMaterialWithAlbedo(material, albedoMap, albedoAlphaMode, albedoAssignedAtRuntime);
EditorGUI.indentLevel -= 2;
}
if ((LightMode)lightMode.floatValue != LightMode.Unlit ||
PropertyEnabled(reflections) ||
PropertyEnabled(rimLight) ||
PropertyEnabled(environmentColoring))
{
materialEditor.ShaderProperty(enableNormalMap, Styles.enableNormalMap);
if (PropertyEnabled(enableNormalMap))
{
EditorGUI.indentLevel += 2;
materialEditor.TexturePropertySingleLine(Styles.normalMap, normalMap, normalMapScale);
EditorGUI.indentLevel -= 2;
}
}
materialEditor.ShaderProperty(enableEmission, Styles.enableEmission);
if (PropertyEnabled(enableEmission))
{
EditorGUI.indentLevel += 2;
materialEditor.TexturePropertySingleLine(Styles.emissiveColor, emissiveMap, emissiveColor);
EditorGUI.indentLevel -= 2;
}
GUI.enabled = !PropertyEnabled(enableSSAA);
materialEditor.ShaderProperty(enableTriplanarMapping, Styles.enableTriplanarMapping);
if (PropertyEnabled(enableTriplanarMapping))
{
materialEditor.ShaderProperty(enableLocalSpaceTriplanarMapping, Styles.enableLocalSpaceTriplanarMapping, 2);
materialEditor.ShaderProperty(triplanarMappingBlendSharpness, Styles.triplanarMappingBlendSharpness, 2);
}
GUI.enabled = true;
GUI.enabled = !PropertyEnabled(enableTriplanarMapping);
// SSAA implementation based off this article: https://medium.com/@bgolus/sharper-mipmapping-using-shader-based-supersampling-ed7aadb47bec
materialEditor.ShaderProperty(enableSSAA, Styles.enableSSAA);
if (PropertyEnabled(enableSSAA))
{
materialEditor.ShaderProperty(mipmapBias, Styles.mipmapBias, 2);
}
GUI.enabled = true;
EditorGUILayout.Space();
materialEditor.TextureScaleOffsetProperty(albedoMap);
}
///
/// Displays inspectors settings for more generic render features.
///
/// Current material editor in use.
/// Current material in use.
protected void RenderingOptions(MaterialEditor materialEditor, Material material)
{
EditorGUILayout.Space();
GUILayout.Label(Styles.renderingOptionsTitle, EditorStyles.boldLabel);
lightMode.floatValue = EditorGUILayout.Popup(Styles.lightMode, (int)lightMode.floatValue, Styles.lightModeNames);
switch ((LightMode)lightMode.floatValue)
{
default:
case LightMode.Unlit:
{
material.DisableKeyword(Styles.lightModeLitDirectional);
material.DisableKeyword(Styles.lightModeLitDistant);
}
break;
case LightMode.LitDirectional:
{
material.EnableKeyword(Styles.lightModeLitDirectional);
material.DisableKeyword(Styles.lightModeLitDistant);
}
break;
case LightMode.LitDistant:
{
material.DisableKeyword(Styles.lightModeLitDirectional);
material.EnableKeyword(Styles.lightModeLitDistant);
GUILayout.Box(string.Format(Styles.propertiesComponentHelp, nameof(DistantLight), Styles.lightModeNames[(int)LightMode.LitDistant]), EditorStyles.helpBox, Array.Empty());
}
break;
}
if ((LightMode)lightMode.floatValue != LightMode.Unlit)
{
materialEditor.ShaderProperty(specularHighlights, Styles.specularHighlights, 2);
materialEditor.ShaderProperty(sphericalHarmonics, Styles.sphericalHarmonics, 2);
materialEditor.ShaderProperty(nonPhotorealisticRendering, Styles.nonPhotorealisticRendering, 2);
}
materialEditor.ShaderProperty(reflections, Styles.reflections);
materialEditor.ShaderProperty(rimLight, Styles.rimLight);
if (PropertyEnabled(rimLight))
{
materialEditor.ShaderProperty(rimColor, Styles.rimColor, 2);
materialEditor.ShaderProperty(rimPower, Styles.rimPower, 2);
}
materialEditor.ShaderProperty(vertexColors, Styles.vertexColors);
materialEditor.ShaderProperty(vertexExtrusion, Styles.vertexExtrusion);
if (PropertyEnabled(vertexExtrusion))
{
materialEditor.ShaderProperty(vertexExtrusionValue, Styles.vertexExtrusionValue, 2);
materialEditor.ShaderProperty(vertexExtrusionSmoothNormals, Styles.vertexExtrusionSmoothNormals, 2);
materialEditor.ShaderProperty(vertexExtrusionConstantWidth, Styles.vertexExtrusionConstantWidth, 2);
}
if ((RenderingMode)renderingMode.floatValue != RenderingMode.Opaque &&
(RenderingMode)renderingMode.floatValue != RenderingMode.Cutout)
{
materialEditor.ShaderProperty(blendedClippingWidth, Styles.blendedClippingWidth);
GUILayout.Box(string.Format(Styles.propertiesComponentHelp, nameof(ClippingPrimitive), "other clipping"), EditorStyles.helpBox, Array.Empty());
}
materialEditor.ShaderProperty(clippingBorder, Styles.clippingBorder);
if (PropertyEnabled(clippingBorder))
{
materialEditor.ShaderProperty(clippingBorderWidth, Styles.clippingBorderWidth, 2);
materialEditor.ShaderProperty(clippingBorderColor, Styles.clippingBorderColor, 2);
GUILayout.Box(string.Format(Styles.propertiesComponentHelp, nameof(ClippingPrimitive), "other clipping"), EditorStyles.helpBox, Array.Empty());
}
materialEditor.ShaderProperty(nearPlaneFade, Styles.nearPlaneFade);
if (PropertyEnabled(nearPlaneFade))
{
materialEditor.ShaderProperty(nearLightFade, Styles.nearLightFade, 2);
materialEditor.ShaderProperty(fadeBeginDistance, Styles.fadeBeginDistance, 2);
materialEditor.ShaderProperty(fadeCompleteDistance, Styles.fadeCompleteDistance, 2);
materialEditor.ShaderProperty(fadeMinValue, Styles.fadeMinValue, 2);
}
}
///
/// Displays inspectors settings for user interface related features.
///
/// Current material editor in use.
/// Current material in use.
protected void FluentOptions(MaterialEditor materialEditor, Material material)
{
/// TODO - [Cameron-Micka] this function has grown quite large. Might make sense to break up into more logical sections?
EditorGUILayout.Space();
GUILayout.Label(Styles.fluentOptionsTitle, EditorStyles.boldLabel);
RenderingMode mode = (RenderingMode)renderingMode.floatValue;
RenderingMode customMode = (RenderingMode)customRenderingMode.floatValue;
materialEditor.ShaderProperty(hoverLight, Styles.hoverLight);
if (PropertyEnabled(hoverLight))
{
GUILayout.Box(string.Format(Styles.propertiesComponentHelp, nameof(HoverLight), Styles.hoverLight.text), EditorStyles.helpBox, Array.Empty());
materialEditor.ShaderProperty(enableHoverColorOverride, Styles.enableHoverColorOverride, 2);
if (PropertyEnabled(enableHoverColorOverride))
{
materialEditor.ShaderProperty(hoverColorOverride, Styles.hoverColorOverride, 4);
}
}
materialEditor.ShaderProperty(proximityLight, Styles.proximityLight);
if (PropertyEnabled(proximityLight))
{
materialEditor.ShaderProperty(enableProximityLightColorOverride, Styles.enableProximityLightColorOverride, 2);
if (PropertyEnabled(enableProximityLightColorOverride))
{
materialEditor.ShaderProperty(proximityLightCenterColorOverride, Styles.proximityLightCenterColorOverride, 4);
materialEditor.ShaderProperty(proximityLightMiddleColorOverride, Styles.proximityLightMiddleColorOverride, 4);
materialEditor.ShaderProperty(proximityLightOuterColorOverride, Styles.proximityLightOuterColorOverride, 4);
}
materialEditor.ShaderProperty(proximityLightSubtractive, Styles.proximityLightSubtractive, 2);
materialEditor.ShaderProperty(proximityLightTwoSided, Styles.proximityLightTwoSided, 2);
GUILayout.Box(string.Format(Styles.propertiesComponentHelp, nameof(ProximityLight), Styles.proximityLight.text), EditorStyles.helpBox, Array.Empty());
}
materialEditor.ShaderProperty(borderLight, Styles.borderLight);
if (PropertyEnabled(borderLight))
{
if (PropertyEnabled(useWorldScale))
{
// Hide range.
EditorGUI.indentLevel += 2;
borderWidth.floatValue = EditorGUILayout.FloatField(Styles.borderWidthWorldScale, borderWidth.floatValue);
EditorGUI.indentLevel -= 2;
}
else
{
materialEditor.ShaderProperty(borderWidth, Styles.borderWidth, 2);
}
materialEditor.ShaderProperty(borderColorMode, Styles.borderColorMode, 2);
/// TODO - [Cameron-Micka] Could switch to using the KeywordEnum property drawer in the future.
switch ((BorderColorMode)borderColorMode.floatValue)
{
default:
case BorderColorMode.Brightness:
{
materialEditor.ShaderProperty(borderMinValue, Styles.borderMinValue, 2);
material.DisableKeyword(Styles.borderColorModeHoverColorName);
material.DisableKeyword(Styles.borderColorModeColorName);
material.DisableKeyword(Styles.borderColorModeGradientName);
}
break;
case BorderColorMode.HoverColor:
{
materialEditor.ShaderProperty(borderMinValue, Styles.borderMinValue, 2);
GUILayout.Box(string.Format("Enable the {0} property and {1} property to alter the color.", Styles.hoverLight.text, Styles.enableHoverColorOverride.text), EditorStyles.helpBox, Array.Empty());
material.EnableKeyword(Styles.borderColorModeHoverColorName);
material.DisableKeyword(Styles.borderColorModeColorName);
material.DisableKeyword(Styles.borderColorModeGradientName);
}
break;
case BorderColorMode.Color:
{
materialEditor.ShaderProperty(borderColor, Styles.borderColor, 2);
material.DisableKeyword(Styles.borderColorModeHoverColorName);
material.EnableKeyword(Styles.borderColorModeColorName);
material.DisableKeyword(Styles.borderColorModeGradientName);
}
break;
case BorderColorMode.Gradient:
{
GUILayout.Box(string.Format("Adjust the {0} property to alter the color.", Styles.gradientMode.text), EditorStyles.helpBox, Array.Empty());
material.DisableKeyword(Styles.borderColorModeHoverColorName);
material.DisableKeyword(Styles.borderColorModeColorName);
material.EnableKeyword(Styles.borderColorModeGradientName);
}
break;
}
materialEditor.ShaderProperty(borderLightReplacesAlbedo, Styles.borderLightReplacesAlbedo, 2);
if (mode == RenderingMode.Cutout || mode == RenderingMode.Fade || mode == RenderingMode.Transparent ||
(mode == RenderingMode.Custom && customMode == RenderingMode.Cutout) ||
(mode == RenderingMode.Custom && customMode == RenderingMode.Fade))
{
materialEditor.ShaderProperty(borderLightOpaque, Styles.borderLightOpaque, 2);
if (PropertyEnabled(borderLightOpaque))
{
materialEditor.ShaderProperty(borderLightOpaqueAlpha, Styles.borderLightOpaqueAlpha, 4);
}
}
}
if (!PropertyEnabled(roundCorners) && PropertyEnabled(borderLight))
{
materialEditor.ShaderProperty(edgeSmoothingMode, Styles.edgeSmoothingMode, 2);
switch ((EdgeSmoothingMode)edgeSmoothingMode.floatValue)
{
default:
case EdgeSmoothingMode.Manual:
{
material.DisableKeyword(Styles.edgeSmoothingModeAutomaticName);
materialEditor.ShaderProperty(edgeSmoothingValue, Styles.edgeSmoothingValue, 3);
}
break;
case EdgeSmoothingMode.Automatic:
{
material.EnableKeyword(Styles.edgeSmoothingModeAutomaticName);
}
break;
}
}
if (PropertyEnabled(hoverLight) || PropertyEnabled(proximityLight) || PropertyEnabled(borderLight))
{
materialEditor.ShaderProperty(fluentLightIntensity, Styles.fluentLightIntensity, 2);
}
materialEditor.ShaderProperty(roundCorners, Styles.roundCorners);
if (PropertyEnabled(roundCorners))
{
materialEditor.ShaderProperty(independentCorners, Styles.independentCorners, 2);
if (PropertyEnabled(independentCorners))
{
materialEditor.ShaderProperty(roundCornersRadius, Styles.roundCornersRadius, 2);
}
else
{
if (PropertyEnabled(useWorldScale))
{
// Hide range.
EditorGUI.indentLevel += 2;
roundCornerRadius.floatValue = EditorGUILayout.FloatField(Styles.roundCornerRadiusWorldScale, roundCornerRadius.floatValue);
EditorGUI.indentLevel -= 2;
}
else
{
materialEditor.ShaderProperty(roundCornerRadius, Styles.roundCornerRadius, 2);
}
}
if (PropertyEnabled(useWorldScale))
{
// Hide range.
EditorGUI.indentLevel += 2;
roundCornerMargin.floatValue = EditorGUILayout.FloatField(Styles.roundCornerMarginWorldScale, roundCornerMargin.floatValue);
EditorGUI.indentLevel -= 2;
}
else
{
materialEditor.ShaderProperty(roundCornerMargin, Styles.roundCornerMargin, 2);
}
if ((RenderingMode)renderingMode.floatValue != RenderingMode.Opaque &&
(RenderingMode)renderingMode.floatValue != RenderingMode.Cutout)
{
materialEditor.ShaderProperty(roundCornersHideInterior, Styles.roundCornersHideInterior, 2);
}
}
if (PropertyEnabled(roundCorners))
{
materialEditor.ShaderProperty(edgeSmoothingMode, Styles.edgeSmoothingMode, 2);
switch ((EdgeSmoothingMode)edgeSmoothingMode.floatValue)
{
default:
case EdgeSmoothingMode.Manual:
{
material.DisableKeyword(Styles.edgeSmoothingModeAutomaticName);
materialEditor.ShaderProperty(edgeSmoothingValue, Styles.edgeSmoothingValue, 3);
}
break;
case EdgeSmoothingMode.Automatic:
{
material.EnableKeyword(Styles.edgeSmoothingModeAutomaticName);
}
break;
}
}
materialEditor.ShaderProperty(innerGlow, Styles.innerGlow);
if (PropertyEnabled(innerGlow))
{
materialEditor.ShaderProperty(innerGlowColor, Styles.innerGlowColor, 2);
materialEditor.ShaderProperty(innerGlowPower, Styles.innerGlowPower, 2);
}
materialEditor.ShaderProperty(gradientMode, Styles.gradientMode);
switch ((GradientMode)gradientMode.floatValue)
{
default:
case GradientMode.None:
{
material.DisableKeyword(Styles.gradientModeIridescence);
material.DisableKeyword(Styles.gradientModeFourPoint);
material.DisableKeyword(Styles.gradientModeLinear);
}
break;
case GradientMode.Iridescence:
{
EditorGUI.indentLevel += 2;
materialEditor.TexturePropertySingleLine(Styles.iridescentSpectrumMap, iridescentSpectrumMap);
EditorGUI.indentLevel -= 2;
materialEditor.ShaderProperty(iridescenceIntensity, Styles.iridescenceIntensity, 2);
materialEditor.ShaderProperty(iridescenceThreshold, Styles.iridescenceThreshold, 2);
materialEditor.ShaderProperty(iridescenceAngle, Styles.iridescenceAngle, 2);
material.EnableKeyword(Styles.gradientModeIridescence);
material.DisableKeyword(Styles.gradientModeFourPoint);
material.DisableKeyword(Styles.gradientModeLinear);
}
break;
case GradientMode.FourPoint:
{
materialEditor.ShaderProperty(gradientColor1, Styles.fourPointGradientTopLeftColor, 2);
materialEditor.ShaderProperty(gradientColor2, Styles.fourPointGradientTopRightColor, 2);
materialEditor.ShaderProperty(gradientColor3, Styles.fourPointGradientBottomLeftColor, 2);
materialEditor.ShaderProperty(gradientColor4, Styles.fourPointGradientBottomRightColor, 2);
if (GUILayout.Button(Styles.fourPointGradientAutoFillButton))
{
Color topLeft, topRight, bottomLeft, bottomRight, stroke;
StandardShaderUtility.AutofillFourPointGradient(gradientColor1.colorValue, out topLeft, out topRight, out bottomLeft, out bottomRight, out stroke);
gradientColor1.colorValue = topLeft;
gradientColor2.colorValue = topRight;
gradientColor3.colorValue = bottomLeft;
gradientColor4.colorValue = bottomRight;
borderColor.colorValue = stroke;
}
material.DisableKeyword(Styles.gradientModeIridescence);
material.EnableKeyword(Styles.gradientModeFourPoint);
material.DisableKeyword(Styles.gradientModeLinear);
}
break;
case GradientMode.Linear:
{
const int maxKeys = 4;
GradientColorKey ToGradientColorKey(MaterialProperty property)
{
Color color = property.colorValue;
return new GradientColorKey(color, color.a);
}
GradientAlphaKey[] ToGradientAlphaKey(MaterialProperty propertyA,
MaterialProperty propertyT)
{
Vector4 alphas = propertyA.vectorValue;
Vector4 times = propertyT.vectorValue;
return new GradientAlphaKey[] { new GradientAlphaKey(alphas.x, times.x),
new GradientAlphaKey(alphas.y, times.y),
new GradientAlphaKey(alphas.z, times.z),
new GradientAlphaKey(alphas.w, times.w) };
}
EditorGUI.BeginChangeCheck();
{
Gradient gradient = new Gradient();
gradient.SetKeys(new GradientColorKey[] { ToGradientColorKey(gradientColor0),
ToGradientColorKey(gradientColor1),
ToGradientColorKey(gradientColor2),
ToGradientColorKey(gradientColor3) },
ToGradientAlphaKey(gradientAlpha, gradientAlphaTime));
EditorGUI.indentLevel += 2;
EditorGUILayout.HelpBox(Styles.linearGradientHelp);
gradient = EditorGUILayout.GradientField(Styles.linearGradientColor, gradient);
EditorGUI.indentLevel -= 2;
if (EditorGUI.EndChangeCheck())
{
List colorKeys = new List(gradient.colorKeys);
// Ensure we always have 'maxKeys' colors keys.
while (colorKeys.Count < maxKeys)
{
colorKeys.Add(colorKeys[colorKeys.Count - 1]);
}
Color ToColorTime(GradientColorKey colorKey)
{
return new Color(colorKey.color.r, colorKey.color.g, colorKey.color.b, colorKey.time);
}
gradientColor0.colorValue = ToColorTime(colorKeys[0]);
gradientColor1.colorValue = ToColorTime(colorKeys[1]);
gradientColor2.colorValue = ToColorTime(colorKeys[2]);
gradientColor3.colorValue = ToColorTime(colorKeys[3]);
List alphaKeys = new List(gradient.alphaKeys);
// Ensure we always have 'maxKeys' alpha keys.
while (alphaKeys.Count < maxKeys)
{
alphaKeys.Add(alphaKeys[alphaKeys.Count - 1]);
}
gradientAlpha.vectorValue = new Vector4(alphaKeys[0].alpha, alphaKeys[1].alpha, alphaKeys[2].alpha, alphaKeys[3].alpha);
gradientAlphaTime.vectorValue = new Vector4(alphaKeys[0].time, alphaKeys[1].time, alphaKeys[2].time, alphaKeys[3].time);
}
}
materialEditor.ShaderProperty(gradientAngle, Styles.linearGradientAngle, 2);
EditorGUI.indentLevel += 2;
EditorGUILayout.LabelField(Styles.linearCssGradient, EditorStyles.boldLabel);
EditorGUI.BeginChangeCheck();
{
EditorGUILayout.BeginHorizontal("Label");
{
cssGradient = EditorGUILayout.TextField(cssGradient);
GUILayout.Box(string.IsNullOrEmpty(cssGradient) ?
EditorGUIUtility.IconContent("orangeLight") :
cssGradientValid ?
EditorGUIUtility.IconContent("greenLight") :
EditorGUIUtility.IconContent("redLight"),
GUILayout.Height(16));
}
EditorGUILayout.EndHorizontal();
EditorGUI.indentLevel -= 2;
if (EditorGUI.EndChangeCheck())
{
Color[] gradientColors;
float[] gradientKeys;
float angle;
if (StandardShaderUtility.TryParseCSSGradient(cssGradient, out gradientColors, out gradientKeys, out angle))
{
List colors = new List(gradientColors);
List keys = new List(gradientKeys);
// Ensure we always have 'maxKeys' colors/keys.
while (colors.Count < maxKeys)
{
colors.Add(colors[colors.Count - 1]);
keys.Add(keys[keys.Count - 1]);
}
Color ToColorTime(Color color, float key)
{
return new Color(color.r, color.g, color.b, key);
}
gradientColor0.colorValue = ToColorTime(colors[0], keys[0]);
gradientColor1.colorValue = ToColorTime(colors[1], keys[1]);
gradientColor2.colorValue = ToColorTime(colors[2], keys[2]);
gradientColor3.colorValue = ToColorTime(colors[3], keys[3]);
gradientAlpha.vectorValue = new Color(colors[0].a, colors[1].a, colors[2].a, colors[3].a);
gradientAlphaTime.vectorValue = new Color(keys[0], keys[1], keys[2], keys[3]);
gradientAngle.floatValue = angle;
cssGradientValid = true;
}
else
{
cssGradientValid = false;
}
}
}
material.DisableKeyword(Styles.gradientModeIridescence);
material.DisableKeyword(Styles.gradientModeFourPoint);
material.EnableKeyword(Styles.gradientModeLinear);
}
break;
}
materialEditor.ShaderProperty(environmentColoring, Styles.environmentColoring);
if (PropertyEnabled(environmentColoring))
{
materialEditor.ShaderProperty(environmentColorThreshold, Styles.environmentColorThreshold, 2);
materialEditor.ShaderProperty(environmentColorIntensity, Styles.environmentColorIntensity, 2);
materialEditor.ShaderProperty(environmentColorX, Styles.environmentColorX, 2);
materialEditor.ShaderProperty(environmentColorY, Styles.environmentColorY, 2);
materialEditor.ShaderProperty(environmentColorZ, Styles.environmentColorZ, 2);
}
materialEditor.ShaderProperty(blurMode, Styles.blurMode);
BlurMode currentBlurMode = (BlurMode)blurMode.floatValue;
switch (currentBlurMode)
{
default:
case BlurMode.None:
{
material.DisableKeyword(Styles.blurModeLayer1Name);
material.DisableKeyword(Styles.blurModeLayer2Name);
material.DisableKeyword(Styles.blurModePrebakedBackgroundName);
}
break;
case BlurMode.Layer1:
{
material.EnableKeyword(Styles.blurModeLayer1Name);
material.DisableKeyword(Styles.blurModeLayer2Name);
material.DisableKeyword(Styles.blurModePrebakedBackgroundName);
}
break;
case BlurMode.Layer2:
{
material.DisableKeyword(Styles.blurModeLayer1Name);
material.EnableKeyword(Styles.blurModeLayer2Name);
material.DisableKeyword(Styles.blurModePrebakedBackgroundName);
}
break;
case BlurMode.PrebakedBackground:
{
material.DisableKeyword(Styles.blurModeLayer1Name);
material.DisableKeyword(Styles.blurModeLayer2Name);
material.EnableKeyword(Styles.blurModePrebakedBackgroundName);
}
break;
}
if (currentBlurMode != BlurMode.None)
{
materialEditor.ShaderProperty(blurTextureIntensity, Styles.blurTextureIntensity, 2);
if (PropertyEnabled(borderLight))
{
materialEditor.ShaderProperty(blurBorderIntensity, Styles.blurBorderIntensity, 2);
}
if (currentBlurMode == BlurMode.PrebakedBackground)
{
GUI.enabled = false;
materialEditor.ShaderProperty(blurBackgroundRect, Styles.blurBackgroundRect, 2);
GUI.enabled = true;
}
}
}
///
/// Displays inspectors settings for features users don't need to alter often.
///
/// Current material editor in use.
/// Current material in use.
protected void AdvancedOptions(MaterialEditor materialEditor, Material material)
{
EditorGUILayout.Space();
GUILayout.Label(Styles.advancedOptionsTitle, EditorStyles.boldLabel);
EditorGUI.BeginChangeCheck();
materialEditor.ShaderProperty(renderQueueOverride, BaseStyles.renderQueueOverride);
if (EditorGUI.EndChangeCheck())
{
MaterialChanged(material);
}
// Show the RenderQueueField but do not allow users to directly manipulate it. That is done via the renderQueueOverride.
GUI.enabled = false;
materialEditor.RenderQueueField();
GUI.enabled = true;
materialEditor.EnableInstancingField();
materialEditor.ShaderProperty(enableStencil, Styles.stencil);
if (PropertyEnabled(enableStencil))
{
materialEditor.ShaderProperty(stencilReference, Styles.stencilReference, 2);
materialEditor.ShaderProperty(stencilComparison, Styles.stencilComparison, 2);
materialEditor.ShaderProperty(stencilOperation, Styles.stencilOperation, 2);
materialEditor.ShaderProperty(stencilWriteMask, Styles.stencilWriteMask, 2);
materialEditor.ShaderProperty(stencilReadMask, Styles.stencilReadMask, 2);
}
else
{
// When stencil is disable, revert to the default stencil operations. Note, when tested on D3D11 hardware the stencil state
// is still set even when the CompareFunction.Disabled is selected, but this does not seem to affect performance.
material.SetInt(Styles.stencilComparisonName, (int)CompareFunction.Disabled);
material.SetInt(Styles.stencilOperationName, (int)StencilOp.Keep);
}
bool scaleRequired = ScaleRequired();
if (scaleRequired)
{
materialEditor.ShaderProperty(useWorldScale, Styles.useWorldScale);
}
// Static and dynamic batching will normalize the object scale, which breaks features which utilize object scale.
material.SetOverrideTag("DisableBatching", scaleRequired ? "True" : "False");
}
///
/// Returns true if the material has a feature enabled that requires world scale of the object be known.
///
/// True if scale is required to render properly.
protected bool ScaleRequired()
{
return PropertyEnabled(vertexExtrusion) ||
PropertyEnabled(roundCorners) ||
PropertyEnabled(borderLight) ||
((GradientMode)gradientMode.floatValue == GradientMode.Linear) ||
(PropertyEnabled(enableTriplanarMapping) && PropertyEnabled(enableLocalSpaceTriplanarMapping));
}
///
/// Enables/disables features based on the albedo settings.
///
/// Current material in use.
/// Albedo texture.
/// Albedo alpha channel usage.
/// Flag if the albedo map can be added at runtime, disables optimizations if true.
protected static void SetupMaterialWithAlbedo(Material material, MaterialProperty albedoMap, MaterialProperty albedoAlphaMode, MaterialProperty albedoAssignedAtRuntime)
{
if (albedoMap.textureValue || PropertyEnabled(albedoAssignedAtRuntime))
{
material.DisableKeyword(Styles.disableAlbedoMapName);
}
else
{
material.EnableKeyword(Styles.disableAlbedoMapName);
}
switch ((AlbedoAlphaMode)albedoAlphaMode.floatValue)
{
case AlbedoAlphaMode.Transparency:
{
material.DisableKeyword(Styles.albedoMapAlphaMetallicName);
material.DisableKeyword(Styles.albedoMapAlphaSmoothnessName);
}
break;
case AlbedoAlphaMode.Metallic:
{
material.EnableKeyword(Styles.albedoMapAlphaMetallicName);
material.DisableKeyword(Styles.albedoMapAlphaSmoothnessName);
}
break;
case AlbedoAlphaMode.Smoothness:
{
material.DisableKeyword(Styles.albedoMapAlphaMetallicName);
material.EnableKeyword(Styles.albedoMapAlphaSmoothnessName);
}
break;
}
}
}
}