public override void OnImportAsset(AssetImportContext ctx)
    {
        var oldShader = AssetDatabase.LoadAssetAtPath <Shader>(ctx.assetPath);

        if (oldShader != null)
        {
            ShaderUtil.ClearShaderErrors(oldShader);
        }

        List <PropertyCollector.TextureInfo> configuredTextures;
        var text   = GetShaderText(ctx.assetPath, out configuredTextures);
        var shader = ShaderUtil.CreateShaderAsset(text);

        EditorMaterialUtility.SetShaderDefaults(
            shader,
            configuredTextures.Where(x => x.modifiable).Select(x => x.name).ToArray(),
            configuredTextures.Where(x => x.modifiable).Select(x => EditorUtility.InstanceIDToObject(x.textureId) as Texture).ToArray());
        EditorMaterialUtility.SetShaderNonModifiableDefaults(
            shader,
            configuredTextures.Where(x => !x.modifiable).Select(x => x.name).ToArray(),
            configuredTextures.Where(x => !x.modifiable).Select(x => EditorUtility.InstanceIDToObject(x.textureId) as Texture).ToArray());

        ctx.AddObjectToAsset("MainAsset", shader);
        ctx.SetMainObject(shader);
    }
Esempio n. 2
0
        public override void OnImportAsset(AssetImportContext ctx)
        {
            var oldShader = AssetDatabase.LoadAssetAtPath <Shader>(ctx.assetPath);

            if (oldShader != null)
            {
                ShaderUtil.ClearShaderMessages(oldShader);
            }

            List <PropertyCollector.TextureInfo> configuredTextures;
            string path = ctx.assetPath;
            var    sourceAssetDependencyPaths = new List <string>();
            var    text   = GetShaderText(path, out configuredTextures, sourceAssetDependencyPaths);
            var    shader = ShaderUtil.CreateShaderAsset(text);

            EditorMaterialUtility.SetShaderDefaults(
                shader,
                configuredTextures.Where(x => x.modifiable).Select(x => x.name).ToArray(),
                configuredTextures.Where(x => x.modifiable).Select(x => EditorUtility.InstanceIDToObject(x.textureId) as Texture).ToArray());
            EditorMaterialUtility.SetShaderNonModifiableDefaults(
                shader,
                configuredTextures.Where(x => !x.modifiable).Select(x => x.name).ToArray(),
                configuredTextures.Where(x => !x.modifiable).Select(x => EditorUtility.InstanceIDToObject(x.textureId) as Texture).ToArray());

            ctx.AddObjectToAsset("MainAsset", shader);
            ctx.SetMainObject(shader);

            foreach (var sourceAssetDependencyPath in sourceAssetDependencyPaths.Distinct())
            {
                ctx.DependsOnSourceAsset(sourceAssetDependencyPath);
            }
        }
Esempio n. 3
0
        public PreviewManager(AbstractMaterialGraph graph)
        {
            m_Graph           = graph;
            m_PreviewMaterial = new Material(Shader.Find("Unlit/Color"))
            {
                hideFlags = HideFlags.HideInHierarchy
            };
            m_PreviewMaterial.hideFlags = HideFlags.HideAndDontSave;
            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.filterMode = FilterMode.Point;
            m_ErrorTexture.Apply();
            m_SceneResources       = new PreviewSceneResources();
            m_UberShader           = ShaderUtil.CreateShaderAsset(k_EmptyShader);
            m_UberShader.hideFlags = HideFlags.HideAndDontSave;
            m_MasterRenderData     = new PreviewRenderData
            {
                renderTexture = new RenderTexture(400, 400, 16, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Default)
                {
                    hideFlags = HideFlags.HideAndDontSave
                }
            };
            m_MasterRenderData.renderTexture.Create();

            foreach (var node in m_Graph.GetNodes <INode>())
            {
                AddPreview(node);
            }
        }
Esempio n. 4
0
    static Material SetupMaterial(MicroSplatKeywords kwds, Material mat, MicroSplatBaseFeatures.DebugOutput debugOutput, bool useDebugTopo)
    {
        MicroSplatShaderGUI.MicroSplatCompiler comp = new MicroSplatShaderGUI.MicroSplatCompiler();

        List <string> keywords = new List <string>(kwds.keywords);

        RemoveKeyword(keywords, "_SNOW");
        RemoveKeyword(keywords, "_TESSDISTANCE");
        RemoveKeyword(keywords, "_WINDPARTICULATE");
        RemoveKeyword(keywords, "_SNOWPARTICULATE");
        RemoveKeyword(keywords, "_GLITTER");
        RemoveKeyword(keywords, "_SNOWGLITTER");

        keywords.Add(FeatureFromOutput(debugOutput).ToString());
        if (useDebugTopo)
        {
            keywords.Add("_DEBUG_USE_TOPOLOGY");
        }

        string   shader    = comp.Compile(keywords.ToArray(), "RenderBake_" + debugOutput.ToString());
        Shader   s         = ShaderUtil.CreateShaderAsset(shader);
        Material renderMat = new Material(mat);

        renderMat.shader = s;
        return(renderMat);
    }
Esempio n. 5
0
        private Texture RenderIcon(Color color)
        {
            if (iconMat == null || iconMat.shader == null)
            {
                iconMat = new Material(ShaderUtil.CreateShaderAsset(iconShader));
            }

            iconMat.SetColor("_Color", color);

            var prevSRGB = GL.sRGBWrite;

            GL.sRGBWrite = true;
            RenderTexture prev = RenderTexture.active;
            var           rt   = RenderTexture.GetTemporary(this.width, this.height, 0);

            RenderTexture.active = rt;
            GL.Clear(false, true, new Color(1, 1, 1, 0));
            Graphics.Blit(this.Raw, rt, iconMat);

            Texture2D texture = new Texture2D(rt.width, rt.height, TextureFormat.ARGB32, false, true);

            texture.filterMode = FilterMode.Bilinear;
            texture.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0);
            texture.alphaIsTransparency = true;
            texture.Apply();

            RenderTexture.ReleaseTemporary(rt);
            RenderTexture.active = prev;
            GL.sRGBWrite         = prevSRGB;
            return(texture);
        }
