void UpdateShaders() { if (m_DirtyShaders.Any()) { PropagateNodeSet(m_DirtyShaders); var masterNodes = new List <INode>(); var colorNodes = new List <INode>(); var wireframeNodes = new List <INode>(); foreach (var index in m_DirtyShaders) { var node = m_Graph.GetNodeFromTempId(m_Identifiers[index]) as AbstractMaterialNode; if (node == null) { continue; } var masterNode = node as IMasterNode; if (masterNode != null) { masterNodes.Add(node); } else if (node.previewMode == PreviewMode.Wireframe) { wireframeNodes.Add(node); } else { colorNodes.Add(node); } } var count = Math.Min(colorNodes.Count, 1) + masterNodes.Count; try { var i = 0; EditorUtility.DisplayProgressBar("Shader Graph", string.Format("Compiling preview shaders ({0}/{1})", i, count), 0f); foreach (var node in masterNodes) { UpdateShader(node.tempId); i++; EditorUtility.DisplayProgressBar("Shader Graph", string.Format("Compiling preview shaders ({0}/{1})", i, count), 0f); } if (colorNodes.Count > 0) { var results = m_Graph.GetUberColorShader(); m_OutputIdName = results.outputIdProperty.referenceName; ShaderUtil.UpdateShaderAsset(m_ColorShader, results.shader); var debugOutputPath = DefaultShaderIncludes.GetDebugOutputPath(); if (debugOutputPath != null) { File.WriteAllText(debugOutputPath + "/ColorShader.shader", (results.shader ?? "null").Replace("UnityEngine.MaterialGraph", "Generated")); } bool uberShaderHasError = false; if (MaterialGraphAsset.ShaderHasError(m_ColorShader)) { var errors = MaterialGraphAsset.GetShaderErrors(m_ColorShader); var message = new ShaderStringBuilder(); message.AppendLine(@"Preview shader for graph has {0} error{1}:", errors.Length, errors.Length != 1 ? "s" : ""); foreach (var error in errors) { INode node; try { node = results.sourceMap.FindNode(error.line); message.AppendLine("Shader compilation error in {3} at line {1} (on {2}):\n{0}", error.message, error.line, error.platform, node != null ? string.Format("node {0} ({1})", node.name, node.guid) : "graph"); message.AppendLine(error.messageDetails); message.AppendNewLine(); } catch { message.AppendLine("Shader compilation error in {3} at line {1} (on {2}):\n{0}", error.message, error.line, error.platform, "graph"); } } Debug.LogWarning(message.ToString()); ShaderUtil.ClearShaderErrors(m_ColorShader); ShaderUtil.UpdateShaderAsset(m_ColorShader, k_EmptyShader); uberShaderHasError = true; } foreach (var node in colorNodes) { var renderData = GetRenderData(node.tempId); if (renderData == null) { continue; } var shaderData = renderData.shaderData; shaderData.shader = m_ColorShader; shaderData.hasError = uberShaderHasError; } i++; EditorUtility.DisplayProgressBar("Shader Graph", string.Format("Compiling preview shaders ({0}/{1})", i, count), 0f); } } finally { EditorUtility.ClearProgressBar(); } // Union dirty shaders into dirty previews m_DirtyPreviews.UnionWith(m_DirtyShaders); m_DirtyShaders.Clear(); } }
void UpdateShader(Identifier nodeId) { var node = m_Graph.GetNodeFromTempId(nodeId) as AbstractMaterialNode; if (node == null) { return; } var renderData = Get(m_RenderDatas, nodeId); if (renderData == null || renderData.shaderData == null) { return; } var shaderData = renderData.shaderData; if (!(node is IMasterNode) && !node.hasPreview) { shaderData.shaderString = null; } else { var masterNode = node as IMasterNode; if (masterNode != null) { List <PropertyCollector.TextureInfo> configuredTextures; shaderData.shaderString = masterNode.GetShader(GenerationMode.Preview, node.name, out configuredTextures); } else { shaderData.shaderString = m_Graph.GetPreviewShader(node).shader; } } var debugOutputPath = DefaultShaderIncludes.GetDebugOutputPath(); if (debugOutputPath != null) { File.WriteAllText(debugOutputPath + "/GeneratedShader.shader", (shaderData.shaderString ?? "null").Replace("UnityEngine.MaterialGraph", "Generated")); } if (string.IsNullOrEmpty(shaderData.shaderString)) { if (shaderData.shader != null) { ShaderUtil.ClearShaderErrors(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.ClearShaderErrors(shaderData.shader); ShaderUtil.UpdateShaderAsset(shaderData.shader, shaderData.shaderString); } // Debug output if (MaterialGraphAsset.ShaderHasError(shaderData.shader)) { var errors = MaterialGraphAsset.GetShaderErrors(shaderData.shader); foreach (var error in errors) { Debug.LogFormat("Compilation error in {3} at line {1} (on {2}):\n{0}", error.message, error.line, error.platform, "graph"); } shaderData.hasError = true; if (debugOutputPath != null) { var message = "RecreateShader: " + node.GetVariableNameForNode() + Environment.NewLine + shaderData.shaderString; Debug.LogWarning(message); } ShaderUtil.ClearShaderErrors(shaderData.shader); Object.DestroyImmediate(shaderData.shader, true); shaderData.shader = null; } else { shaderData.hasError = false; } }
void UpdateShaders() { if (!m_NeedShaderUpdate) { return; } try { EditorUtility.DisplayProgressBar("Shader Graph", "Compiling preview shaders", 0f); foreach (var masterNode in m_Graph.GetNodes <IMasterNode>()) { UpdateMasterNodeShader(masterNode.tempId); } EditorUtility.DisplayProgressBar("Shader Graph", "Compiling preview shaders", 0.5f); // Reset error states for the UI, the shader, and all render data m_Messenger.ClearAllFromProvider(this); m_RenderDatas.ForEach(data => { if (data != null) { data.shaderData.hasError = false; } }); var errNodes = new HashSet <INode>(); GenerationResults results; var uberShaderHasError = GenerateUberShader(errNodes, out results); if (uberShaderHasError) { errNodes = ProcessUberErrors(results); // Also collect any nodes that had validation errors because they cause the uber shader to fail without // putting valid entries in the source map so ProcessUberErrors doesn't find them. errNodes.UnionWith(m_Graph.GetNodes <AbstractMaterialNode>().Where(node => node.hasError)); PropagateNodeList(errNodes, true); // Try generating the shader again, excluding the nodes with errors (and descendants) uberShaderHasError = GenerateUberShader(errNodes, out results); if (uberShaderHasError) { Debug.LogWarning("Shader Graph compilation failed due to multiple errors. Resolve the visible errors to reveal more."); } foreach (var errNode in errNodes) { GetRenderData(errNode.tempId).shaderData.hasError = true; } } var debugOutputPath = DefaultShaderIncludes.GetDebugOutputPath(); if (debugOutputPath != null) { File.WriteAllText(debugOutputPath + "/ColorShader.shader", (results.shader ?? "null").Replace("UnityEngine.MaterialGraph", "Generated")); } m_NeedShaderUpdate = false; } finally { EditorUtility.ClearProgressBar(); } }