void PropagateNodeSet(IndexSet nodeSet, bool forward = true, IEnumerable <Identifier> initialWavefront = null) { m_Wavefront.Clear(); if (initialWavefront != null) { foreach (var id in initialWavefront) { m_Wavefront.Push(id); } } else { foreach (var index in nodeSet) { m_Wavefront.Push(m_Identifiers[index]); } } while (m_Wavefront.Count > 0) { var index = m_Wavefront.Pop(); var node = m_Graph.GetNodeFromTempId(index); if (node == null) { continue; } // Loop through all nodes that the node feeds into. m_Slots.Clear(); if (forward) { node.GetOutputSlots(m_Slots); } else { node.GetInputSlots(m_Slots); } foreach (var slot in m_Slots) { m_Edges.Clear(); m_Graph.GetEdges(slot.slotReference, m_Edges); foreach (var edge in m_Edges) { // We look at each node we feed into. var connectedSlot = forward ? edge.inputSlot : edge.outputSlot; var connectedNodeGuid = connectedSlot.nodeGuid; var connectedNode = m_Graph.GetNodeFromGuid(connectedNodeGuid); // If the input node is already in the set of time-dependent nodes, we don't need to process it. if (nodeSet.Contains(connectedNode.tempId.index)) { 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. nodeSet.Add(connectedNode.tempId.index); m_Wavefront.Push(connectedNode.tempId); } } } }
void UpdateBadges() { if (!m_MessageManager.nodeMessagesChanged) { return; } foreach (var messageData in m_MessageManager.GetNodeMessages()) { var node = m_Graph.GetNodeFromTempId(messageData.Key); if (!(m_GraphView.GetNodeByGuid(node.guid.ToString()) is MaterialNodeView nodeView)) { continue; } if (messageData.Value.Count == 0) { var badge = nodeView.Q <IconBadge>(); badge?.Detach(); badge?.RemoveFromHierarchy(); } else { nodeView.AttachError(messageData.Value.First().message); } } }
void UpdateMasterNodeShader(Identifier nodeId) { var masterNode = m_Graph.GetNodeFromTempId(nodeId) as IMasterNode; var renderData = Get(m_RenderDatas, nodeId); var shaderData = renderData?.shaderData; if (masterNode == null || shaderData == null) { return; } List <PropertyCollector.TextureInfo> configuredTextures; shaderData.shaderString = masterNode.GetShader(GenerationMode.Preview, masterNode.name, out configuredTextures); var debugOutputPath = DefaultShaderIncludes.GetDebugOutputPath(); if (!string.IsNullOrEmpty(debugOutputPath)) { File.WriteAllText(debugOutputPath + "/GeneratedShader.shader", (shaderData.shaderString ?? "null").Replace("UnityEngine.MaterialGraph", "Generated")); } if (string.IsNullOrEmpty(shaderData.shaderString)) { if (shaderData.shader != null) { ShaderUtil.ClearShaderMessages(shaderData.shader); Object.DestroyImmediate(shaderData.shader, true); shaderData.shader = null; } return; } if (shaderData.shader == null) { shaderData.shader = ShaderUtil.CreateShaderAsset(shaderData.shaderString); shaderData.shader.hideFlags = HideFlags.HideAndDontSave; } else { ShaderUtil.ClearCachedData(shaderData.shader); ShaderUtil.UpdateShaderAsset(shaderData.shader, shaderData.shaderString); } // Debug output shaderData.hasError = ShaderUtil.ShaderHasError(shaderData.shader); if (shaderData.hasError) { var messages = ShaderUtil.GetShaderMessages(shaderData.shader); foreach (var message in messages) { Debug.LogFormat("Compilation error in {3} at line {1} (on {2}):\n{0}", message.message, message.line, message.platform, "graph"); } if (!string.IsNullOrEmpty(debugOutputPath)) { var AMNode = masterNode as AbstractMaterialNode; var message = "RecreateShader: " + AMNode?.GetVariableNameForNode() + Environment.NewLine + shaderData.shaderString; Debug.LogWarning(message); } ShaderUtil.ClearShaderMessages(shaderData.shader); Object.DestroyImmediate(shaderData.shader, true); shaderData.shader = null; } }