Esempio n. 6
0
        /// <summary>
        /// Generates a texture containing the given graph's noise output.
        /// If this is being called very often, create a permanent render target and material and
        ///     use the other version of this method instead for much better performance.
        /// If an error occurred, outputs to the Unity debug console and returns "null".
        /// </summary>
        /// <param name="outputComponents">
        /// The texture output.
        /// For example, pass "rgb" or "xyz" to output the noise into the red, green, and blue channels
        ///     but not the alpha channel.
        /// </param>
        /// <param name="defaultColor">
        /// The color (generally 0-1) of the color components which aren't set by the noise.
        /// </param>
        /// <param name="uvZ">The Z coordinate of the UVs, in case the graph uses it for 3D noise.</param>
        /// <param name="leaveReadable">
        /// Whether the texture's pixel data can still be read from the CPU after this operation.
        /// </param>
        public static Texture2D GenerateToTexture(Graph g, GraphParamCollection c,
                                                  int width, int height, float uvZ,
                                                  string outputComponents, float defaultColor,
                                                  TextureFormat format = TextureFormat.RGBAFloat,
                                                  bool leaveReadable   = false)
        {
            //Generate a shader/material from the graph.
            Shader shader = ShaderUtil.CreateShaderAsset(g.GenerateShader("TempGPUNoiseShader",
                                                                          outputComponents,
                                                                          defaultColor));

            if (shader == null)
            {
                return(null);
            }
            Material mat = new Material(shader);

            c.SetParams(mat);
            mat.SetFloat(GraphUtils.Param_UVz, uvZ);

            //Render the shader's output into a render texture and copy the data to a Texture2D.
            RenderTexture target = RenderTexture.GetTemporary(width, height, 16,
                                                              RenderTextureFormat.ARGBFloat);
            Texture2D resultTex = new Texture2D(width, height, format, false, true);

            //Generate.
            GraphUtils.GenerateToTexture(target, mat, resultTex, leaveReadable);

            //Clean up.
            RenderTexture.ReleaseTemporary(target);

            return(resultTex);
        }
Esempio n. 7
0
    public override void OnImportAsset(AssetImportContext ctx)
    {
        var oldShader = AssetDatabase.LoadAssetAtPath <Shader>(ctx.assetPath);

        if (oldShader != null)
        {
            ShaderUtil.ClearShaderErrors(oldShader);
        }

        List <PropertyCollector.TextureInfo> configuredTextures;
        string path         = ctx.assetPath;
        string shaderString = null;
        var    sourceAssetDependencyPaths = new List <string>();
        var    shaderName = Path.GetFileNameWithoutExtension(path);

        try
        {
            var textGraph = File.ReadAllText(path, Encoding.UTF8);
            var graph     = JsonUtility.FromJson <MaterialGraph>(textGraph);
            graph.LoadedFromDisk();

            if (!string.IsNullOrEmpty(graph.path))
            {
                shaderName = graph.path + "/" + shaderName;
            }
            shaderString = graph.GetShader(shaderName, GenerationMode.ForReals, out configuredTextures, sourceAssetDependencyPaths);

            foreach (var node in graph.GetNodes <AbstractMaterialNode>())
            {
                node.GetSourceAssetDependencies(sourceAssetDependencyPaths);
            }
        }
        catch (Exception)
        {
            configuredTextures = new List <PropertyCollector.TextureInfo>();
            // ignored
        }

        var text   = shaderString ?? k_ErrorShader.Replace("Hidden/GraphErrorShader2", shaderName);
        var shader = ShaderUtil.CreateShaderAsset(text);

        EditorMaterialUtility.SetShaderDefaults(
            shader,
            configuredTextures.Where(x => x.modifiable).Select(x => x.name).ToArray(),
            configuredTextures.Where(x => x.modifiable).Select(x => EditorUtility.InstanceIDToObject(x.textureId) as Texture).ToArray());
        EditorMaterialUtility.SetShaderNonModifiableDefaults(
            shader,
            configuredTextures.Where(x => !x.modifiable).Select(x => x.name).ToArray(),
            configuredTextures.Where(x => !x.modifiable).Select(x => EditorUtility.InstanceIDToObject(x.textureId) as Texture).ToArray());

        ctx.AddObjectToAsset("MainAsset", shader);
        ctx.SetMainObject(shader);

        foreach (var sourceAssetDependencyPath in sourceAssetDependencyPaths.Distinct())
        {
            ctx.DependsOnSourceAsset(sourceAssetDependencyPath);
        }
    }
Esempio n. 8
0
        /// <summary>
        /// Generates a 3D texture containing the given graph's noise output.
        /// </summary>
        /// <param name="outputComponents">
        /// The texture output.
        /// For example, pass "rgb" or "xyz" to output the noise into the red, green, and blue channels
        ///     but not the alpha channel.
        /// </param>
        /// <param name="defaultColor">
        /// The color (generally 0-1) of the color components which aren't set by the noise.
        /// </param>
        /// <param name="useMipmaps">Whether the 3D texture object uses mipmapping.</param>
        /// <param name="leaveTextureReadable">
        /// Whether to let the texture keep a CPU copy of its data on hand for later reading.
        /// </param>
        public static Texture3D GenerateToTexture(Graph g, GraphParamCollection c,
                                                  int width, int height, int depth,
                                                  string outputComponents, float defaultColor,
                                                  bool useMipmaps, bool leaveTextureReadable,
                                                  TextureFormat format = TextureFormat.RGBA32)
        {
            //Generate a shader/material from the graph.
            Shader shader = ShaderUtil.CreateShaderAsset(g.GenerateShader("TempGPUNoiseShader",
                                                                          outputComponents,
                                                                          defaultColor));

            if (shader == null)
            {
                return(null);
            }
            Material mat = new Material(shader);

            c.SetParams(mat);


            //For every Z layer in the texture, generate a 2D texture representing that layer.

            Color32[] finalPixels = new Color32[width * height * depth];

            RenderTexture target = RenderTexture.GetTemporary(width, height, 16,
                                                              RenderTextureFormat.ARGBFloat);
            Texture2D resultTex = new Texture2D(width, height, TextureFormat.RGBAFloat, false, true);


            for (int depthI = 0; depthI < depth; ++depthI)
            {
                //Get the UV.z coordinate.
                float uvZ = (float)depthI / depth;
                mat.SetFloat(GraphUtils.Param_UVz, uvZ);

                GraphUtils.GenerateToTexture(target, mat, resultTex, true);

                //Copy the resulting data into part of the 3D texture.
                Color32[] layerPixels = resultTex.GetPixels32();
                int       pixelOffset = depthI * (width * height);
                for (int pixelI = 0; pixelI < (width * height); ++pixelI)
                {
                    finalPixels[pixelI + pixelOffset] = layerPixels[pixelI];
                }
            }


            //Create the actual texture object.
            Texture3D finalTex = new Texture3D(width, height, depth, format, useMipmaps);

            finalTex.SetPixels32(finalPixels);
            finalTex.Apply(useMipmaps, !leaveTextureReadable);

            //Clean up.
            RenderTexture.ReleaseTemporary(target);

            return(finalTex);
        }
