Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[2021.2][URP][ShaderGraph] Enable automatic render queue control on SG-based material inspector #4610

Merged
merged 5 commits into from
Jun 10, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions com.unity.render-pipelines.universal/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Fixed renderer creation in playmode to have its property reloaded. [case 1333463]
- Fixed gizmos no longer allocate memory in game view. [case 1328852]
- Fixed an issue where shadow artefacts appeared between cascades on Terrain Detail objects.
- Fixed ShaderGraph materials to select render queue in the same way as handwritten shader materials by default, but allows for a user override for custom behavior. [case 1335795]

### Changed
- Change Asset/Create/Shader/Universal Render Pipeline/Lit Shader Graph to Asset/Create/Shader Graph/URP/Lit Shader Graph
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,19 @@ public enum RenderFace
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();
Expand Down Expand Up @@ -118,6 +125,9 @@ protected class Styles

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.");
}

#endregion
Expand Down Expand Up @@ -156,6 +166,8 @@ protected class Styles

protected MaterialProperty queueOffsetProp { get; set; }

protected MaterialProperty queueControlProp { get; set; }

public bool m_FirstTimeApply = true;

// By default, everything is expanded, except advanced
Expand Down Expand Up @@ -190,6 +202,7 @@ public virtual void FindProperties(MaterialProperty[] properties)

// 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);
Expand Down Expand Up @@ -424,6 +437,48 @@ internal static void UpdateMaterialSurfaceOptions(Material material, bool automa
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, 0); // Automatic behavior - surface type override
jessebarker marked this conversation as resolved.
Show resolved Hide resolved
}
else
{
material.SetFloat(Property.QueueControl, 1); // User has selected explicit render queue
jessebarker marked this conversation as resolved.
Show resolved Hide resolved
}
}

internal static bool GetAutomaticQueueControlSetting(Material material)
{
// If the material doesn't yet have the queue control property, we should not engage automatic behavior until
// the shader gets reimported.
bool automaticQueueControl = false;
if (material.HasProperty(Property.QueueControl))
{
var queueControl = material.GetFloat(Property.QueueControl);
if (queueControl < 0.0f)
{
UpdateMaterialRenderQueueControl(material);
}
automaticQueueControl = (material.GetFloat(Property.QueueControl) == 0.0f);
}
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)
{
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"reference": "GUID:2bafac87e7f4b9b418d9448d219b01ab"
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -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;
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ public static void UpdateMaterial(Material material, MaterialUpdateType updateTy
if (updateType == MaterialUpdateType.CreatedNewMaterial)
material.globalIlluminationFlags = MaterialGlobalIlluminationFlags.BakedEmissive;

BaseShaderGUI.UpdateMaterialSurfaceOptions(material, automaticRenderQueue: false);
bool automaticRenderQueue = GetAutomaticQueueControlSetting(material);
BaseShaderGUI.UpdateMaterialSurfaceOptions(material, automaticRenderQueue);
jessebarker marked this conversation as resolved.
Show resolved Hide resolved
LitGUI.SetupSpecularWorkflowKeyword(material, out bool isSpecularWorkflow);
}

Expand Down Expand Up @@ -67,7 +68,10 @@ public override void DrawSurfaceInputs(Material material)

public override void DrawAdvancedOptions(Material material)
{
materialEditor.RenderQueueField();
// 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) == 1.0f)
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
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using UnityEngine;
using UnityEditor.Rendering.Universal;
using static Unity.Rendering.Universal.ShaderUtils;

namespace UnityEditor
Expand All @@ -20,7 +21,8 @@ public override void FindProperties(MaterialProperty[] properties)

public static void UpdateMaterial(Material material, MaterialUpdateType updateType)
{
BaseShaderGUI.UpdateMaterialSurfaceOptions(material, automaticRenderQueue: false);
bool automaticRenderQueue = GetAutomaticQueueControlSetting(material);
BaseShaderGUI.UpdateMaterialSurfaceOptions(material, automaticRenderQueue);
}

public override void ValidateMaterial(Material material)
Expand All @@ -36,7 +38,10 @@ public override void DrawSurfaceInputs(Material material)

public override void DrawAdvancedOptions(Material material)
{
materialEditor.RenderQueueField();
// 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) == 1.0f)
materialEditor.RenderQueueField();
base.DrawAdvancedOptions(material);
materialEditor.DoubleSidedGIField();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,12 @@ public override void ProcessPreviewMaterial(Material material)
material.SetFloat(Property.ZTest, (float)target.zTestMode);
}

// We always need these properties regardless of whether the material is allowed to override
// Queue control & offset enable correct automatic render queue behavior
// Control == 0 is automatic, 1 is user-specified render queue
material.SetFloat(Property.QueueOffset, 0.0f);
material.SetFloat(Property.QueueControl, 0.0f);

// call the full unlit material setup function
ShaderGraphLitGUI.UpdateMaterial(material, MaterialUpdateType.CreatedNewMaterial);
}
Expand Down Expand Up @@ -157,6 +163,12 @@ public override void CollectShaderProperties(PropertyCollector collector, Genera
collector.AddFloatProperty(Property.ZTest, (float)target.zTestMode); // ztest mode is designed to directly pass as ztest
collector.AddFloatProperty(Property.CullMode, (float)target.renderFace); // render face enum is designed to directly pass as a cull mode
}

// We always need these properties regardless of whether the material is allowed to override other shader properties.
// Queue control & offset enable correct automatic render queue behavior. Control == 0 is automatic, 1 is user-specified.
// We initialize queue control to -1 to indicate to UpdateMaterial that it needs to initialize it properly on the material.
collector.AddFloatProperty(Property.QueueOffset, 0.0f);
collector.AddFloatProperty(Property.QueueControl, -1.0f);
}

