浏览代码

Full-resolution preview in blackboard

/main
Peter Bay Bastian 7 年前
当前提交
14bcb1d7
共有 5 个文件被更改,包括 131 次插入123 次删除
  1. 46
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Inspector/GraphInspectorView.cs
  2. 3
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/MaterialGraphEditWindow.cs
  3. 185
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/PreviewManager.cs
  4. 4
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/GraphEditorView.cs
  5. 16
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/MaterialNodeView.cs

46
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Inspector/GraphInspectorView.cs


AbstractMaterialGraph m_Graph;
PreviewManager m_PreviewManager;
MasterNode m_MasterNode;
PreviewData m_PreviewHandle;
PreviewRenderData m_PreviewRenderHandle;
List<INode> m_SelectedNodes;

}
Add(bottomContainer);
masterNode = graph.GetNodes<MasterNode>().FirstOrDefault();
m_PreviewRenderHandle = previewManager.masterRenderData;
m_PreviewRenderHandle.onPreviewChanged += OnPreviewChanged;
foreach (var property in m_Graph.properties)
m_PropertyItems.Add(new ShaderPropertyView(m_Graph, property));

MasterNode masterNode
{
get { return m_MasterNode; }
set
{
if (value == m_MasterNode)
return;
if (m_MasterNode != null)
m_PreviewHandle.onPreviewChanged -= OnPreviewChanged;
m_PreviewHandle = null;
m_MasterNode = value;
if (m_MasterNode != null)
{
m_PreviewHandle = m_PreviewManager.GetPreview(m_MasterNode);
m_PreviewHandle.onPreviewChanged += OnPreviewChanged;
}
}
get { return m_PreviewRenderHandle.shaderData.node as MasterNode; }
}
void OnAddProperty()

void OnPreviewChanged()
{
m_PreviewTextureView.image = m_PreviewHandle.texture ?? Texture2D.blackTexture;
m_PreviewTextureView.image = m_PreviewRenderHandle.texture ?? Texture2D.blackTexture;
m_PreviewTextureView.Dirty(ChangeType.Repaint);
}

{
m_PreviewHandle.mesh = null;
m_PreviewRenderHandle.mesh = null;
m_PersistentMasterNodePreviewMesh.mesh = null;
}

{
m_PreviewHandle.mesh = changedMesh;
m_PreviewRenderHandle.mesh = changedMesh;
m_PersistentMasterNodePreviewMesh.mesh = changedMesh;
}

foreach (var layer in layerGraph.addedLayers)
m_LayerItems.Add(new ShaderLayerView(layerGraph, layer));
}
if (masterNode != null)
{
if (m_Graph.removedNodes.Contains(masterNode))
masterNode = null;
}
if (masterNode == null)
{
var addedMasterNode = m_Graph.addedNodes.OfType<MasterNode>().FirstOrDefault();
if (addedMasterNode != null)
masterNode = addedMasterNode;
}
if (m_PreviewHandle != null)
if (m_PreviewRenderHandle != null)
m_PreviewHandle.onPreviewChanged -= OnPreviewChanged;
m_PreviewHandle = null;
m_PreviewRenderHandle.onPreviewChanged -= OnPreviewChanged;
m_PreviewRenderHandle = null;
}
}
}

3
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/MaterialGraphEditWindow.cs


graphEditorView = new GraphEditorView(materialGraph, asset.name) {persistenceKey = AssetDatabase.AssetPathToGUID(AssetDatabase.GUIDToAssetPath(selectedGuid))};
}
graphEditorView.previewManager.HandleGraphChanges();
graphEditorView.previewManager.RenderPreviews();
graphEditorView.inspectorView.HandleGraphChanges();
graphObject.graph.ClearChanges();
}

185
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/PreviewManager.cs