Esempio n. 9
0
        public override void OnImportAsset(AssetImportContext ctx)
        {
            var oldShader = AssetDatabase.LoadAssetAtPath <Shader>(ctx.assetPath);

            if (oldShader != null)
            {
                ShaderUtil.ClearShaderMessages(oldShader);
            }

            List <PropertyCollector.TextureInfo> configuredTextures;
            string path = ctx.assetPath;
            var    sourceAssetDependencyPaths = new List <string>();
            var    text   = GetShaderText(path, out configuredTextures, sourceAssetDependencyPaths, out var graph);
            var    shader = ShaderUtil.CreateShaderAsset(text, false);

            if (graph != null && graph.messageManager.nodeMessagesChanged)
            {
                foreach (var pair in graph.messageManager.GetNodeMessages())
                {
                    var node = graph.GetNodeFromTempId(pair.Key);
                    MessageManager.Log(node, path, pair.Value.First(), shader);
                }
            }

            EditorMaterialUtility.SetShaderDefaults(
                shader,
                configuredTextures.Where(x => x.modifiable).Select(x => x.name).ToArray(),
                configuredTextures.Where(x => x.modifiable).Select(x => EditorUtility.InstanceIDToObject(x.textureId) as Texture).ToArray());
            EditorMaterialUtility.SetShaderNonModifiableDefaults(
                shader,
                configuredTextures.Where(x => !x.modifiable).Select(x => x.name).ToArray(),
                configuredTextures.Where(x => !x.modifiable).Select(x => EditorUtility.InstanceIDToObject(x.textureId) as Texture).ToArray());

            Texture2D texture = Resources.Load <Texture2D>("Icons/sg_graph_icon@64");

            ctx.AddObjectToAsset("MainAsset", shader, texture);
            ctx.SetMainObject(shader);

            var metadata = ScriptableObject.CreateInstance <ShaderGraphMetadata>();

            metadata.hideFlags = HideFlags.HideInHierarchy;
            if (graph != null)
            {
                metadata.outputNodeTypeName = graph.outputNode.GetType().FullName;
            }
            ctx.AddObjectToAsset("Metadata", metadata);

            foreach (var sourceAssetDependencyPath in sourceAssetDependencyPaths.Distinct())
            {
                // Ensure that dependency path is relative to project
                if (!sourceAssetDependencyPath.StartsWith("Packages/") && !sourceAssetDependencyPath.StartsWith("Assets/"))
                {
                    Debug.LogWarning($"Invalid dependency path: {sourceAssetDependencyPath}", shader);
                    continue;
                }
                ctx.DependsOnSourceAsset(sourceAssetDependencyPath);
            }
        }
        public override void OnImportAsset(AssetImportContext ctx)
        {
            string fileContent = File.ReadAllText(ctx.assetPath);
            var    package     = ObjectFactory.CreateInstance <ShaderPackage>();

            if (!string.IsNullOrEmpty(fileContent))
            {
                EditorJsonUtility.FromJsonOverwrite(fileContent, package);
            }

            if (package.entries == null)
            {
                package.entries = new List <ShaderPackage.Entry>();
            }

#if __BETTERSHADERS__
            if (package.betterShader != null)
            {
                package.betterShaderPath = AssetDatabase.GetAssetPath(package.betterShader);
            }
#endif

            package.Pack(false);

#if __BETTERSHADERS__
            if (package.betterShader != null)
            {
                ctx.DependsOnSourceAsset(package.betterShaderPath);
            }
#endif

            foreach (var e in package.entries)
            {
                if (e.shader != null)
                {
                    ctx.DependsOnSourceAsset(AssetDatabase.GetAssetPath(e.shader));
                }
            }

            string shaderSrc = package.GetShaderSrc();
            if (shaderSrc == null)
            {
                Debug.LogError("No Shader for this platform and SRP provided");
                // maybe make an error shader here?
                return;
            }

            Shader shader = ShaderUtil.CreateShaderAsset(ctx, shaderSrc, false);

            ctx.AddObjectToAsset("MainAsset", shader);
            ctx.SetMainObject(shader);
        }
        void CompileNodeShader(AbstractMaterialNode node, GenerationMode mode, string nodeName)
        {
            var generator = new Generator(m_Graph, node, mode, nodeName, null);
            var shader    = ShaderUtil.CreateShaderAsset(generator.generatedShader, true);

            shader.hideFlags = HideFlags.HideAndDontSave;
            var mat = new Material(shader)
            {
                hideFlags = HideFlags.HideAndDontSave
            };

            ShaderUtil.CompilePass(mat, 0, true);
        }
        public override void OnImportAsset(AssetImportContext ctx)
        {
            Shader shader = null;

#if UNITY_2020_2_OR_NEWER
            //2020.2 or later supports shader dependencies registration
            shader = ShaderUtil.CreateShaderAsset(ctx, File.ReadAllText(ctx.assetPath), false);
#else
            //Versions of older unity don't support asset system context shader dependencies registration
            shader = ShaderUtil.CreateShaderAsset(File.ReadAllText(ctx.assetPath), false);
#endif
            ctx.AddObjectToAsset("MainAsset", shader);
            ctx.SetMainObject(shader);
        }
