public static string GetTemplatePath(string templateName) { var path = new List <string> { DefaultShaderIncludes.GetAssetsPackagePath() ?? Path.GetFullPath("Packages/com.unity.shadergraph"), "Editor", "Templates" }; string result = path[0]; for (int i = 1; i < path.Count; i++) { result = Path.Combine(result, path[i]); } result = Path.Combine(result, templateName); if (File.Exists(result)) { return(result); } return(string.Empty); }
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_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(); } }
public void ShaderGeneratorOutput(TestInfo testInfo) { var file = testInfo.info; var filePath = Path.Combine(s_Path, file.Name); var textGraph = File.ReadAllText(filePath, Encoding.UTF8); var graph = JsonUtility.FromJson <ShaderGraph.MaterialGraph>(textGraph); Assert.IsNotNull(graph.masterNode, "No master node in graph."); // //Assert.IsNotNull(graphAsset, "Graph asset not found"); //var materialGraph = graphAsset.graph as UnityEngine.MaterialGraph.MaterialGraph; //Assert.IsNotNull(materialGraph); // Generate the shader List <PropertyCollector.TextureInfo> configuredTextures = new List <PropertyCollector.TextureInfo>(); var shaderString = String.Empty; //graph.masterNode.GetFullShader(GenerationMode.ForReals, Path.GetFileNameWithoutExtension(filePath), out configuredTextures); var rootPath = Path.Combine(Path.Combine(DefaultShaderIncludes.GetRepositoryPath(), "Testing"), "IntegrationTests"); var shaderTemplatePath = Path.Combine(rootPath, "ShaderTemplates"); Directory.CreateDirectory(shaderTemplatePath); var textTemplateFilePath = Path.Combine(shaderTemplatePath, string.Format("{0}.{1}", file.Name, "shader")); if (!File.Exists(textTemplateFilePath)) { File.WriteAllText(textTemplateFilePath, shaderString); Assert.Fail("Text template file not found for {0}, creating it.", file); } else { var textTemplate = File.ReadAllText(textTemplateFilePath); var textsAreEqual = string.Compare(shaderString, textTemplate, CultureInfo.CurrentCulture, CompareOptions.IgnoreSymbols); if (0 != textsAreEqual) { var failedPath = Path.Combine(rootPath, "Failed"); Directory.CreateDirectory(failedPath); var misMatchLocationResult = Path.Combine(failedPath, string.Format("{0}.{1}", file.Name, "shader")); var misMatchLocationTemplate = Path.Combine(failedPath, string.Format("{0}.template.{1}", file.Name, "shader")); File.WriteAllText(misMatchLocationResult, shaderString); File.WriteAllText(misMatchLocationTemplate, textTemplate); Assert.Fail("Shader text from graph {0}, did not match .template file.", file); } } m_Shader = ShaderUtil.CreateShaderAsset(shaderString); m_Shader.hideFlags = HideFlags.HideAndDontSave; Assert.IsNotNull(m_Shader, "Shader Generation Failed"); //Assert.IsFalse(AbstractMaterialNodeUI.ShaderHasError(m_Shader), "Shader has error"); m_PreviewMaterial = new Material(m_Shader) { hideFlags = HideFlags.HideAndDontSave }; foreach (var textureInfo in configuredTextures) { var texture = EditorUtility.InstanceIDToObject(textureInfo.textureId) as Texture; if (texture == null) { continue; } m_PreviewMaterial.SetTexture(textureInfo.name, texture); } Assert.IsNotNull(m_PreviewMaterial, "preview material could not be created"); const int res = 256; using (var generator = new MaterialGraphPreviewGenerator()) { var renderTexture = new RenderTexture(res, res, 16, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Default) { hideFlags = HideFlags.HideAndDontSave }; generator.DoRenderPreview(renderTexture, m_PreviewMaterial, null, PreviewMode.Preview3D, true, 10); Assert.IsNotNull(renderTexture, "Render failed"); RenderTexture.active = renderTexture; m_Captured = new Texture2D(renderTexture.width, renderTexture.height, TextureFormat.ARGB32, false); m_Captured.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0); RenderTexture.active = null; //can help avoid errors Object.DestroyImmediate(renderTexture, true); // find the reference image var dumpFileLocation = Path.Combine(shaderTemplatePath, string.Format("{0}.{1}", file.Name, "png")); if (!File.Exists(dumpFileLocation)) { // no reference exists, create it var generated = m_Captured.EncodeToPNG(); File.WriteAllBytes(dumpFileLocation, generated); Assert.Fail("Image template file not found for {0}, creating it.", file); } var template = File.ReadAllBytes(dumpFileLocation); m_FromDisk = new Texture2D(2, 2); m_FromDisk.LoadImage(template, false); var rmse = CompareTextures(m_FromDisk, m_Captured); if (rmse > testInfo.threshold) { var failedPath = Path.Combine(rootPath.ToString(), "Failed"); Directory.CreateDirectory(failedPath); var misMatchLocationResult = Path.Combine(failedPath, string.Format("{0}.{1}", file.Name, "png")); var misMatchLocationTemplate = Path.Combine(failedPath, string.Format("{0}.template.{1}", file.Name, "png")); var generated = m_Captured.EncodeToPNG(); File.WriteAllBytes(misMatchLocationResult, generated); File.WriteAllBytes(misMatchLocationTemplate, template); Assert.Fail("Shader image from graph {0}, did not match .template file.", file); } } }
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(); } }