浏览代码

Plug CustomGUI to MaterialGraph for HDRenderLoop

/scriptablerenderloop-materialgraph
Paul Demeulenaere 8 年前
当前提交
c26b4333
共有 3 个文件被更改,包括 297 次插入240 次删除
  1. 2
      Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.cs
  2. 18
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Lit/Lit.template
  3. 517
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Lit/LitUI.cs

2
Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.cs


struct Attributes
{
float3 positionOS : POSITION;
float3 positionOS : POSITION;
${VertexAttributes}
};

18
Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Lit/Lit.template


Properties
{
${ShaderPropertiesHeader}
[ToggleOff] _AlphaCutoffEnable("Alpha Cutoff Enable", Float) = 0.0
_AlphaCutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5
[HideInInspector] _SurfaceType("__surfacetype", Float) = 0.0
[HideInInspector] _SrcBlend ("__src", Float) = 1.0
[HideInInspector] _BlendMode ("__blendmode", Float) = 0.0
[HideInInspector] _DstBlend ("__dst", Float) = 0.0
[HideInInspector] _ZWrite ("__zw", Float) = 1.0
[HideInInspector] _CullMode("__cullmode", Float) = 2.0
[HideInInspector] _MaterialId("_MaterialId", Float) = 0
[Enum(None, 0, DoubleSided, 1, DoubleSidedLigthingFlip, 2, DoubleSidedLigthingMirror, 3)] _DoubleSidedMode("Double sided mode", Float) = 0
}
HLSLINCLUDE

Name "Forward" // Name is not used
Tags{ "LightMode" = "Forward" } // This will be only for transparent object based on the RenderQueue index
//TODO
//Blend[_SrcBlend][_DstBlend]
//ZWrite[_ZWrite]
//Cull[_CullMode]
Blend[_SrcBlend][_DstBlend]
ZWrite[_ZWrite]
Cull[_CullMode]
HLSLPROGRAM

ENDHLSL
}
}
CustomEditor "LitGraphUI"
}

517
Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Lit/LitUI.cs