Esempio n. 13
0
        void AddPreview(AbstractMaterialNode node)
        {
            var renderData = new PreviewRenderData
            {
                renderTexture =
                    new RenderTexture(200, 200, 16, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Default)
                {
                    hideFlags = HideFlags.HideAndDontSave
                }
            };

            if (masterRenderData == null && (node is IMasterNode || node is SubGraphOutputNode))
            {
                m_MasterRenderData             = renderData;
                renderData.renderTexture.width = renderData.renderTexture.height = 400;
            }

            renderData.renderTexture.Create();

            var shaderData = new PreviewShaderData
            {
                node        = node,
                isCompiling = false,
                hasError    = false,
                shader      = ShaderUtil.CreateShaderAsset(k_EmptyShader, false)
            };

            shaderData.shader.hideFlags = HideFlags.HideAndDontSave;
            shaderData.mat = new Material(shaderData.shader)
            {
                hideFlags = HideFlags.HideAndDontSave
            };
            renderData.shaderData = shaderData;

            Set(m_Identifiers, node.tempId, node.tempId);
            Set(m_RenderDatas, node.tempId, renderData);
            node.RegisterCallback(OnNodeModified);

            if (node.RequiresTime())
            {
                m_RefreshTimedNodes = true;
            }

            if (m_MasterRenderData == renderData && onPrimaryMasterChanged != null)
            {
                onPrimaryMasterChanged();
            }

            m_NodesToUpdate.Add(node);
        }
Esempio n. 14
0
    internal static Shader BuildShaderGraph(GraphData graph, string name, bool hide = true)
    {
        var    generator    = new Generator(graph, graph.outputNode, GenerationMode.ForReals, "TransformGraph", null);
        string shaderString = generator.generatedShader;

        var shader = ShaderUtil.CreateShaderAsset(shaderString, false);

        if (hide)
        {
            shader.hideFlags = HideFlags.HideAndDontSave;
        }

        return(shader);
    }
Esempio n. 15
0
        public override void OnImportAsset(AssetImportContext ctx)
        {
            var oldShader = AssetDatabase.LoadAssetAtPath <Shader>(ctx.assetPath);

            if (oldShader != null)
            {
                ShaderUtil.ClearShaderMessages(oldShader);
            }

            List <PropertyCollector.TextureInfo> configuredTextures;
            string path = ctx.assetPath;
            var    sourceAssetDependencyPaths = new List <string>();
            var    text   = GetShaderText(path, out configuredTextures, sourceAssetDependencyPaths, out var graph);
            var    shader = ShaderUtil.CreateShaderAsset(text);

            if (graph.messageManager.nodeMessagesChanged)
            {
                foreach (var pair in graph.messageManager.GetNodeMessages())
                {
                    var node        = graph.GetNodeFromTempId(pair.Key);
                    var errorString = $"Error in Shader Graph at {path} in node {node.name}: {pair.Value.First().message}";
                    Debug.LogError(errorString, shader);
                }
            }

            EditorMaterialUtility.SetShaderDefaults(
                shader,
                configuredTextures.Where(x => x.modifiable).Select(x => x.name).ToArray(),
                configuredTextures.Where(x => x.modifiable).Select(x => EditorUtility.InstanceIDToObject(x.textureId) as Texture).ToArray());
            EditorMaterialUtility.SetShaderNonModifiableDefaults(
                shader,
                configuredTextures.Where(x => !x.modifiable).Select(x => x.name).ToArray(),
                configuredTextures.Where(x => !x.modifiable).Select(x => EditorUtility.InstanceIDToObject(x.textureId) as Texture).ToArray());

            ctx.AddObjectToAsset("MainAsset", shader);
            ctx.SetMainObject(shader);

            foreach (var sourceAssetDependencyPath in sourceAssetDependencyPaths.Distinct())
            {
                // Ensure that dependency path is relative to project
                if (!sourceAssetDependencyPath.StartsWith("Packages/") && !sourceAssetDependencyPath.StartsWith("Assets/"))
                {
                    Debug.LogWarning($"Invalid dependency path: {sourceAssetDependencyPath}", shader);
                    continue;
                }
                ctx.DependsOnSourceAsset(sourceAssetDependencyPath);
            }
        }
Esempio n. 16
0
        /// <summary>
        /// Generates a texture containing the given graph's noise output.
        /// If this is being called very often, create a permanent render target and material and
        ///     use the other version of this method instead for much better performance.
        /// If an error occurred, outputs to the Unity debug console and returns "null".
        /// </summary>
        /// <param name="gradientRampName">The name of the gradient ramp texture param.</param>
        /// <param name="uvZ">The Z coordinate of the UVs, in case the graph uses it for 3D noise.</param>
        /// <param name="leaveReadable">
        /// Whether to leave the texture data readable on the CPU after the operation.
        /// </param>
        public static Texture2D GenerateToTexture(Graph g, GraphParamCollection c,
                                                  int width, int height, float uvZ,
                                                  Gradient gradientRamp,
                                                  TextureFormat format = TextureFormat.RGBAFloat,
                                                  bool leaveReadable   = false)
        {
            //Generate a shader/material from the graph.
            Shader shader = ShaderUtil.CreateShaderAsset(g.GenerateShader("TempGPUNoiseShader",
                                                                          "_MyGradientRamp14123"));

            if (shader == null)
            {
                return(null);
            }
            Material mat = new Material(shader);

            c.SetParams(mat);
            mat.SetFloat(GraphUtils.Param_UVz, uvZ);

            //Generate a texture from the gradient.
            Texture2D myRamp = new Texture2D(1024, 1, TextureFormat.RGBA32, false);

            Color[] cols = new Color[myRamp.width];
            for (int i = 0; i < cols.Length; ++i)
            {
                cols[i] = gradientRamp.Evaluate((float)i / (float)(cols.Length - 1));
            }
            myRamp.SetPixels(cols);
            myRamp.Apply(false, true);
            mat.SetTexture("_MyGradientRamp14123", myRamp);

            //Render the shader's output into a render texture and copy the data to a Texture2D.
            RenderTexture target = RenderTexture.GetTemporary(width, height, 16,
                                                              RenderTextureFormat.ARGBFloat);
            Texture2D resultTex = new Texture2D(width, height, format, false, true);

            //Generate.
            GraphUtils.GenerateToTexture(target, mat, resultTex, leaveReadable);

            //Clean up.
            RenderTexture.ReleaseTemporary(target);

            return(resultTex);
        }