public override void GetPropertiesGUI(ref TargetPropertyGUIContext context, Action onChange, Action<String> registerUndo)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ public override void ProcessPreviewMaterial(Material material)
material.SetFloat(Property.ZTest, (float)target.zTestMode);
}

// We always need these properties regardless of whether the material is allowed to override
// Queue control & offset enable correct automatic render queue behavior
// Control == 0 is automatic, 1 is user-specified render queue
material.SetFloat(Property.QueueOffset, 0.0f);
jessebarker marked this conversation as resolved.
Show resolved Hide resolved
material.SetFloat(Property.QueueControl, 0.0f);

// call the full unlit material setup function
ShaderGraphUnlitGUI.UpdateMaterial(material, MaterialUpdateType.CreatedNewMaterial);
}
Expand Down Expand Up @@ -84,6 +90,12 @@ public override void CollectShaderProperties(PropertyCollector collector, Genera
collector.AddFloatProperty(Property.ZTest, (float)target.zTestMode); // ztest mode is designed to directly pass as ztest
collector.AddFloatProperty(Property.CullMode, (float)target.renderFace); // render face enum is designed to directly pass as a cull mode
}

// We always need these properties regardless of whether the material is allowed to override other shader properties.
// Queue control & offset enable correct automatic render queue behavior. Control == 0 is automatic, 1 is user-specified.
// We initialize queue control to -1 to indicate to UpdateMaterial that it needs to initialize it properly on the material.
collector.AddFloatProperty(Property.QueueOffset, 0.0f);
collector.AddFloatProperty(Property.QueueControl, -1.0f);
}

public override void GetPropertiesGUI(ref TargetPropertyGUIContext context, Action onChange, Action<String> registerUndo)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ internal static class Property
// for ShaderGraph shaders only
public static readonly string ZTest = "_ZTest";
public static readonly string ZWriteControl = "_ZWriteControl";
public static readonly string QueueControl = "_QueueControl";

// Global Illumination requires some properties to be named specifically:
public static readonly string EmissionMap = "_EmissionMap";
Expand Down
1 change: 1 addition & 0 deletions com.unity.shadergraph/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Fixed an issue where SamplerState properties could not be renamed after creation [1336126]
- Fixed loading all materials from project when saving a ShaderGraph.
- Fixed a ShaderGraph issue where resize handles on blackboard and graph inspector were too small [1329247] (https://issuetracker.unity3d.com/issues/shadergraph-resize-bounds-for-blackboard-and-graph-inspector-are-too-small)
- Fixed a ShaderGraph issue where a material inspector could contain an extra set of render queue, GPU instancing, and double-sided GI controls.

## [11.0.0] - 2020-10-21

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,6 @@ public static void DrawShaderGraphGUI(MaterialEditor materialEditor, IEnumerable
{
DrawCategory(materialEditor, properties, mcd);
}

EditorGUILayout.Space();
EditorGUILayout.Space();
if (SupportedRenderingFeatures.active.editableMaterialRenderQueue)
{
materialEditor.RenderQueueField();
}
materialEditor.EnableInstancingField();
materialEditor.DoubleSidedGIField();
}

private static void DrawCategory(MaterialEditor materialEditor, IEnumerable<MaterialProperty> properties, MinimalCategoryData minimalCategoryData)
Expand Down