您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
215 行
7.2 KiB
215 行
7.2 KiB
using System;
|
|
using System.Reflection;
|
|
using UnityEditor.Graphing;
|
|
using UnityEditor.Graphing.Drawing;
|
|
using UnityEngine;
|
|
using UnityEngine.Graphing;
|
|
using UnityEngine.MaterialGraph;
|
|
using Object = UnityEngine.Object;
|
|
|
|
namespace UnityEditor.MaterialGraph
|
|
{
|
|
[CustomNodeUI(typeof(AbstractMaterialNode))]
|
|
public class AbstractMaterialNodeUI : ICustomNodeUi
|
|
{
|
|
private MaterialGraphPreviewGenerator m_PreviewGenerator;
|
|
|
|
[NonSerialized]
|
|
private int m_LastShaderVersion = -1;
|
|
|
|
[NonSerialized]
|
|
private Material m_PreviewMaterial;
|
|
|
|
[NonSerialized]
|
|
private Shader m_PreviewShader;
|
|
|
|
private AbstractMaterialNode m_Node;
|
|
|
|
private PreviewMode m_GeneratedShaderMode = PreviewMode.Preview2D;
|
|
|
|
public Material previewMaterial
|
|
{
|
|
get
|
|
{
|
|
if (m_PreviewMaterial == null)
|
|
{
|
|
m_PreviewMaterial = new Material(Shader.Find("Unlit/Color")) {hideFlags = HideFlags.HideInHierarchy};
|
|
m_PreviewMaterial.hideFlags = HideFlags.HideInHierarchy;
|
|
}
|
|
return m_PreviewMaterial;
|
|
}
|
|
}
|
|
|
|
private MaterialGraphPreviewGenerator previewGenerator
|
|
{
|
|
get
|
|
{
|
|
if (m_PreviewGenerator == null)
|
|
{
|
|
m_PreviewGenerator = new MaterialGraphPreviewGenerator();
|
|
}
|
|
return m_PreviewGenerator;
|
|
}
|
|
}
|
|
|
|
private float m_PreviewWidth;
|
|
public virtual float GetNodeUiHeight(float width)
|
|
{
|
|
if (!m_Node.drawState.expanded)
|
|
return 0;
|
|
|
|
if (m_Node.hasPreview == false)
|
|
return 0;
|
|
|
|
m_PreviewWidth = width - 20;
|
|
return m_PreviewWidth;
|
|
}
|
|
|
|
public INode node
|
|
{
|
|
get { return m_Node; }
|
|
set
|
|
{
|
|
var materialNode = value as AbstractMaterialNode;
|
|
if (materialNode != null)
|
|
m_Node = materialNode;
|
|
}
|
|
}
|
|
|
|
public PreviewMode generatedShaderMode
|
|
{
|
|
get { return m_GeneratedShaderMode; }
|
|
set { m_GeneratedShaderMode = value; }
|
|
}
|
|
|
|
public virtual float GetNodeWidth()
|
|
{
|
|
return 200;
|
|
}
|
|
|
|
public virtual GUIModificationType Render(Rect area)
|
|
{
|
|
if (m_Node == null || !m_Node.drawState.expanded)
|
|
return GUIModificationType.None;
|
|
|
|
if (m_Node.hasPreview == false)
|
|
return GUIModificationType.None;
|
|
|
|
if (m_LastShaderVersion != m_Node.version)
|
|
{
|
|
if (UpdatePreviewShader())
|
|
m_LastShaderVersion = m_Node.version;
|
|
}
|
|
|
|
var preview = RenderPreview(area);
|
|
GL.sRGBWrite = QualitySettings.activeColorSpace == ColorSpace.Linear;
|
|
GUI.DrawTexture(area, preview, ScaleMode.StretchToFill, false);
|
|
GL.sRGBWrite = false;
|
|
return GUIModificationType.None;
|
|
}
|
|
|
|
protected virtual string GetPreviewShaderString()
|
|
{
|
|
return ShaderGenerator.GeneratePreviewShader(m_Node, out m_GeneratedShaderMode);
|
|
}
|
|
|
|
private bool UpdatePreviewShader()
|
|
{
|
|
if (m_Node == null || m_Node.hasError)
|
|
return false;
|
|
|
|
var resultShader = GetPreviewShaderString();
|
|
Debug.Log("RecreateShaderAndMaterial : " + m_Node.GetVariableNameForNode() + Environment.NewLine + resultShader);
|
|
|
|
if (string.IsNullOrEmpty(resultShader))
|
|
return false;
|
|
|
|
// workaround for some internal shader compiler weirdness
|
|
// if we are in error we sometimes to not properly clean
|
|
// out the error flags and will stay in error, even
|
|
// if we are now valid
|
|
if (m_PreviewShader && ShaderHasError(m_PreviewShader))
|
|
{
|
|
Object.DestroyImmediate(m_PreviewShader, true);
|
|
m_PreviewShader = null;
|
|
}
|
|
|
|
if (m_PreviewShader == null)
|
|
{
|
|
m_PreviewShader = ShaderUtil.CreateShaderAsset(resultShader);
|
|
m_PreviewShader.hideFlags = HideFlags.HideAndDontSave;
|
|
}
|
|
else
|
|
{
|
|
ShaderUtil.UpdateShaderAsset(m_PreviewShader, resultShader);
|
|
}
|
|
|
|
return !ShaderHasError(m_PreviewShader);
|
|
}
|
|
|
|
public static bool ShaderHasError(Shader shader)
|
|
{
|
|
var hasErrorsCall = typeof(ShaderUtil).GetMethod("GetShaderErrorCount", BindingFlags.Static | BindingFlags.NonPublic);
|
|
var result = hasErrorsCall.Invoke(null, new object[] {shader});
|
|
return (int)result != 0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// RenderPreview gets called in OnPreviewGUI. Nodes can override
|
|
/// RenderPreview and do their own rendering to the render texture
|
|
/// </summary>
|
|
public Texture RenderPreview(Rect targetSize)
|
|
{
|
|
previewMaterial.shader = m_PreviewShader;
|
|
UpdateMaterialProperties(m_Node, previewMaterial);
|
|
return previewGenerator.DoRenderPreview(previewMaterial, m_GeneratedShaderMode, targetSize);
|
|
}
|
|
|
|
private static void SetPreviewMaterialProperty(PreviewProperty previewProperty, Material mat)
|
|
{
|
|
switch (previewProperty.m_PropType)
|
|
{
|
|
case PropertyType.Texture2D:
|
|
mat.SetTexture(previewProperty.m_Name, previewProperty.m_Texture);
|
|
break;
|
|
case PropertyType.Color:
|
|
mat.SetColor(previewProperty.m_Name, previewProperty.m_Color);
|
|
break;
|
|
case PropertyType.Vector2:
|
|
mat.SetVector(previewProperty.m_Name, previewProperty.m_Vector4);
|
|
break;
|
|
case PropertyType.Vector3:
|
|
mat.SetVector(previewProperty.m_Name, previewProperty.m_Vector4);
|
|
break;
|
|
case PropertyType.Vector4:
|
|
mat.SetVector(previewProperty.m_Name, previewProperty.m_Vector4);
|
|
break;
|
|
case PropertyType.Float:
|
|
mat.SetFloat(previewProperty.m_Name, previewProperty.m_Float);
|
|
break;
|
|
}
|
|
}
|
|
|
|
public static void UpdateMaterialProperties(AbstractMaterialNode target, Material material)
|
|
{
|
|
var childNodes = ListPool<INode>.Get();
|
|
NodeUtils.DepthFirstCollectNodesFromNode(childNodes, target);
|
|
|
|
var pList = ListPool<PreviewProperty>.Get();
|
|
for (var index = 0; index < childNodes.Count; index++)
|
|
{
|
|
var node = childNodes[index] as AbstractMaterialNode;
|
|
if (node == null)
|
|
continue;
|
|
|
|
node.CollectPreviewMaterialProperties(pList);
|
|
}
|
|
|
|
foreach (var prop in pList)
|
|
SetPreviewMaterialProperty(prop, material);
|
|
|
|
ListPool<INode>.Release(childNodes);
|
|
ListPool<PreviewProperty>.Release(pList);
|
|
}
|
|
}
|
|
}
|