Esempio n. 17
0
        /// <summary>
        /// Properly updates the preview texture for this window.
        /// Returns it in case anybody wants it (returns null if there was a problem loading the graph).
        /// </summary>
        public Texture2D GetPreview(bool regenerateShader)
        {
            //Regenerate shader.
            if (regenerateShader || previewMat == null)
            {
                //Render the gradient ramp to a texture.
                Gradient  gradient = MakeGradient();
                Texture2D myRamp   = new Texture2D(1024, 1, TextureFormat.RGBA32, false);
                myRamp.wrapMode = TextureWrapMode.Clamp;
                Color[] cols = new Color[myRamp.width];
                for (int i = 0; i < cols.Length; ++i)
                {
                    cols[i] = gradient.Evaluate((float)i / (float)(cols.Length - 1));
                }
                myRamp.SetPixels(cols);
                myRamp.Apply(false, true);

                Graph  graph  = new Graph(graphPaths[SelectedGraphIndex]);
                string errMsg = graph.Load();
                if (errMsg.Length > 0)
                {
                    Debug.LogError("Error loading graph " + graphPaths[SelectedGraphIndex] +
                                   ": " + errMsg);
                    return(null);
                }

                Shader shader = ShaderUtil.CreateShaderAsset(graph.GenerateShader(
                                                                 "Graph editor temp shader",
                                                                 "_textureGeneratorWindowGradient"));
                previewMat = new Material(shader);
                previewMat.SetTexture("_textureGeneratorWindowGradient", myRamp);
            }

            //Set parameters.
            gParams.SetParams(previewMat);
            previewMat.SetFloat(GraphUtils.Param_UVz, previewUVz);

            //Generate.
            GeneratePreview(ref previewTex, previewMat);
            return(previewTex);
        }
Esempio n. 18
0
        /// <summary>
        /// Converts a Sprite to a Texture2D.
        /// </summary>
        /// <param name="sprite"></param>
        /// <returns></returns>
        public static Texture2D ConvertSpriteToTexture(Sprite sprite)
        {
            var rect = sprite.rect;

            if (extractSpriteMaterial == null || extractSpriteMaterial.shader == null)
            {
                extractSpriteMaterial = new Material(ShaderUtil.CreateShaderAsset(extractSpriteShader));
            }

            extractSpriteMaterial.SetVector("_TexelSize", new Vector2(1f / sprite.texture.width, 1f / sprite.texture.height));
            extractSpriteMaterial.SetVector("_Rect", new Vector4(
                                                rect.x / sprite.texture.width,
                                                rect.y / sprite.texture.height,
                                                rect.width / sprite.texture.width,
                                                rect.height / sprite.texture.height
                                                ));

            var prevSRGB = GL.sRGBWrite;

            GL.sRGBWrite = true;
            RenderTexture prev = RenderTexture.active;
            var           rt   = RenderTexture.GetTemporary((int)rect.width, (int)rect.height, 0);

            RenderTexture.active = rt;
            GL.Clear(false, true, new Color(1, 1, 1, 0));
            Graphics.Blit(sprite.texture, rt, extractSpriteMaterial);


            Texture2D texture = new Texture2D(rt.width, rt.height, TextureFormat.ARGB32, false, true);

            texture.filterMode = FilterMode.Bilinear;
            texture.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0);
            texture.alphaIsTransparency = true;
            texture.Apply();

            RenderTexture.ReleaseTemporary(rt);
            RenderTexture.active = prev;
            GL.sRGBWrite         = prevSRGB;
            return(texture);
        }
Esempio n. 19
0
        void UpdateMasterNodeShader()
        {
            var shaderData = masterRenderData?.shaderData;
            var masterNode = shaderData?.node as IMasterNode;

            if (masterNode == null)
            {
                return;
            }

            List <PropertyCollector.TextureInfo> configuredTextures;

            shaderData.shaderString = masterNode.GetShader(GenerationMode.Preview, shaderData.node.name, out configuredTextures);

            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, false);
                shaderData.shader.hideFlags = HideFlags.HideAndDontSave;
            }
            else
            {
                ShaderUtil.ClearCachedData(shaderData.shader);
            }

            BeginCompile(masterRenderData, shaderData.shaderString, masterNode.GetActiveSubShader()?.GetPreviewPassIndex() ?? 0);
        }
Esempio n. 20
0
        void UpdateMasterNodeShader()
        {
            var shaderData = masterRenderData?.shaderData;
            var masterNode = shaderData?.node as IMasterNode;

            if (masterNode == null)
            {
                return;
            }

            var generator = new Generator(m_Graph, shaderData?.node, GenerationMode.Preview, shaderData?.node.name);

            shaderData.shaderString = generator.generatedShader;

            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, false);
                shaderData.shader.hideFlags = HideFlags.HideAndDontSave;
            }
            else
            {
                ShaderUtil.ClearCachedData(shaderData.shader);
            }

            BeginCompile(masterRenderData, shaderData.shaderString);
        }
Esempio n. 21
0
        void BeginCompile(PreviewRenderData renderData, string shaderStr)
        {
            using (BeginCompileMarker.Auto())
            {
                var shaderData = renderData.shaderData;

                // want to ensure this so we don't get confused with multiple compile versions in flight
                Assert.IsTrue(shaderData.passesCompiling == 0);

                if (shaderData.shader == null)
                {
                    shaderData.shader           = ShaderUtil.CreateShaderAsset(shaderStr, false);
                    shaderData.shader.hideFlags = HideFlags.HideAndDontSave;
                }
                else
                {
                    ShaderUtil.ClearCachedData(shaderData.shader);
                    ShaderUtil.UpdateShaderAsset(shaderData.shader, shaderStr, false);
                }

                if (shaderData.mat == null)
                {
                    shaderData.mat = new Material(shaderData.shader)
                    {
                        hideFlags = HideFlags.HideAndDontSave
                    };
                }

                shaderData.passesCompiling = shaderData.mat.passCount;
                for (var i = 0; i < shaderData.mat.passCount; i++)
                {
                    ShaderUtil.CompilePass(shaderData.mat, i);
                }
                m_NodesCompiling.Add(shaderData.node);
            }
        }
