187 lines
7.6 KiB
C#
187 lines
7.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.Rendering.HighDefinition;
|
|
using System.Linq;
|
|
|
|
// Include material common properties names
|
|
using static UnityEngine.Rendering.HighDefinition.HDMaterialProperties;
|
|
|
|
namespace UnityEditor.Rendering.HighDefinition
|
|
{
|
|
/// <summary>
|
|
/// The UI block that represents Shader Graph material properties.
|
|
/// This UI block displays every non-hidden property inside a shader. You can also use this with non-shadergraph shaders.
|
|
/// </summary>
|
|
public class ShaderGraphUIBlock : MaterialUIBlock
|
|
{
|
|
/// <summary>ShaderGraph UI Block features.</summary>
|
|
[Flags]
|
|
public enum Features
|
|
{
|
|
/// <summary>Nothing is displayed.</summary>
|
|
None = 0,
|
|
/// <summary>Display the exposed properties.</summary>
|
|
ExposedProperties = 1 << 1,
|
|
/// <summary>Display the default exposed diffusion profile from the graph.</summary>
|
|
DiffusionProfileAsset = 1 << 2,
|
|
/// <summary>Display the shadow matte options.</summary>
|
|
ShadowMatte = 1 << 5,
|
|
/// <summary>Display all the Unlit fields.</summary>
|
|
Unlit = ExposedProperties | ShadowMatte,
|
|
/// <summary>Display all the fields.</summary>
|
|
All = ~0,
|
|
}
|
|
|
|
internal static class Styles
|
|
{
|
|
public const string header = "Exposed Properties";
|
|
}
|
|
|
|
ExpandableBit m_ExpandableBit;
|
|
Features m_Features;
|
|
|
|
/// <summary>
|
|
/// Constructs a ShaderGraphUIBlock based on the parameters.
|
|
/// </summary>
|
|
/// <param name="expandableBit">Bit index used to store the foldout state.</param>
|
|
/// <param name="features">Features enabled in the block.</param>
|
|
public ShaderGraphUIBlock(ExpandableBit expandableBit = ExpandableBit.ShaderGraph, Features features = Features.All)
|
|
{
|
|
m_ExpandableBit = expandableBit;
|
|
m_Features = features;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Loads the material properties for the block.
|
|
/// </summary>
|
|
public override void LoadMaterialProperties() {}
|
|
|
|
/// <summary>
|
|
/// Renders the properties in the block.
|
|
/// </summary>
|
|
public override void OnGUI()
|
|
{
|
|
using (var header = new MaterialHeaderScope(Styles.header, (uint)m_ExpandableBit, materialEditor))
|
|
{
|
|
if (header.expanded)
|
|
DrawShaderGraphGUI();
|
|
}
|
|
}
|
|
|
|
MaterialProperty[] oldProperties;
|
|
|
|
bool CheckPropertyChanged(MaterialProperty[] properties)
|
|
{
|
|
bool propertyChanged = false;
|
|
|
|
if (oldProperties != null)
|
|
{
|
|
// Check if shader was changed (new/deleted properties)
|
|
if (properties.Length != oldProperties.Length)
|
|
{
|
|
propertyChanged = true;
|
|
}
|
|
else
|
|
{
|
|
for (int i = 0; i < properties.Length; i++)
|
|
{
|
|
if (properties[i].type != oldProperties[i].type)
|
|
propertyChanged = true;
|
|
if (properties[i].displayName != oldProperties[i].displayName)
|
|
propertyChanged = true;
|
|
if (properties[i].flags != oldProperties[i].flags)
|
|
propertyChanged = true;
|
|
if (properties[i].name != oldProperties[i].name)
|
|
propertyChanged = true;
|
|
if (properties[i].floatValue != oldProperties[i].floatValue)
|
|
propertyChanged = true;
|
|
if (properties[i].vectorValue != oldProperties[i].vectorValue)
|
|
propertyChanged = true;
|
|
if (properties[i].colorValue != oldProperties[i].colorValue)
|
|
propertyChanged = true;
|
|
if (properties[i].textureValue != oldProperties[i].textureValue)
|
|
propertyChanged = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
oldProperties = properties;
|
|
|
|
return propertyChanged;
|
|
}
|
|
|
|
void DrawShaderGraphGUI()
|
|
{
|
|
// Filter out properties we don't want to draw:
|
|
if ((m_Features & Features.ExposedProperties) != 0)
|
|
PropertiesDefaultGUI(properties);
|
|
|
|
// If we change a property in a shadergraph, we trigger a material keyword reset
|
|
if (CheckPropertyChanged(properties))
|
|
{
|
|
foreach (var material in materials)
|
|
HDShaderUtils.ResetMaterialKeywords(material);
|
|
}
|
|
|
|
if ((m_Features & Features.DiffusionProfileAsset) != 0)
|
|
DrawDiffusionProfileUI();
|
|
|
|
if ((m_Features & Features.ShadowMatte) != 0 && materials.All(m => m.HasProperty(kShadowMatteFilter)))
|
|
DrawShadowMatteToggle();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Draws the material properties.
|
|
/// </summary>
|
|
/// <param name="properties">List of Material Properties to draw</param>
|
|
protected void PropertiesDefaultGUI(MaterialProperty[] properties)
|
|
{
|
|
for (var i = 0; i < properties.Length; i++)
|
|
{
|
|
if ((properties[i].flags & (MaterialProperty.PropFlags.HideInInspector | MaterialProperty.PropFlags.PerRendererData)) != 0)
|
|
continue;
|
|
|
|
float h = materialEditor.GetPropertyHeight(properties[i], properties[i].displayName);
|
|
Rect r = EditorGUILayout.GetControlRect(true, h, EditorStyles.layerMaskField);
|
|
|
|
materialEditor.ShaderProperty(r, properties[i], properties[i].displayName);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Draws the Shadow Matte settings. This is only available for Unlit materials.
|
|
/// </summary>
|
|
protected void DrawShadowMatteToggle()
|
|
{
|
|
uint exponent = 0b10000000; // 0 as exponent
|
|
uint mantissa = 0x007FFFFF;
|
|
|
|
float value = materials[0].GetFloat(HDMaterialProperties.kShadowMatteFilter);
|
|
uint uValue = HDShadowUtils.Asuint(value);
|
|
uint filter = uValue & mantissa;
|
|
|
|
bool shadowFilterPoint = (filter & (uint)LightFeatureFlags.Punctual) != 0;
|
|
bool shadowFilterDir = (filter & (uint)LightFeatureFlags.Directional) != 0;
|
|
bool shadowFilterRect = (filter & (uint)LightFeatureFlags.Area) != 0;
|
|
uint finalFlag = 0x00000000;
|
|
finalFlag |= EditorGUILayout.Toggle("Point/Spot Shadow", shadowFilterPoint) ? (uint)LightFeatureFlags.Punctual : 0x00000000u;
|
|
finalFlag |= EditorGUILayout.Toggle("Directional Shadow", shadowFilterDir) ? (uint)LightFeatureFlags.Directional : 0x00000000u;
|
|
finalFlag |= EditorGUILayout.Toggle("Area Shadow", shadowFilterRect) ? (uint)LightFeatureFlags.Area : 0x00000000u;
|
|
finalFlag &= mantissa;
|
|
finalFlag |= exponent;
|
|
|
|
materials[0].SetFloat(HDMaterialProperties.kShadowMatteFilter, HDShadowUtils.Asfloat(finalFlag));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Draw the built-in exposed Diffusion Profile when a material uses sub-surface scattering or transmission.
|
|
/// </summary>
|
|
protected void DrawDiffusionProfileUI()
|
|
{
|
|
if (DiffusionProfileMaterialUI.IsSupported(materialEditor))
|
|
DiffusionProfileMaterialUI.OnGUI(materialEditor, FindProperty("_DiffusionProfileAsset"), FindProperty("_DiffusionProfileHash"), 0);
|
|
}
|
|
}
|
|
}
|