Peter Bay Bastian
7 年前
当前提交
bec6cdbb
共有 14 个文件被更改,包括 555 次插入 和 488 次删除
-
12MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/AbstractMaterialGraphEditWindow.cs
-
32MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Inspector/GraphInspectorPresenter.cs
-
31MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Inspector/GraphInspectorView.cs
-
89MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/MaterialGraphPreviewGenerator.cs
-
32MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Presenters/GraphEditorPresenter.cs
-
96MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Presenters/MaterialGraphPresenter.cs
-
47MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Presenters/MaterialNodePresenter.cs
-
29MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/MaterialNodeView.cs
-
33MaterialGraphProject/Assets/UnityShaderEditor/Editor/Resources/Styles/MaterialGraph.uss
-
16MaterialGraphProject/Assets/UnityShaderEditor/Editor/Testing/IntegrationTests/ShaderGenerationTest.cs
-
355MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/PreviewSystem.cs
-
3MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/PreviewSystem.cs.meta
-
12MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Presenters/NodePreviewPresenter.cs.meta
-
256MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Presenters/NodePreviewPresenter.cs
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.IO; |
|||
using System.Linq; |
|||
using System.Runtime.InteropServices; |
|||
using System.Threading; |
|||
using UnityEngine; |
|||
using UnityEngine.Graphing; |
|||
using UnityEngine.MaterialGraph; |
|||
using Object = UnityEngine.Object; |
|||
|
|||
namespace UnityEditor.MaterialGraph.Drawing |
|||
{ |
|||
public class PreviewSystem : IDisposable |
|||
{ |
|||
IGraph m_Graph; |
|||
Dictionary<Guid, PreviewData> m_Previews = new Dictionary<Guid, PreviewData>(); |
|||
HashSet<Guid> m_DirtyPreviews = new HashSet<Guid>(); |
|||
HashSet<Guid> m_DirtyShaders = new HashSet<Guid>(); |
|||
HashSet<Guid> m_TimeDependentPreviews = new HashSet<Guid>(); |
|||
Material m_PreviewMaterial; |
|||
MaterialPropertyBlock m_PreviewPropertyBlock; |
|||
MaterialGraphPreviewGenerator m_PreviewGenerator = new MaterialGraphPreviewGenerator(); |
|||
Texture2D m_ErrorTexture; |
|||
|
|||
public PreviewSystem(IGraph graph) |
|||
{ |
|||
m_Graph = graph; |
|||
m_PreviewMaterial = new Material(Shader.Find("Unlit/Color")) { hideFlags = HideFlags.HideInHierarchy }; |
|||
m_PreviewMaterial.hideFlags = HideFlags.HideInHierarchy; |
|||
m_PreviewPropertyBlock = new MaterialPropertyBlock(); |
|||
m_ErrorTexture = new Texture2D(2, 2); |
|||
m_ErrorTexture.SetPixel(0, 0, Color.magenta); |
|||
m_ErrorTexture.SetPixel(0, 1, Color.black); |
|||
m_ErrorTexture.SetPixel(1, 0, Color.black); |
|||
m_ErrorTexture.SetPixel(1, 1, Color.magenta); |
|||
m_ErrorTexture.Apply(); |
|||
} |
|||
|
|||
public PreviewHandle GetPreviewHandle(Guid nodeGuid) |
|||
{ |
|||
PreviewData previewData; |
|||
if (!m_Previews.TryGetValue(nodeGuid, out previewData)) |
|||
{ |
|||
var node = m_Graph.GetNodeFromGuid(nodeGuid); |
|||
if (node == null) |
|||
throw new ArgumentException("Node does not exist.", "nodeGuid"); |
|||
previewData = new PreviewData(); |
|||
previewData.renderTexture = new RenderTexture(256, 256, 16, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Default) { hideFlags = HideFlags.HideAndDontSave }; |
|||
m_Previews.Add(nodeGuid, previewData); |
|||
m_DirtyShaders.Add(nodeGuid); |
|||
m_DirtyPreviews.Add(nodeGuid); |
|||
node.onModified += OnNodeModified; |
|||
} |
|||
previewData.refCount++; |
|||
return new PreviewHandle(nodeGuid, previewData, this); |
|||
} |
|||
|
|||
void OnNodeModified(INode node, ModificationScope scope) |
|||
{ |
|||
if (scope >= ModificationScope.Graph) |
|||
m_DirtyShaders.Add(node.guid); |
|||
else if (scope == ModificationScope.Node) |
|||
m_DirtyPreviews.Add(node.guid); |
|||
} |
|||
|
|||
Stack<Guid> m_Wavefront = new Stack<Guid>(); |
|||
|
|||
void PropagateNodeSet(HashSet<Guid> nodeGuidSet, bool forward = true) |
|||
{ |
|||
m_Wavefront.Clear(); |
|||
foreach (var guid in nodeGuidSet) |
|||
m_Wavefront.Push(guid); |
|||
while (m_Wavefront.Count > 0) |
|||
{ |
|||
var nodeGuid = m_Wavefront.Pop(); |
|||
var node = m_Graph.GetNodeFromGuid(nodeGuid); |
|||
if (node == null) |
|||
continue; |
|||
|
|||
// Loop through all nodes that the node feeds into.
|
|||
foreach (var slot in forward ? node.GetOutputSlots<ISlot>() : node.GetInputSlots<ISlot>()) |
|||
{ |
|||
foreach (var edge in m_Graph.GetEdges(slot.slotReference)) |
|||
{ |
|||
// We look at each node we feed into.
|
|||
var connectedSlot = forward ? edge.inputSlot : edge.outputSlot; |
|||
var connectedNodeGuid = connectedSlot.nodeGuid; |
|||
|
|||
// If the input node is already in the set of time-dependent nodes, we don't need to process it.
|
|||
if (nodeGuidSet.Contains(connectedNodeGuid)) |
|||
continue; |
|||
|
|||
// Add the node to the set of time-dependent nodes, and to the wavefront such that we can process the nodes that it feeds into.
|
|||
nodeGuidSet.Add(connectedNodeGuid); |
|||
m_Wavefront.Push(connectedNodeGuid); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
public void UpdateTimeDependentPreviews() |
|||
{ |
|||
m_TimeDependentPreviews.Clear(); |
|||
foreach (var node in m_Graph.GetNodes<INode>()) |
|||
{ |
|||
var timeNode = node as IMayRequireTime; |
|||
if (timeNode != null && timeNode.RequiresTime()) |
|||
m_TimeDependentPreviews.Add(node.guid); |
|||
} |
|||
PropagateNodeSet(m_TimeDependentPreviews); |
|||
} |
|||
|
|||
HashSet<Guid> m_PropertyNodeGuids = new HashSet<Guid>(); |
|||
List<PreviewProperty> m_PreviewProperties = new List<PreviewProperty>(); |
|||
|
|||
public void Update() |
|||
{ |
|||
PropagateNodeSet(m_DirtyShaders); |
|||
foreach (var nodeGuid in m_DirtyShaders) |
|||
{ |
|||
UpdateShader(nodeGuid); |
|||
} |
|||
m_DirtyPreviews.UnionWith(m_DirtyShaders); |
|||
m_DirtyShaders.Clear(); |
|||
|
|||
PropagateNodeSet(m_DirtyPreviews); |
|||
m_DirtyPreviews.UnionWith(m_TimeDependentPreviews); |
|||
|
|||
// Find nodes we need properties from
|
|||
m_PropertyNodeGuids.Clear(); |
|||
foreach (var nodeGuid in m_DirtyPreviews) |
|||
m_PropertyNodeGuids.Add(nodeGuid); |
|||
PropagateNodeSet(m_PropertyNodeGuids, false); |
|||
|
|||
// Fill MaterialPropertyBlock
|
|||
m_PreviewPropertyBlock.Clear(); |
|||
foreach (var nodeGuid in m_DirtyPreviews) |
|||
{ |
|||
var node = m_Graph.GetNodeFromGuid<AbstractMaterialNode>(nodeGuid); |
|||
node.CollectPreviewMaterialProperties(m_PreviewProperties); |
|||
foreach (var previewProperty in m_PreviewProperties) |
|||
{ |
|||
if (previewProperty.m_PropType == PropertyType.Texture && previewProperty.m_Texture != null) |
|||
m_PreviewPropertyBlock.SetTexture(previewProperty.m_Name, previewProperty.m_Texture); |
|||
else if (previewProperty.m_PropType == PropertyType.Cubemap && previewProperty.m_Cubemap != null) |
|||
m_PreviewPropertyBlock.SetTexture(previewProperty.m_Name, previewProperty.m_Cubemap); |
|||
else if (previewProperty.m_PropType == PropertyType.Color) |
|||
m_PreviewPropertyBlock.SetColor(previewProperty.m_Name, previewProperty.m_Color); |
|||
else if (previewProperty.m_PropType == PropertyType.Vector2) |
|||
m_PreviewPropertyBlock.SetVector(previewProperty.m_Name, previewProperty.m_Vector4); |
|||
else if (previewProperty.m_PropType == PropertyType.Vector3) |
|||
m_PreviewPropertyBlock.SetVector(previewProperty.m_Name, previewProperty.m_Vector4); |
|||
else if (previewProperty.m_PropType == PropertyType.Vector4) |
|||
m_PreviewPropertyBlock.SetVector(previewProperty.m_Name, previewProperty.m_Vector4); |
|||
else if (previewProperty.m_PropType == PropertyType.Float) |
|||
m_PreviewPropertyBlock.SetFloat(previewProperty.m_Name, previewProperty.m_Float); |
|||
} |
|||
m_PreviewProperties.Clear(); |
|||
} |
|||
|
|||
var time = Time.realtimeSinceStartup; |
|||
foreach (var nodeGuid in m_DirtyPreviews) |
|||
{ |
|||
var previewData = m_Previews[nodeGuid]; |
|||
if (previewData.shader == null) |
|||
{ |
|||
previewData.texture = null; |
|||
continue; |
|||
} |
|||
if (MaterialGraphAsset.ShaderHasError(previewData.shader)) |
|||
{ |
|||
previewData.texture = m_ErrorTexture; |
|||
continue; |
|||
} |
|||
var node = m_Graph.GetNodeFromGuid(nodeGuid); |
|||
m_PreviewMaterial.shader = previewData.shader; |
|||
m_PreviewGenerator.DoRenderPreview(previewData.renderTexture, m_PreviewMaterial, previewData.previewMode, node is IMasterNode, time, m_PreviewPropertyBlock); |
|||
previewData.texture = previewData.renderTexture; |
|||
} |
|||
|
|||
foreach (var nodeGuid in m_DirtyPreviews) |
|||
{ |
|||
var previewData = m_Previews[nodeGuid]; |
|||
if (previewData.onPreviewChanged != null) |
|||
previewData.onPreviewChanged(); |
|||
} |
|||
|
|||
m_DirtyPreviews.Clear(); |
|||
} |
|||
|
|||
void UpdateShader(Guid nodeGuid) |
|||
{ |
|||
var node = m_Graph.GetNodeFromGuid<AbstractMaterialNode>(nodeGuid); |
|||
PreviewData previewData; |
|||
if (!m_Previews.TryGetValue(nodeGuid, out previewData)) |
|||
return; |
|||
|
|||
if (node is IMasterNode) |
|||
{ |
|||
var masterNode = (IMasterNode)node; |
|||
List<PropertyGenerator.TextureInfo> defaultTextures; |
|||
previewData.shaderString = masterNode.GetFullShader(GenerationMode.Preview, node.guid + "_preview", out defaultTextures); |
|||
previewData.previewMode = masterNode.has3DPreview() ? PreviewMode.Preview3D : PreviewMode.Preview2D; |
|||
} |
|||
else if (!node.hasPreview || NodeUtils.FindEffectiveShaderStage(node, true) == ShaderStage.Vertex) |
|||
{ |
|||
previewData.shaderString = null; |
|||
} |
|||
else |
|||
{ |
|||
PreviewMode previewMode; |
|||
previewData.shaderString = ShaderGenerator.GeneratePreviewShader(node, out previewMode); |
|||
previewData.previewMode = previewMode; |
|||
} |
|||
|
|||
// Debug output
|
|||
Debug.Log("RecreateShader: " + node.GetVariableNameForNode() + Environment.NewLine + previewData.shaderString); |
|||
File.WriteAllText(Application.dataPath + "/../GeneratedShader.shader", (previewData.shaderString ?? "null").Replace("UnityEngine.MaterialGraph", "Generated")); |
|||
|
|||
if (string.IsNullOrEmpty(previewData.shaderString)) |
|||
{ |
|||
if (previewData.shader != null) |
|||
Object.DestroyImmediate(previewData.shader, true); |
|||
previewData.shader = null; |
|||
return; |
|||
} |
|||
|
|||
if (previewData.shader != null && MaterialGraphAsset.ShaderHasError(previewData.shader)) |
|||
{ |
|||
Object.DestroyImmediate(previewData.shader, true); |
|||
previewData.shader = null; |
|||
} |
|||
|
|||
if (previewData.shader == null) |
|||
{ |
|||
previewData.shader = ShaderUtil.CreateShaderAsset(previewData.shaderString); |
|||
previewData.shader.hideFlags = HideFlags.HideAndDontSave; |
|||
} |
|||
else |
|||
{ |
|||
ShaderUtil.UpdateShaderAsset(previewData.shader, previewData.shaderString); |
|||
} |
|||
} |
|||
|
|||
public void DestroyPreviewHandle(Guid nodeGuid) |
|||
{ |
|||
PreviewData previewData; |
|||
if (!m_Previews.TryGetValue(nodeGuid, out previewData)) |
|||
return; |
|||
previewData.refCount--; |
|||
if (previewData.refCount == 0) |
|||
DestroyPreview(nodeGuid, previewData); |
|||
} |
|||
|
|||
void DestroyPreview(Guid nodeGuid, PreviewData previewData) |
|||
{ |
|||
if (m_Previews.Remove(nodeGuid)) |
|||
{ |
|||
if (previewData.shader != null) |
|||
Object.DestroyImmediate(previewData.shader, true); |
|||
if (previewData.renderTexture != null) |
|||
Object.DestroyImmediate(previewData.renderTexture, true); |
|||
var node = m_Graph.GetNodeFromGuid(nodeGuid); |
|||
if (node != null) |
|||
node.onModified -= OnNodeModified; |
|||
m_DirtyPreviews.Remove(nodeGuid); |
|||
m_DirtyShaders.Remove(nodeGuid); |
|||
m_TimeDependentPreviews.Remove(nodeGuid); |
|||
previewData.shader = null; |
|||
previewData.renderTexture = null; |
|||
previewData.texture = null; |
|||
previewData.onPreviewChanged = null; |
|||
} |
|||
} |
|||
|
|||
void ReleaseUnmanagedResources() |
|||
{ |
|||
if (m_PreviewMaterial != null) |
|||
Object.DestroyImmediate(m_PreviewMaterial, true); |
|||
m_PreviewMaterial = null; |
|||
if (m_PreviewGenerator != null) |
|||
m_PreviewGenerator.Dispose(); |
|||
m_PreviewGenerator = null; |
|||
var previews = m_Previews.ToList(); |
|||
foreach (var kvp in previews) |
|||
DestroyPreview(kvp.Key, kvp.Value); |
|||
} |
|||
|
|||
public void Dispose() |
|||
{ |
|||
ReleaseUnmanagedResources(); |
|||
GC.SuppressFinalize(this); |
|||
} |
|||
|
|||
~PreviewSystem() |
|||
{ |
|||
ReleaseUnmanagedResources(); |
|||
} |
|||
} |
|||
|
|||
public delegate void OnPreviewChanged(); |
|||
|
|||
public class PreviewData |
|||
{ |
|||
public Shader shader { get; set; } |
|||
public string shaderString { get; set; } |
|||
public PreviewMode previewMode { get; set; } |
|||
public RenderTexture renderTexture { get; set; } |
|||
public Texture texture { get; set; } |
|||
public int refCount { get; set; } |
|||
public OnPreviewChanged onPreviewChanged; |
|||
} |
|||
|
|||
public class PreviewHandle : IDisposable |
|||
{ |
|||
Guid m_NodeGuid; |
|||
PreviewData m_PreviewData; |
|||
PreviewSystem m_PreviewSystem; |
|||
|
|||
public PreviewHandle(Guid nodeGuid, PreviewData previewData, PreviewSystem previewSystem) |
|||
{ |
|||
m_NodeGuid = nodeGuid; |
|||
m_PreviewData = previewData; |
|||
m_PreviewSystem = previewSystem; |
|||
} |
|||
|
|||
public OnPreviewChanged onPreviewChanged |
|||
{ |
|||
get { return m_PreviewData.onPreviewChanged; } |
|||
set { m_PreviewData.onPreviewChanged = value; } |
|||
} |
|||
|
|||
public Texture texture |
|||
{ |
|||
get { return m_PreviewData.texture; } |
|||
} |
|||
|
|||
void ReleaseUnmanagedResources() |
|||
{ |
|||
m_PreviewSystem.DestroyPreviewHandle(m_NodeGuid); |
|||
} |
|||
|
|||
public void Dispose() |
|||
{ |
|||
ReleaseUnmanagedResources(); |
|||
GC.SuppressFinalize(this); |
|||
} |
|||
|
|||
~PreviewHandle() |
|||
{ |
|||
ReleaseUnmanagedResources(); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: aa2238545a2849ecb0a6285b5a632a69 |
|||
timeCreated: 1505525146 |
|
|||
fileFormatVersion: 2 |
|||
guid: 1b2eecd8c1fc12f41810a98414854158 |
|||
timeCreated: 1476707366 |
|||
licenseType: Pro |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Reflection; |
|||
using UnityEditor.Experimental.UIElements.GraphView; |
|||
using UnityEngine; |
|||
using UnityEngine.Graphing; |
|||
using UnityEngine.MaterialGraph; |
|||
using Object = UnityEngine.Object; |
|||
using UnityEditor.Experimental.UIElements.GraphView; |
|||
|
|||
namespace UnityEditor.MaterialGraph.Drawing |
|||
{ |
|||
[Serializable] |
|||
public class NodePreviewPresenter : ScriptableObject |
|||
{ |
|||
protected NodePreviewPresenter() |
|||
{} |
|||
|
|||
MaterialGraphPreviewGenerator m_PreviewGenerator; |
|||
|
|||
[NonSerialized] |
|||
int m_LastShaderVersion = -1; |
|||
|
|||
[NonSerialized] |
|||
Material m_PreviewMaterial; |
|||
|
|||
[NonSerialized] |
|||
Shader m_PreviewShader; |
|||
|
|||
AbstractMaterialNode m_Node; |
|||
|
|||
[SerializeField] |
|||
ModificationScope m_ModificationScope; |
|||
|
|||
// Null means no modification is currently in progress.
|
|||
public ModificationScope modificationScope |
|||
{ |
|||
get |
|||
{ |
|||
return m_ModificationScope; |
|||
} |
|||
set |
|||
{ |
|||
// External changes can only set the modification scope higher, to prevent missing out on a previously set shader regeneration.
|
|||
if (m_ModificationScope >= value) |
|||
return; |
|||
m_ModificationScope = value; |
|||
} |
|||
} |
|||
|
|||
[NonSerialized] |
|||
Texture m_Texture; |
|||
|
|||
public Texture texture |
|||
{ |
|||
get { return m_Texture; } |
|||
} |
|||
|
|||
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; |
|||
} |
|||
} |
|||
|
|||
MaterialGraphPreviewGenerator previewGenerator |
|||
{ |
|||
get |
|||
{ |
|||
if (m_PreviewGenerator == null) |
|||
{ |
|||
m_PreviewGenerator = new MaterialGraphPreviewGenerator(m_Node is AbstractMasterNode); |
|||
} |
|||
return m_PreviewGenerator; |
|||
} |
|||
} |
|||
|
|||
public void Initialize(AbstractMaterialNode node) |
|||
{ |
|||
m_Node = node; |
|||
m_ModificationScope = ModificationScope.Graph; |
|||
} |
|||
|
|||
public void UpdateTexture() |
|||
{ |
|||
if (m_Node == null) |
|||
{ |
|||
m_Texture = null; |
|||
return; |
|||
} |
|||
|
|||
if (m_Node.hasPreview == false) |
|||
{ |
|||
m_Texture = null; |
|||
return; |
|||
} |
|||
|
|||
var scope = m_ModificationScope; |
|||
m_ModificationScope = ModificationScope.Nothing; |
|||
|
|||
if (scope != ModificationScope.Nothing) |
|||
{ |
|||
if (scope >= ModificationScope.Graph) |
|||
{ |
|||
var stage = NodeUtils.FindEffectiveShaderStage(m_Node, true); |
|||
if (!(m_Node is AbstractSurfaceMasterNode) && stage == ShaderStage.Vertex) |
|||
{ |
|||
// Debug.Log(m_Node.name + ":" + stage);
|
|||
m_Texture = null; |
|||
return; |
|||
} |
|||
// TODO: Handle shader regeneration error
|
|||
var status = UpdatePreviewShader(); |
|||
} |
|||
m_Texture = RenderPreview(new Vector2(256, 256)); |
|||
} |
|||
else if (texture == null) |
|||
{ |
|||
m_Texture = RenderPreview(new Vector2(256, 256)); |
|||
} |
|||
} |
|||
|
|||
void OnDisable() |
|||
{ |
|||
if (m_PreviewGenerator != null) |
|||
m_PreviewGenerator.Dispose(); |
|||
} |
|||
|
|||
protected virtual string GetPreviewShaderString() |
|||
{ |
|||
// TODO: this is a workaround right now.
|
|||
if (m_Node is IMasterNode) |
|||
{ |
|||
var localNode = (IMasterNode)m_Node; |
|||
if (localNode == null) |
|||
return string.Empty; |
|||
|
|||
List<PropertyGenerator.TextureInfo> defaultTextures; |
|||
var resultShader = ((IMasterNode)m_Node).GetFullShader(GenerationMode.Preview, m_Node.guid + "_preview", out defaultTextures); |
|||
|
|||
if (((IMasterNode)m_Node).has3DPreview()) |
|||
{ |
|||
m_GeneratedShaderMode = PreviewMode.Preview3D; |
|||
} |
|||
|
|||
return resultShader; |
|||
} |
|||
return ShaderGenerator.GeneratePreviewShader(m_Node, out m_GeneratedShaderMode); |
|||
} |
|||
|
|||
bool UpdatePreviewShader() |
|||
{ |
|||
if (m_Node == null || m_Node.hasError) |
|||
return false; |
|||
|
|||
var resultShader = GetPreviewShaderString(); |
|||
Debug.Log("RecreateShaderAndMaterial : " + m_Node.GetVariableNameForNode() + Environment.NewLine + resultShader); |
|||
string shaderOuputString = resultShader.Replace("UnityEngine.MaterialGraph", "Generated"); |
|||
System.IO.File.WriteAllText(Application.dataPath + "/../GeneratedShader.shader", shaderOuputString); |
|||
|
|||
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 && MaterialGraphAsset.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 !MaterialGraphAsset.ShaderHasError(m_PreviewShader); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// RenderPreview gets called in OnPreviewGUI. Nodes can override
|
|||
/// RenderPreview and do their own rendering to the render texture
|
|||
/// </summary>
|
|||
Texture RenderPreview(Vector2 targetSize) |
|||
{ |
|||
previewMaterial.shader = m_PreviewShader; |
|||
UpdateMaterialProperties(m_Node, previewMaterial); |
|||
return previewGenerator.DoRenderPreview(previewMaterial, m_GeneratedShaderMode, new Rect(0, 0, targetSize.x, targetSize.y)); |
|||
} |
|||
|
|||
static void SetPreviewMaterialProperty(PreviewProperty previewProperty, Material mat) |
|||
{ |
|||
switch (previewProperty.m_PropType) |
|||
{ |
|||
case PropertyType.Texture: |
|||
mat.SetTexture(previewProperty.m_Name, previewProperty.m_Texture); |
|||
break; |
|||
case PropertyType.Cubemap: |
|||
mat.SetTexture(previewProperty.m_Name, previewProperty.m_Cubemap); |
|||
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); |
|||
} |
|||
} |
|||
} |
撰写
预览
正在加载...
取消
保存
Reference in new issue