Esempio n. 22
0
        /// <summary>
        /// Draws the icon in a square rect, with a custom shader that makes the icon look better when down-scaled.
        /// This also handles mouseover effects, and linier color spacing.
        /// </summary>
        public void Draw(Rect rect, Texture texture)
        {
            if (Event.current.type != EventType.Repaint)
            {
                return;
            }

            if (!GUIClipInfo.VisibleRect.Contains(rect.center))
            {
                return;
            }

            if (blurWhenDownscalingMaterial == null || blurWhenDownscalingMaterial.shader == null)
            {
                blurWhenDownscalingMaterial = new Material(ShaderUtil.CreateShaderAsset(blurWhenDownscalingShader));
            }

            // The smaller the image, the bigger the texel size.
            float texelSize = Mathf.Pow(Mathf.Max((1f - rect.width / this.Active.width) * 1.866f, 0), 1.46f) / this.Active.width;

            blurWhenDownscalingMaterial.SetFloat("_TexelSize", texelSize);
            blurWhenDownscalingMaterial.SetColor("_TintColor", GUI.color);
            Graphics.DrawTexture(rect, texture, blurWhenDownscalingMaterial);
        }
Esempio n. 23
0
    static Material SetupMaterial(MicroSplatKeywords kwds, Material mat, MicroSplatBaseFeatures.DebugOutput debugOutput, bool useDebugTopo)
    {
        MicroSplatShaderGUI.MicroSplatCompiler comp = new MicroSplatShaderGUI.MicroSplatCompiler();

        List <string> keywords = new List <string>(kwds.keywords);

        RemoveKeyword(keywords, "_SNOW");
        RemoveKeyword(keywords, "_TESSDISTANCE");
        RemoveKeyword(keywords, "_WINDPARTICULATE");
        RemoveKeyword(keywords, "_SNOWPARTICULATE");
        RemoveKeyword(keywords, "_GLITTER");
        RemoveKeyword(keywords, "_SNOWGLITTER");
        RemoveKeyword(keywords, "_SPECULARFROMMETALLIC");
        RemoveKeyword(keywords, "_USESPECULARWORKFLOW");
        RemoveKeyword(keywords, "_BDRFLAMBERT");
        RemoveKeyword(keywords, "_BDRF1");
        RemoveKeyword(keywords, "_BDRF2");
        RemoveKeyword(keywords, "_BDRF3");

        keywords.Add(FeatureFromOutput(debugOutput).ToString());
        if (useDebugTopo)
        {
            keywords.Add("_DEBUG_USE_TOPOLOGY");
        }

        keywords.Add("_RENDERBAKE");

        string   shader    = comp.Compile(keywords.ToArray(), "RenderBake_" + debugOutput.ToString());
        Shader   s         = ShaderUtil.CreateShaderAsset(shader);
        Material renderMat = new Material(mat);

        renderMat.shader = s;
        renderMat.CopyPropertiesFromMaterial(mat); // because the constructor doesn't do it right in URP
        renderMat.enableInstancing = false;        // for some reason instance drawing breaks in URP
        return(renderMat);
    }
Esempio n. 24
0
        internal void OnBakeTexture()
        {
            var graph = owner as GraphData;

            if (graph == null)
            {
                Debug.LogError("BakeTextureNode's owner isn't a AbstractMaterialGraph, how is it possible ?");
            }

            // from https://github.com/Unity-Technologies/ScriptableRenderPipeline/commit/3b28421204badded8c0d14315f10c256de3345a0#diff-52bd31870846010ea070163214aac090
            graph.GetShader(this, GenerationMode.Preview, "hidden/preview");


            BakeShaderData shaderData = new BakeShaderData();

            shaderData.ShaderString = graph.GetPreviewShader(this).shader;
            shaderData.Shader       = ShaderUtil.CreateShaderAsset(shaderData.ShaderString);
            shaderData.Node         = this;
            shaderData.Graph        = graph;
            shaderData.HasError     = false; // TODO handle shader errors
            shaderData.OutputIdName = "Out";

            BakeTextureManager.BakeShaderIntoTexture(shaderData);
        }
    public override void OnImportAsset(AssetImportContext ctx)
    {
        var oldShader = AssetDatabase.LoadAssetAtPath <Shader>(ctx.assetPath);

        if (oldShader != null)
        {
            ShaderUtil.ClearShaderErrors(oldShader);
        }

        List <PropertyCollector.TextureInfo> configuredTextures;
        var text = GetShaderText <MaterialGraph>(ctx.assetPath, out configuredTextures);

        if (text == null)
        {
            text = errorShader;
        }

        var    name       = Path.GetFileNameWithoutExtension(ctx.assetPath);
        string shaderName = string.Format("graphs/{0}", name);

        text = text.Replace("Hidden/GraphErrorShader2", shaderName);

        var shader = ShaderUtil.CreateShaderAsset(text);

        EditorMaterialUtility.SetShaderDefaults(
            shader,
            configuredTextures.Where(x => x.modifiable).Select(x => x.name).ToArray(),
            configuredTextures.Where(x => x.modifiable).Select(x => EditorUtility.InstanceIDToObject(x.textureId) as Texture).ToArray());
        EditorMaterialUtility.SetShaderNonModifiableDefaults(
            shader,
            configuredTextures.Where(x => !x.modifiable).Select(x => x.name).ToArray(),
            configuredTextures.Where(x => !x.modifiable).Select(x => EditorUtility.InstanceIDToObject(x.textureId) as Texture).ToArray());

        ctx.AddObjectToAsset("MainAsset", shader);
        ctx.SetMainObject(shader);
    }
Esempio n. 26
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;
            }
        }
Esempio n. 27
0
 public static Shader CreataShader(string shader)
 {
     return(ShaderUtil.CreateShaderAsset(shader));
 }
