Example #1
0
        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);
        }
Example #2
0
        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;
            }
        }
Example #3
0
        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();
            }
        }
Example #4
0
        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);
                }
            }
        }
Example #5
0
        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();
            }
        }