public class PreviewManager : IDisposable
{
AbstractMaterialGraph m_Graph;
Dictionary<Guid, PreviewData> m_Previews = new Dictionary<Guid, PreviewData>();
Dictionary<Guid, PreviewRenderData> m_RenderDatas = new Dictionary<Guid, PreviewRenderData>();
Dictionary<Guid, PreviewShaderData> m_ShaderDatas = new Dictionary<Guid, PreviewShaderData>();
PreviewRenderData m_MasterRenderData;
HashSet<Guid> m_DirtyPreviews = new HashSet<Guid>();
HashSet<Guid> m_DirtyShaders = new HashSet<Guid>();
HashSet<Guid> m_TimeDependentPreviews = new HashSet<Guid>();

public PreviewRate previewRate { get; set; }
public PreviewRenderData masterRenderData
{
get { return m_MasterRenderData; }
}
public PreviewManager(AbstractMaterialGraph graph)
{
m_Graph = graph;

m_UberShader = ShaderUtil.CreateShaderAsset(k_EmptyShader);
m_UberShader.hideFlags = HideFlags.HideAndDontSave;
m_UberShaderIds = new Dictionary<Guid, int>();
m_MasterRenderData = new PreviewRenderData
{
renderTexture = new RenderTexture(400, 400, 16, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Default) { hideFlags = HideFlags.HideAndDontSave }
};
public PreviewData GetPreview(INode node)
public PreviewRenderData GetPreview(INode node)
return m_Previews[node.guid];
return m_RenderDatas[node.guid];
var previewData = new PreviewData
PreviewShaderData shaderData;
if (!m_ShaderDatas.TryGetValue(node.guid, out shaderData))
{
shaderData = new PreviewShaderData
{
node = node
};
m_ShaderDatas[node.guid] = shaderData;
}
var previewData = new PreviewRenderData
node = node,
shaderData = shaderData,
if (m_Previews.ContainsKey(node.guid))
if (m_RenderDatas.ContainsKey(node.guid))
m_Previews.Add(node.guid, previewData);
m_RenderDatas.Add(node.guid, previewData);
var masterNode = node as IMasterNode;
if (masterRenderData.shaderData == null && masterNode != null)
{
masterRenderData.shaderData = shaderData;
}
m_Previews.Remove(node.guid);
m_RenderDatas.Remove(node.guid);
if (masterRenderData.shaderData != null && masterRenderData.shaderData.node == node)
masterRenderData.shaderData = m_ShaderDatas.Values.FirstOrDefault(x => x.node is IMasterNode);
}
void OnNodeModified(INode node, ModificationScope scope)

m_DirtyShaders.Add(edge.inputSlot.nodeGuid);
}
List<PreviewData> m_RenderList2D = new List<PreviewData>();
List<PreviewData> m_RenderList3D = new List<PreviewData>();
List<PreviewRenderData> m_RenderList2D = new List<PreviewRenderData>();
List<PreviewRenderData> m_RenderList3D = new List<PreviewRenderData>();
HashSet<Guid> m_NodesWith3DPreview = new HashSet<Guid>();
public void RenderPreviews()

foreach (var node in uberNodes)
{
PreviewData previewData;
if (!m_Previews.TryGetValue(node.guid, out previewData))
PreviewShaderData shaderData;
if (!m_ShaderDatas.TryGetValue(node.guid, out shaderData))
previewData.previewMode = m_NodesWith3DPreview.Contains(node.guid) ? PreviewMode.Preview3D : PreviewMode.Preview2D;
previewData.shader = m_UberShader;
shaderData.previewMode = m_NodesWith3DPreview.Contains(node.guid) ? PreviewMode.Preview3D : PreviewMode.Preview2D;
shaderData.shader = m_UberShader;
}
i++;
EditorUtility.DisplayProgressBar("Shader Graph", string.Format("Compiling preview shaders ({0}/{1})", i, count), 0f);