using System;
using System.Linq;
internal class LitGUI : ShaderGUI
class BaseLitGUI : ShaderGUI
public enum SurfaceType
{
Opaque,
Transparent
}
public enum BlendMode
{
Lerp,
Add,
SoftAdd,
Multiply,
Premultiply
}
public enum SmoothnessMapChannel
{
MaskAlpha,
AlbedoAlpha,
}
public enum EmissiveColorMode
{
UseEmissiveColor,
UseEmissiveMask,
}
public enum DoubleSidedMode
{
None,
DoubleSided,
DoubleSidedLightingFlip,
DoubleSidedLightingMirror,
}
public enum NormalMapSpace
{
TangentSpace,
ObjectSpace,
}
public enum HeightmapMode
{
Parallax,
Displacement,
}
private static class Styles
protected static class Styles
{
public static string OptionText = "Options";
public static string SurfaceTypeText = "Surface Type";

}
MaterialProperty surfaceType = null;
MaterialProperty blendMode = null;
MaterialProperty alphaCutoff = null;
MaterialProperty alphaCutoffEnable = null;
MaterialProperty doubleSidedMode = null;
public enum SurfaceType
{
Opaque,
Transparent
}
public enum BlendMode
{
Lerp,
Add,
SoftAdd,
Multiply,
Premultiply
}
public enum DoubleSidedMode
{
None,
DoubleSided,
DoubleSidedLightingFlip,
DoubleSidedLightingMirror,
}
void SurfaceTypePopup()
{
EditorGUI.showMixedValue = surfaceType.hasMixedValue;
var mode = (SurfaceType)surfaceType.floatValue;
EditorGUI.BeginChangeCheck();
mode = (SurfaceType)EditorGUILayout.Popup(Styles.SurfaceTypeText, (int)mode, Styles.surfaceTypeNames);
if (EditorGUI.EndChangeCheck())
{
m_MaterialEditor.RegisterPropertyChangeUndo("Surface Type");
surfaceType.floatValue = (float)mode;
}
EditorGUI.showMixedValue = false;
}
protected void ShaderOptionsGUI()
{
EditorGUI.indentLevel++;
GUILayout.Label(Styles.OptionText, EditorStyles.boldLabel);
SurfaceTypePopup();
if ((SurfaceType)surfaceType.floatValue == SurfaceType.Transparent)
{
BlendModePopup();
}
m_MaterialEditor.ShaderProperty(alphaCutoffEnable, Styles.alphaCutoffEnableText.text);
if (alphaCutoffEnable.floatValue == 1.0)
{
m_MaterialEditor.ShaderProperty(alphaCutoff, Styles.alphaCutoffText.text);
}
m_MaterialEditor.ShaderProperty(doubleSidedMode, Styles.doubleSidedModeText.text);
EditorGUI.indentLevel--;
}
private void BlendModePopup()
{
EditorGUI.showMixedValue = blendMode.hasMixedValue;
var mode = (BlendMode)blendMode.floatValue;
EditorGUI.BeginChangeCheck();
mode = (BlendMode)EditorGUILayout.Popup(Styles.BlendModeText, (int)mode, Styles.blendModeNames);
if (EditorGUI.EndChangeCheck())
{
m_MaterialEditor.RegisterPropertyChangeUndo("Blend Mode");
blendMode.floatValue = (float)mode;
}
EditorGUI.showMixedValue = false;
}
protected void FindOptionProperties(MaterialProperty[] props)
{
surfaceType = FindProperty(kSurfaceType, props);
blendMode = FindProperty(kBlendMode, props);
alphaCutoff = FindProperty(kAlphaCutoff, props);
alphaCutoffEnable = FindProperty(kAlphaCutoffEnabled, props);
doubleSidedMode = FindProperty(kDoubleSidedMode, props);
}
protected void SetupMaterial(Material material)
{
bool alphaTestEnable = material.GetFloat(kAlphaCutoffEnabled) == 1.0;
SurfaceType surfaceType = (SurfaceType)material.GetFloat(kSurfaceType);
BlendMode blendMode = (BlendMode)material.GetFloat(kBlendMode);
DoubleSidedMode doubleSidedMode = (DoubleSidedMode)material.GetFloat(kDoubleSidedMode);
if (surfaceType == SurfaceType.Opaque)
{
material.SetOverrideTag("RenderType", alphaTestEnable ? "TransparentCutout" : "");
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
material.SetInt("_ZWrite", 1);
material.renderQueue = alphaTestEnable ? (int)UnityEngine.Rendering.RenderQueue.AlphaTest : -1;
}
else
{
material.SetOverrideTag("RenderType", "Transparent");
material.SetInt("_ZWrite", 0);
material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent;
switch (blendMode)
{
case BlendMode.Lerp:
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
break;
case BlendMode.Add:
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.One);
break;
case BlendMode.SoftAdd:
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusDstColor);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.One);
break;
case BlendMode.Multiply:
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.DstColor);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
break;
case BlendMode.Premultiply:
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
break;
}
}
if (doubleSidedMode == DoubleSidedMode.None)
{
material.SetInt("_CullMode", (int)UnityEngine.Rendering.CullMode.Back);
}
else
{
material.SetInt("_CullMode", (int)UnityEngine.Rendering.CullMode.Off);
}
if (doubleSidedMode == DoubleSidedMode.DoubleSidedLightingFlip)
{
material.EnableKeyword("_DOUBLESIDED_LIGHTING_FLIP");
material.DisableKeyword("_DOUBLESIDED_LIGHTING_MIRROR");
}
else if (doubleSidedMode == DoubleSidedMode.DoubleSidedLightingMirror)
{
material.DisableKeyword("_DOUBLESIDED_LIGHTING_FLIP");
material.EnableKeyword("_DOUBLESIDED_LIGHTING_MIRROR");
}
else
{
material.DisableKeyword("_DOUBLESIDED_LIGHTING_FLIP");
material.DisableKeyword("_DOUBLESIDED_LIGHTING_MIRROR");
}
SetKeyword(material, "_ALPHATEST_ON", alphaTestEnable);
}
protected void SetKeyword(Material m, string keyword, bool state)
{
if (state)
m.EnableKeyword(keyword);
else
m.DisableKeyword(keyword);
}
public void ShaderPropertiesGUI(Material material)
{
// Use default labelWidth
EditorGUIUtility.labelWidth = 0f;
// Detect any changes to the material
EditorGUI.BeginChangeCheck();
{
ShaderOptionsGUI();
EditorGUILayout.Space();
ShaderInputOptionsGUI();
EditorGUILayout.Space();
ShaderInputGUI();
}
if (EditorGUI.EndChangeCheck())
{
foreach (var obj in m_MaterialEditor.targets)
SetupMaterial((Material)obj);
}
}
public virtual void FindInputProperties(MaterialProperty[] props) { }
protected virtual void ShaderInputGUI() { }
protected virtual void ShaderInputOptionsGUI() { }
public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] props)
{
FindOptionProperties(props); // MaterialProperties can be animated so we do not cache them but fetch them every event to ensure animated values are updated correctly
FindInputProperties(props);
m_MaterialEditor = materialEditor;
Material material = materialEditor.target as Material;
ShaderPropertiesGUI(material);
}
protected MaterialEditor m_MaterialEditor;
private MaterialProperty surfaceType = null;
private MaterialProperty alphaCutoffEnable = null;
private MaterialProperty blendMode = null;
private MaterialProperty alphaCutoff = null;
private MaterialProperty doubleSidedMode = null;
private const string kSurfaceType = "_SurfaceType";
private const string kBlendMode = "_BlendMode";
private const string kAlphaCutoff = "_AlphaCutoff";
private const string kAlphaCutoffEnabled = "_AlphaCutoffEnable";
private const string kDoubleSidedMode = "_DoubleSidedMode";
protected static string[] reservedProperties = new string[] { kSurfaceType, kBlendMode, kAlphaCutoff, kAlphaCutoffEnabled, kDoubleSidedMode };
}
class LitGraphUI : BaseLitGUI
{
private MaterialProperty[] genericProperties = new MaterialProperty[] { };
public override void FindInputProperties(MaterialProperty[] props)
{
genericProperties = props.Where(p => (p.flags & MaterialProperty.PropFlags.HideInInspector) == 0 & !reservedProperties.Contains(p.name)).ToArray();
}
protected override void ShaderInputOptionsGUI()
{
EditorGUI.indentLevel++;
foreach(var prop in genericProperties)
{
if ((prop.type & MaterialProperty.PropType.Texture) != 0)
{
m_MaterialEditor.TexturePropertySingleLine(new GUIContent(prop.name), prop);
}
else
{
m_MaterialEditor.ShaderProperty(prop, prop.name);
}
}
EditorGUI.indentLevel--;
}
}
class LitGUI : BaseLitGUI
{
public enum SmoothnessMapChannel
{
MaskAlpha,
AlbedoAlpha,
}
public enum EmissiveColorMode
{
UseEmissiveColor,
UseEmissiveMask,
}
public enum NormalMapSpace
{
TangentSpace,
ObjectSpace,
}
public enum HeightmapMode
{
Parallax,
Displacement,
}
MaterialProperty smoothnessMapChannel = null;
MaterialProperty emissiveColorMode = null;

// MaterialProperty subSurfaceRadius = null;
// MaterialProperty subSurfaceRadiusMap = null;
protected MaterialEditor m_MaterialEditor;
protected const string kSurfaceType = "_SurfaceType";
protected const string kBlendMode = "_BlendMode";
protected const string kAlphaCutoff = "_AlphaCutoff";
protected const string kAlphaCutoffEnabled = "_AlphaCutoffEnable";
protected const string kDoubleSidedMode = "_DoubleSidedMode";
protected const string kSmoothnessTextureChannelProp = "_SmoothnessTextureChannel";
protected const string kEmissiveColorMode = "_EmissiveColorMode";
protected const string kNormalMapSpace = "_NormalMapSpace";

protected const string kTangentMap = "_TangentMap";
protected const string kAnisotropyMap = "_AnisotropyMap";
public void FindOptionProperties(MaterialProperty[] props)
new public void FindOptionProperties(MaterialProperty[] props)
surfaceType = FindProperty(kSurfaceType, props);
blendMode = FindProperty(kBlendMode, props);
alphaCutoff = FindProperty(kAlphaCutoff, props);
alphaCutoffEnable = FindProperty(kAlphaCutoffEnabled, props);
doubleSidedMode = FindProperty(kDoubleSidedMode, props);
base.FindOptionProperties(props);
smoothnessMapChannel = FindProperty(kSmoothnessTextureChannelProp, props);
emissiveColorMode = FindProperty(kEmissiveColorMode, props);
normalMapSpace = FindProperty(kNormalMapSpace, props);

public void FindInputProperties(MaterialProperty[] props)
override public void FindInputProperties(MaterialProperty[] props)
{
baseColor = FindProperty("_BaseColor", props);
baseColorMap = FindProperty("_BaseColorMap", props);

emissiveIntensity = FindProperty("_EmissiveIntensity", props);
}
public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] props)
{
FindOptionProperties(props); // MaterialProperties can be animated so we do not cache them but fetch them every event to ensure animated values are updated correctly
FindInputProperties(props);
m_MaterialEditor = materialEditor;
Material material = materialEditor.target as Material;
ShaderPropertiesGUI(material);
}
protected void ShaderOptionsGUI()
{
EditorGUI.indentLevel++;
GUILayout.Label(Styles.OptionText, EditorStyles.boldLabel);
SurfaceTypePopup();
if ((SurfaceType)surfaceType.floatValue == SurfaceType.Transparent)
{
BlendModePopup();
}
m_MaterialEditor.ShaderProperty(alphaCutoffEnable, Styles.alphaCutoffEnableText.text);
if (alphaCutoffEnable.floatValue == 1.0)
{
m_MaterialEditor.ShaderProperty(alphaCutoff, Styles.alphaCutoffText.text);
}
m_MaterialEditor.ShaderProperty(doubleSidedMode, Styles.doubleSidedModeText.text);
EditorGUI.indentLevel--;
}
protected void ShaderInputOptionsGUI()
override protected void ShaderInputOptionsGUI()
{
EditorGUI.indentLevel++;
GUILayout.Label(Styles.InputsOptionsText, EditorStyles.boldLabel);

EditorGUI.indentLevel--;
}
protected void ShaderInputGUI()
override protected void ShaderInputGUI()
{
EditorGUI.indentLevel++;
bool smoothnessInAlbedoAlpha = (SmoothnessMapChannel)smoothnessMapChannel.floatValue == SmoothnessMapChannel.AlbedoAlpha;

EditorGUI.indentLevel--;
}
public void ShaderPropertiesGUI(Material material)
{
// Use default labelWidth
EditorGUIUtility.labelWidth = 0f;
// Detect any changes to the material
EditorGUI.BeginChangeCheck();
{
ShaderOptionsGUI();
EditorGUILayout.Space();
ShaderInputOptionsGUI();
EditorGUILayout.Space();
ShaderInputGUI();
}
if (EditorGUI.EndChangeCheck())
{
foreach (var obj in m_MaterialEditor.targets)
SetupMaterial((Material)obj);
}
}
// TODO: try to setup minimun value to fall back to standard shaders and reverse
public override void AssignNewShaderToMaterial(Material material, Shader oldShader, Shader newShader)
{

void SurfaceTypePopup()
{
EditorGUI.showMixedValue = surfaceType.hasMixedValue;
var mode = (SurfaceType)surfaceType.floatValue;
EditorGUI.BeginChangeCheck();
mode = (SurfaceType)EditorGUILayout.Popup(Styles.SurfaceTypeText, (int)mode, Styles.surfaceTypeNames);
if (EditorGUI.EndChangeCheck())
{
m_MaterialEditor.RegisterPropertyChangeUndo("Surface Type");
surfaceType.floatValue = (float)mode;
}
EditorGUI.showMixedValue = false;
}
void BlendModePopup()
{
EditorGUI.showMixedValue = blendMode.hasMixedValue;
var mode = (BlendMode)blendMode.floatValue;
EditorGUI.BeginChangeCheck();
mode = (BlendMode)EditorGUILayout.Popup(Styles.BlendModeText, (int)mode, Styles.blendModeNames);
if (EditorGUI.EndChangeCheck())
{
m_MaterialEditor.RegisterPropertyChangeUndo("Blend Mode");
blendMode.floatValue = (float)mode;
}
EditorGUI.showMixedValue = false;
}
protected virtual void SetupKeywordsForInputMaps(Material material)
{
SetKeyword(material, "_NORMALMAP", material.GetTexture(kNormalMap));

SetKeyword(material, "_ANISOTROPYMAP", material.GetTexture(kAnisotropyMap));
}
protected void SetupMaterial(Material material)
new protected void SetupMaterial(Material material)
bool alphaTestEnable = material.GetFloat(kAlphaCutoffEnabled) == 1.0;
SurfaceType surfaceType = (SurfaceType)material.GetFloat(kSurfaceType);
BlendMode blendMode = (BlendMode)material.GetFloat(kBlendMode);
DoubleSidedMode doubleSidedMode = (DoubleSidedMode)material.GetFloat(kDoubleSidedMode);
base.SetupMaterial(material);
if (surfaceType == SurfaceType.Opaque)
{
material.SetOverrideTag("RenderType", alphaTestEnable ? "TransparentCutout" : "");
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
material.SetInt("_ZWrite", 1);
material.renderQueue = alphaTestEnable ? (int)UnityEngine.Rendering.RenderQueue.AlphaTest : -1;
}
else
{
material.SetOverrideTag("RenderType", "Transparent");
material.SetInt("_ZWrite", 0);
material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent;
switch (blendMode)
{
case BlendMode.Lerp:
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
break;
case BlendMode.Add:
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.One);
break;
case BlendMode.SoftAdd:
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusDstColor);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.One);
break;
case BlendMode.Multiply:
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.DstColor);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
break;
case BlendMode.Premultiply:
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
break;
}
}
if (doubleSidedMode == DoubleSidedMode.None)
{
material.SetInt("_CullMode", (int)UnityEngine.Rendering.CullMode.Back);
}
else
{
material.SetInt("_CullMode", (int)UnityEngine.Rendering.CullMode.Off);
}
if (doubleSidedMode == DoubleSidedMode.DoubleSidedLightingFlip)
{
material.EnableKeyword("_DOUBLESIDED_LIGHTING_FLIP");
material.DisableKeyword("_DOUBLESIDED_LIGHTING_MIRROR");
}
else if (doubleSidedMode == DoubleSidedMode.DoubleSidedLightingMirror)
{
material.DisableKeyword("_DOUBLESIDED_LIGHTING_FLIP");
material.EnableKeyword("_DOUBLESIDED_LIGHTING_MIRROR");
}
else
{
material.DisableKeyword("_DOUBLESIDED_LIGHTING_FLIP");
material.DisableKeyword("_DOUBLESIDED_LIGHTING_MIRROR");
}
SetKeyword(material, "_ALPHATEST_ON", alphaTestEnable);
SetKeyword(material, "_NORMALMAP_TANGENT_SPACE", (NormalMapSpace)material.GetFloat(kNormalMapSpace) == NormalMapSpace.TangentSpace);
SetKeyword(material, "_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A", ((SmoothnessMapChannel)material.GetFloat(kSmoothnessTextureChannelProp)) == SmoothnessMapChannel.AlbedoAlpha);
SetKeyword(material, "_EMISSIVE_COLOR", ((EmissiveColorMode)material.GetFloat(kEmissiveColorMode)) == EmissiveColorMode.UseEmissiveColor);

*/
return true;
}
protected void SetKeyword(Material m, string keyword, bool state)
{
if (state)
m.EnableKeyword(keyword);
else
m.DisableKeyword(keyword);
}
}
} // namespace UnityEditor
正在加载...
取消
保存