Esempio n. 28
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 || NodeUtils.FindEffectiveShaderStage(node, true) == ShaderStage.Vertex))
            {
                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;
                }
            }

            #if UNITY_SHADER_GRAPH_DEVMODE
            File.WriteAllText(Application.dataPath + "/../GeneratedShader.shader", (shaderData.shaderString ?? "null").Replace("UnityEngine.MaterialGraph", "Generated"));
            #endif

            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 UNITY_SHADER_GRAPH_DEVMODE
            var message = "RecreateShader: " + node.GetVariableNameForNode() + Environment.NewLine + shaderData.shaderString;
            #endif
            if (MaterialGraphAsset.ShaderHasError(shaderData.shader))
            {
                shaderData.hasError = true;
                Debug.LogWarning(message);
                ShaderUtil.ClearShaderErrors(shaderData.shader);
                Object.DestroyImmediate(shaderData.shader, true);
                shaderData.shader = null;
            }
            else
            {
                shaderData.hasError = false;
            }
        }
Esempio n. 29
0
        public override void OnImportAsset(AssetImportContext ctx)
        {
            var oldShader = AssetDatabase.LoadAssetAtPath <Shader>(ctx.assetPath);

            if (oldShader != null)
            {
                ShaderUtil.ClearShaderMessages(oldShader);
            }

            List <PropertyCollector.TextureInfo> configuredTextures;
            string path = ctx.assetPath;

            AssetCollection assetCollection = new AssetCollection();

            MinimalGraphData.GatherMinimalDependenciesFromFile(assetPath, assetCollection);

            var textGraph = File.ReadAllText(path, Encoding.UTF8);
            var graph     = new GraphData
            {
                messageManager = new MessageManager(), assetGuid = AssetDatabase.AssetPathToGUID(path)
            };

            MultiJson.Deserialize(graph, textGraph);
            graph.OnEnable();
            graph.ValidateGraph();

            Shader shader = null;

#if VFX_GRAPH_10_0_0_OR_NEWER
            if (!graph.isOnlyVFXTarget)
#endif
            {
                // build the shader text
                // this will also add Target dependencies into the asset collection
                var text = GetShaderText(path, out configuredTextures, assetCollection, graph);

#if UNITY_2021_1_OR_NEWER
                // 2021.1 or later is guaranteed to have the new version of this function
                shader = ShaderUtil.CreateShaderAsset(ctx, text, false);
#else
                // earlier builds of Unity may or may not have it
                // here we try to invoke the new version via reflection
                var createShaderAssetMethod = typeof(ShaderUtil).GetMethod(
                    "CreateShaderAsset",
                    System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.ExactBinding,
                    null,
                    new Type[] { typeof(AssetImportContext), typeof(string), typeof(bool) },
                    null);

                if (createShaderAssetMethod != null)
                {
                    shader = createShaderAssetMethod.Invoke(null, new Object[] { ctx, text, false }) as Shader;
                }
                else
                {
                    // method doesn't exist in this version of Unity, call old version
                    // this doesn't create dependencies properly, but is the best that we can do
                    shader = ShaderUtil.CreateShaderAsset(text, false);
                }
#endif

                if (graph.messageManager.nodeMessagesChanged)
                {
                    foreach (var pair in graph.messageManager.GetNodeMessages())
                    {
                        var node = graph.GetNodeFromId(pair.Key);
                        MessageManager.Log(node, path, pair.Value.First(), shader);
                    }
                }

                EditorMaterialUtility.SetShaderDefaults(
                    shader,
                    configuredTextures.Where(x => x.modifiable).Select(x => x.name).ToArray(),
                    configuredTextures.Where(x => x.modifiable).Select(x => EditorUtility.InstanceIDToObject(x.textureId) as Texture).ToArray());
                EditorMaterialUtility.SetShaderNonModifiableDefaults(
                    shader,
                    configuredTextures.Where(x => !x.modifiable).Select(x => x.name).ToArray(),
                    configuredTextures.Where(x => !x.modifiable).Select(x => EditorUtility.InstanceIDToObject(x.textureId) as Texture).ToArray());
            }

            UnityEngine.Object mainObject = shader;
#if VFX_GRAPH_10_0_0_OR_NEWER
            ShaderGraphVfxAsset vfxAsset = null;
            if (graph.hasVFXTarget)
            {
                vfxAsset = GenerateVfxShaderGraphAsset(graph);
                if (mainObject == null)
                {
                    mainObject = vfxAsset;
                }
                else
                {
                    //Correct main object if we have a shader and ShaderGraphVfxAsset : save as sub asset
                    vfxAsset.name = Path.GetFileNameWithoutExtension(path);
                    ctx.AddObjectToAsset("VFXShaderGraph", vfxAsset);
                }
            }
#endif

            Texture2D texture = Resources.Load <Texture2D>("Icons/sg_graph_icon");
            ctx.AddObjectToAsset("MainAsset", mainObject, texture);
            ctx.SetMainObject(mainObject);

            foreach (var target in graph.activeTargets)
            {
                if (target is IHasMetadata iHasMetadata)
                {
                    var metadata = iHasMetadata.GetMetadataObject();
                    if (metadata == null)
                    {
                        continue;
                    }

                    metadata.hideFlags = HideFlags.HideInHierarchy;
                    ctx.AddObjectToAsset($"{iHasMetadata.identifier}:Metadata", metadata);
                }
            }

            var sgMetadata = ScriptableObject.CreateInstance <ShaderGraphMetadata>();
            sgMetadata.hideFlags         = HideFlags.HideInHierarchy;
            sgMetadata.assetDependencies = new List <UnityEngine.Object>();

            foreach (var asset in assetCollection.assets)
            {
                if (asset.Value.HasFlag(AssetCollection.Flags.IncludeInExportPackage))
                {
                    // this sucks that we have to fully load these assets just to set the reference,
                    // which then gets serialized as the GUID that we already have here.  :P

                    var dependencyPath = AssetDatabase.GUIDToAssetPath(asset.Key);
                    if (!string.IsNullOrEmpty(dependencyPath))
                    {
                        sgMetadata.assetDependencies.Add(
                            AssetDatabase.LoadAssetAtPath(dependencyPath, typeof(UnityEngine.Object)));
                    }
                }
            }
            ctx.AddObjectToAsset("SGInternal:Metadata", sgMetadata);

            // declare dependencies
            foreach (var asset in assetCollection.assets)
            {
                if (asset.Value.HasFlag(AssetCollection.Flags.SourceDependency))
                {
                    ctx.DependsOnSourceAsset(asset.Key);

                    // I'm not sure if this warning below is actually used or not, keeping it to be safe
                    var assetPath = AssetDatabase.GUIDToAssetPath(asset.Key);

                    // Ensure that dependency path is relative to project
                    if (!string.IsNullOrEmpty(assetPath) && !assetPath.StartsWith("Packages/") && !assetPath.StartsWith("Assets/"))
                    {
                        Debug.LogWarning($"Invalid dependency path: {assetPath}", mainObject);
                    }
                }

                // NOTE: dependencies declared by GatherDependenciesFromSourceFile are automatically registered as artifact dependencies
                // HOWEVER: that path ONLY grabs dependencies via MinimalGraphData, and will fail to register dependencies
                // on GUIDs that don't exist in the project.  For both of those reasons, we re-declare the dependencies here.
                if (asset.Value.HasFlag(AssetCollection.Flags.ArtifactDependency))
                {
                    ctx.DependsOnArtifact(asset.Key);
                }
            }
        }