foreach (var nodeGuid in m_DirtyPreviews)
{
PreviewData previewData;
if (!m_Previews.TryGetValue(nodeGuid, out previewData))
PreviewRenderData renderData;
if (!m_RenderDatas.TryGetValue(nodeGuid, out renderData))
if (previewData.shader == null)
if (renderData.shaderData.shader == null)
previewData.texture = null;
renderData.texture = null;
if (MaterialGraphAsset.ShaderHasError(previewData.shader))
if (MaterialGraphAsset.ShaderHasError(renderData.shaderData.shader))
previewData.texture = m_ErrorTexture;
renderData.texture = m_ErrorTexture;
if (previewData.previewMode == PreviewMode.Preview2D)
m_RenderList2D.Add(previewData);
if (renderData.shaderData.previewMode == PreviewMode.Preview2D)
m_RenderList2D.Add(renderData);
m_RenderList3D.Add(previewData);
m_RenderList3D.Add(renderData);
if (masterRenderData.shaderData != null && m_DirtyPreviews.Contains(masterRenderData.shaderData.node.guid))
m_RenderList3D.Add(masterRenderData);
var time = Time.realtimeSinceStartup;
EditorUtility.SetCameraAnimateMaterialsTime(m_SceneResources.camera, time);

m_SceneResources.camera.transform.rotation = Quaternion.identity;
m_SceneResources.camera.orthographicSize = 1;
m_SceneResources.camera.orthographic = true;
foreach (var previewData in m_RenderList2D)
foreach (var renderData in m_RenderList2D)
if (m_UberShaderIds.TryGetValue(previewData.node.guid, out outputId))
if (m_UberShaderIds.TryGetValue(renderData.shaderData.node.guid, out outputId))
m_PreviewMaterial.shader = previewData.shader;
m_SceneResources.camera.targetTexture = previewData.renderTexture;
m_PreviewMaterial.shader = renderData.shaderData.shader;
m_SceneResources.camera.targetTexture = renderData.renderTexture;
RenderTexture.active = previewData.renderTexture;
RenderTexture.active = renderData.renderTexture;
Graphics.Blit(Texture2D.whiteTexture, previewData.renderTexture, m_SceneResources.checkerboardMaterial);
Graphics.Blit(Texture2D.whiteTexture, renderData.renderTexture, m_SceneResources.checkerboardMaterial);
Graphics.DrawMesh(m_SceneResources.quad, Matrix4x4.identity, m_PreviewMaterial, 1, m_SceneResources.camera, 0, m_PreviewPropertyBlock, ShadowCastingMode.Off, false, null, false);
var previousUseSRP = Unsupported.useScriptableRenderPipeline;
Unsupported.useScriptableRenderPipeline = false;

previewData.texture = previewData.renderTexture;
renderData.texture = renderData.renderTexture;
m_RenderList2D.Clear();
// Render 3D previews
m_SceneResources.camera.transform.position = -Vector3.forward * 5;

{
int outputId;
if (m_UberShaderIds.TryGetValue(previewData.node.guid, out outputId))
if (m_UberShaderIds.TryGetValue(previewData.shaderData.node.guid, out outputId))
m_PreviewMaterial.shader = previewData.shader;
m_PreviewMaterial.shader = previewData.shaderData.shader;
m_SceneResources.camera.targetTexture = previewData.renderTexture;
var previousRenderTexure = RenderTexture.active;
RenderTexture.active = previewData.renderTexture;

Graphics.DrawMesh(mesh, Matrix4x4.TRS(-mesh.bounds.center, Quaternion.identity, Vector3.one), m_PreviewMaterial, 1, m_SceneResources.camera, 0, m_PreviewPropertyBlock, ShadowCastingMode.Off, false, null, false);
var previousUseSRP = Unsupported.useScriptableRenderPipeline;
Unsupported.useScriptableRenderPipeline = previewData.node is IMasterNode;
Unsupported.useScriptableRenderPipeline = previewData.shaderData.node is IMasterNode;
m_RenderList3D.Clear();
foreach (var nodeGuid in m_DirtyPreviews)
foreach (var previewRenderData in m_RenderList2D.Union(m_RenderList3D))
PreviewData previewData;
if (!m_Previews.TryGetValue(nodeGuid, out previewData))
continue;
if (previewData.onPreviewChanged != null)
previewData.onPreviewChanged();
if (previewRenderData.onPreviewChanged != null)
previewRenderData.onPreviewChanged();
m_RenderList2D.Clear();
m_RenderList3D.Clear();
m_DirtyPreviews.Clear();
}

if (node == null)
return;
PreviewData previewData;
if (!m_Previews.TryGetValue(nodeGuid, out previewData))
PreviewShaderData shaderData;
if (!m_ShaderDatas.TryGetValue(nodeGuid, out shaderData))
previewData.previewMode = m_NodesWith3DPreview.Contains(nodeGuid) ? PreviewMode.Preview3D : PreviewMode.Preview2D;
shaderData.previewMode = m_NodesWith3DPreview.Contains(nodeGuid) ? PreviewMode.Preview3D : PreviewMode.Preview2D;
previewData.shaderString = null;
shaderData.shaderString = null;
previewData.shaderString = m_Graph.GetPreviewShader(node, out mode);
shaderData.shaderString = m_Graph.GetPreviewShader(node, out mode);
File.WriteAllText(Application.dataPath + "/../GeneratedShader.shader", (previewData.shaderString ?? "null").Replace("UnityEngine.MaterialGraph", "Generated"));
File.WriteAllText(Application.dataPath + "/../GeneratedShader.shader", (shaderData.shaderString ?? "null").Replace("UnityEngine.MaterialGraph", "Generated"));
if (string.IsNullOrEmpty(previewData.shaderString))
if (string.IsNullOrEmpty(shaderData.shaderString))
if (previewData.shader != null)
Object.DestroyImmediate(previewData.shader, true);
previewData.shader = null;
if (shaderData.shader != null)
Object.DestroyImmediate(shaderData.shader, true);
shaderData.shader = null;
if (previewData.shader != null && MaterialGraphAsset.ShaderHasError(previewData.shader))
if (shaderData.shader != null && MaterialGraphAsset.ShaderHasError(shaderData.shader))
ShaderUtil.ClearShaderErrors(previewData.shader);
Object.DestroyImmediate(previewData.shader, true);
previewData.shader = null;
ShaderUtil.ClearShaderErrors(shaderData.shader);
Object.DestroyImmediate(shaderData.shader, true);
shaderData.shader = null;
if (previewData.shader == null)
if (shaderData.shader == null)
previewData.shader = ShaderUtil.CreateShaderAsset(previewData.shaderString);
previewData.shader.hideFlags = HideFlags.HideAndDontSave;
shaderData.shader = ShaderUtil.CreateShaderAsset(shaderData.shaderString);
shaderData.shader.hideFlags = HideFlags.HideAndDontSave;
ShaderUtil.ClearShaderErrors(previewData.shader);
ShaderUtil.UpdateShaderAsset(previewData.shader, previewData.shaderString);
ShaderUtil.ClearShaderErrors(shaderData.shader);
ShaderUtil.UpdateShaderAsset(shaderData.shader, shaderData.shaderString);
var message = "RecreateShader: " + node.GetVariableNameForNode() + Environment.NewLine + previewData.shaderString;
if (MaterialGraphAsset.ShaderHasError(previewData.shader))
var message = "RecreateShader: " + node.GetVariableNameForNode() + Environment.NewLine + shaderData.shaderString;
if (MaterialGraphAsset.ShaderHasError(shaderData.shader))
void DestroyPreview(Guid nodeGuid, PreviewData previewData)
void DestroyPreview(Guid nodeGuid, PreviewRenderData previewRenderData)
if (m_Previews.Remove(nodeGuid))
if (m_RenderDatas.Remove(nodeGuid))
if (previewData.shader != null)
Object.DestroyImmediate(previewData.shader, true);
if (previewData.renderTexture != null)
Object.DestroyImmediate(previewData.renderTexture, true);
if (previewRenderData.shaderData.shader != null)
Object.DestroyImmediate(previewRenderData.shaderData.shader, true);
if (previewRenderData.renderTexture != null)
Object.DestroyImmediate(previewRenderData.renderTexture, true);
var node = m_Graph.GetNodeFromGuid(nodeGuid);
if (node != null)
node.onModified -= OnNodeModified;

previewData.shader = null;
previewData.renderTexture = null;
previewData.texture = null;
previewData.onPreviewChanged = null;
previewRenderData.shaderData.shader = null;
previewRenderData.renderTexture = null;
previewRenderData.texture = null;
previewRenderData.onPreviewChanged = null;
}
}

if (m_SceneResources != null)
m_SceneResources.Dispose();
m_SceneResources = null;
var previews = m_Previews.ToList();
var previews = m_RenderDatas.ToList();
foreach (var kvp in previews)
DestroyPreview(kvp.Key, kvp.Value);
}

public delegate void OnPreviewChanged();
public class PreviewData
public class PreviewShaderData
public Mesh mesh { get; set; }
}
public class PreviewRenderData
{
public PreviewShaderData shaderData { get; set; }
public Mesh mesh { get; set; }
public RenderTexture renderTexture { get; set; }
public Texture texture { get; set; }
public OnPreviewChanged onPreviewChanged;

4
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/GraphEditorView.cs


public void HandleGraphChanges()
{
previewManager.HandleGraphChanges();
previewManager.RenderPreviews();
inspectorView.HandleGraphChanges();
foreach (var node in m_Graph.removedNodes)
{
node.onModified -= OnNodeChanged;

16
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/MaterialNodeView.cs


public sealed class MaterialNodeView : Node
{
List<VisualElement> m_ControlViews;
PreviewData m_PreviewData;
PreviewRenderData m_PreviewRenderData;
PreviewTextureView m_PreviewTextureView;
VisualElement m_ControlsContainer;
VisualElement m_PreviewContainer;

pickingMode = PickingMode.Ignore,
image = Texture2D.whiteTexture
};
m_PreviewData = previewManager.GetPreview(inNode);
m_PreviewData.onPreviewChanged += UpdatePreviewTexture;
m_PreviewRenderData = previewManager.GetPreview(inNode);
m_PreviewRenderData.onPreviewChanged += UpdatePreviewTexture;
UpdatePreviewTexture();
m_PreviewContainer.Add(m_PreviewTextureView);

void UpdatePreviewTexture()
{
if (m_PreviewData.texture == null || !node.previewExpanded)
if (m_PreviewRenderData.texture == null || !node.previewExpanded)
{
m_PreviewTextureView.visible = false;
m_PreviewTextureView.image = Texture2D.blackTexture;

m_PreviewTextureView.visible = true;
m_PreviewTextureView.AddToClassList("visible");
m_PreviewTextureView.RemoveFromClassList("hidden");
m_PreviewTextureView.image = m_PreviewData.texture;
m_PreviewTextureView.image = m_PreviewRenderData.texture;
}
m_PreviewTextureView.Dirty(ChangeType.Repaint);
}

m_Attachers.Clear();
node = null;
if (m_PreviewData != null)
if (m_PreviewRenderData != null)
m_PreviewData.onPreviewChanged -= UpdatePreviewTexture;
m_PreviewData = null;
m_PreviewRenderData.onPreviewChanged -= UpdatePreviewTexture;
m_PreviewRenderData = null;
}
}
}
正在加载...
取消
保存