Esempio n. 30
0
        public override void OnImportAsset(AssetImportContext ctx)
        {
            var oldShader = AssetDatabase.LoadAssetAtPath <Shader>(ctx.assetPath);

            if (oldShader != null)
            {
                ShaderUtil.ClearShaderMessages(oldShader);
            }

            List <PropertyCollector.TextureInfo> configuredTextures;
            string path = ctx.assetPath;
            var    sourceAssetDependencyPaths = new List <string>();

            var textGraph = File.ReadAllText(path, Encoding.UTF8);
            var graph     = new GraphData
            {
                messageManager = new MessageManager(), assetGuid = AssetDatabase.AssetPathToGUID(path)
            };

            MultiJson.Deserialize(graph, textGraph);
            graph.OnEnable();
            graph.ValidateGraph();

            Shader shader = null;

#if VFX_GRAPH_10_0_0_OR_NEWER
            if (!graph.isOnlyVFXTarget)
#endif
            {
                var text = GetShaderText(path, out configuredTextures, sourceAssetDependencyPaths, graph);

#if UNITY_2021_1_OR_NEWER
                // 2021.1 or later is guaranteed to have the new version of this function
                shader = ShaderUtil.CreateShaderAsset(ctx, text, false);
#else
                // earlier builds of Unity may or may not have it
                // here we try to invoke the new version via reflection
                var createShaderAssetMethod = typeof(ShaderUtil).GetMethod(
                    "CreateShaderAsset",
                    System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.ExactBinding,
                    null,
                    new Type[] { typeof(AssetImportContext), typeof(string), typeof(bool) },
                    null);

                if (createShaderAssetMethod != null)
                {
                    shader = createShaderAssetMethod.Invoke(null, new Object[] { ctx, text, false }) as Shader;
                }
                else
                {
                    // method doesn't exist in this version of Unity, call old version
                    // this doesn't create dependencies properly, but is the best that we can do
                    shader = ShaderUtil.CreateShaderAsset(text, false);
                }
#endif

                if (graph.messageManager.nodeMessagesChanged)
                {
                    foreach (var pair in graph.messageManager.GetNodeMessages())
                    {
                        var node = graph.GetNodeFromId(pair.Key);
                        MessageManager.Log(node, path, pair.Value.First(), shader);
                    }
                }

                EditorMaterialUtility.SetShaderDefaults(
                    shader,
                    configuredTextures.Where(x => x.modifiable).Select(x => x.name).ToArray(),
                    configuredTextures.Where(x => x.modifiable).Select(x => EditorUtility.InstanceIDToObject(x.textureId) as Texture).ToArray());
                EditorMaterialUtility.SetShaderNonModifiableDefaults(
                    shader,
                    configuredTextures.Where(x => !x.modifiable).Select(x => x.name).ToArray(),
                    configuredTextures.Where(x => !x.modifiable).Select(x => EditorUtility.InstanceIDToObject(x.textureId) as Texture).ToArray());
            }

            UnityEngine.Object mainObject = shader;
#if VFX_GRAPH_10_0_0_OR_NEWER
            ShaderGraphVfxAsset vfxAsset = null;
            if (graph.hasVFXTarget)
            {
                vfxAsset = GenerateVfxShaderGraphAsset(graph);
                if (mainObject == null)
                {
                    mainObject = vfxAsset;
                }
                else
                {
                    //Correct main object if we have a shader and ShaderGraphVfxAsset : save as sub asset
                    vfxAsset.name = Path.GetFileNameWithoutExtension(path);
                    ctx.AddObjectToAsset("VFXShaderGraph", vfxAsset);
                }
            }
#endif

            Texture2D texture = Resources.Load <Texture2D>("Icons/sg_graph_icon@64");
            ctx.AddObjectToAsset("MainAsset", mainObject, texture);
            ctx.SetMainObject(mainObject);

            foreach (var target in graph.activeTargets)
            {
                if (target is IHasMetadata iHasMetadata)
                {
                    var metadata = iHasMetadata.GetMetadataObject();
                    if (metadata == null)
                    {
                        continue;
                    }

                    metadata.hideFlags = HideFlags.HideInHierarchy;
                    ctx.AddObjectToAsset($"{iHasMetadata.identifier}:Metadata", metadata);
                }
            }

            var sgMetadata = ScriptableObject.CreateInstance <ShaderGraphMetadata>();
            sgMetadata.hideFlags         = HideFlags.HideInHierarchy;
            sgMetadata.assetDependencies = new List <UnityEngine.Object>();
            var deps = GatherDependenciesFromSourceFile(ctx.assetPath);
            foreach (string dependency in deps)
            {
                sgMetadata.assetDependencies.Add(AssetDatabase.LoadAssetAtPath(dependency, typeof(UnityEngine.Object)));
            }
            ctx.AddObjectToAsset("SGInternal:Metadata", sgMetadata);


            foreach (var sourceAssetDependencyPath in sourceAssetDependencyPaths.Distinct())
            {
                // Ensure that dependency path is relative to project
                if (!sourceAssetDependencyPath.StartsWith("Packages/") && !sourceAssetDependencyPath.StartsWith("Assets/"))
                {
                    Debug.LogWarning($"Invalid dependency path: {sourceAssetDependencyPath}", mainObject);
                    continue;
                }

                ctx.DependsOnSourceAsset(sourceAssetDependencyPath);
            }
        }