/// <summary>
		/// Gets all parameters from the given collection and recreates them for the given graph.
		/// </summary>
		public GraphParamCollection(Graph otherG, GraphParamCollection c)
			: this(otherG)
		{
			//Needed for lambdas.
			List<FloatParamInfo> myFloatParams = FloatParams;
			List<Texture2DParamInfo> myTex2DParams = Tex2DParams;

			for (int i = 0; i < FloatParams.Count; ++i)
			{
				int otherPMIndex = c.FloatParams.FindIndex(param2 => param2.Name == myFloatParams[i].Name);
				if (otherPMIndex == -1)
					Debug.LogError("Couldn't find an original value for scalar var '" + FloatParams[i].Name + "'");
				else
					FloatParams[i] = new FloatParamInfo(FloatParams[i],
														c.FloatParams[otherPMIndex].DefaultValue);
			}
			for (int i = 0; i < Tex2DParams.Count; ++i)
			{
				int otherPMIndex = c.Tex2DParams.FindIndex(param2 => param2.Name == myTex2DParams[i].Name);
				if (otherPMIndex == -1)
					Debug.LogError("Couldn't find an original value for Tex2D var '" + Tex2DParams[i].Name + "'");
				else
					Tex2DParams[i] = new Texture2DParamInfo(Tex2DParams[i].Name,
															c.Tex2DParams[otherPMIndex].DefaultVal);
			}
		}
        /// <summary>
        /// Gets all parameters from the given collection and recreates them for the given graph.
        /// </summary>
        public GraphParamCollection(Graph otherG, GraphParamCollection c)
            : this(otherG)
        {
            //Needed for lambdas.
            List<FloatParamInfo> myFloatParams = FloatParams;
            List<Texture2DParamInfo> myTex2DParams = Tex2DParams;

            for (int i = 0; i < FloatParams.Count; ++i)
            {
                int otherPMIndex = c.FloatParams.FindIndex(param2 => param2.Name == myFloatParams[i].Name);
                if (otherPMIndex == -1)
                    Debug.LogError("Couldn't find an original value for scalar var '" + FloatParams[i].Name + "'");
                else
                    FloatParams[i] = new FloatParamInfo(FloatParams[i],
                                                        c.FloatParams[otherPMIndex].DefaultValue);
            }
            for (int i = 0; i < Tex2DParams.Count; ++i)
            {
                int otherPMIndex = c.Tex2DParams.FindIndex(param2 => param2.Name == myTex2DParams[i].Name);
                if (otherPMIndex == -1)
                    Debug.LogError("Couldn't find an original value for Tex2D var '" + Tex2DParams[i].Name + "'");
                else
                    Tex2DParams[i] = new Texture2DParamInfo(Tex2DParams[i].Name,
                                                            c.Tex2DParams[otherPMIndex].DefaultVal);
            }
        }
Example #3
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>
        public static Texture2D GenerateToTexture(Graph g, GraphParamCollection c, int width, int height,
                                                  string outputComponents, float defaultColor,
                                                  TextureFormat format = TextureFormat.RGBAFloat)
        {
            //Generate a shader from the graph and have Unity compile it.
            string shaderPath = Path.Combine(Application.dataPath, "gpuNoiseShaderTemp.shader");
            Shader shader     = SaveShader(g, shaderPath, "TempGPUNoiseShader", outputComponents, defaultColor);

            if (shader == null)
            {
                return(null);
            }

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

            target.Create();
            Texture2D resultTex = new Texture2D(width, height, format, false, true);

            //Create the material and set its parameters.
            Material mat = new Material(shader);

            c.SetParams(mat);

            GraphUtils.GenerateToTexture(target, mat, resultTex);

            //Clean up.
            target.Release();
            if (!AssetDatabase.DeleteAsset(StringUtils.GetRelativePath(shaderPath, "Assets")))
            {
                Debug.LogError("Unable to delete temp file: " + shaderPath);
            }

            return(resultTex);
        }
        void OnEnable()
        {
            graphPaths.Clear();
            graphPaths = GraphEditorUtils.GetAllGraphsInProject();

            Func<string, GUIContent> selector = (gp => new GUIContent(Path.GetFileNameWithoutExtension(gp), gp));
            graphNameOptions = graphPaths.Select(selector).ToArray();

            this.titleContent = new GUIContent("Texture Gen");
            this.minSize = new Vector2(200.0f, 270.0f);

            gParams = new GraphParamCollection();

            GradientRamp_Colors = new List<Color>() { Color.black, Color.white };
            GradientRamp_Times = new List<float>() { 0.0f, 1.0f };

            SelectedGraphIndex = 0;
            if (graphPaths.Count > 0)
            {
                Graph g = new Graph(graphPaths[SelectedGraphIndex]);
                if (g.Load().Length == 0)
                {
                    gParams = new GraphParamCollection(g);
                }
            }
        }
Example #5
0
        /// <summary>
        /// Generates a 3D grid of noise from the given graph.
        /// If an error occurred, outputs to the Unity debug console and returns "null".
        /// </summary>
        public static float[,,] GenerateToArray(Graph g, GraphParamCollection c,
                                                int width, int height, int depth)
        {
            //Generate a 3D texture using the graph's shader.
            Texture3D t = GenerateToTexture(g, c, width, height, depth, "r", 0.0f, false, true,
                                            TextureFormat.RGBA32);

            if (t == null)
            {
                return(null);
            }

            //Read the texture data and put it into a 3D array.
            Color[] cols = t.GetPixels();
            float[,,] vals = new float[width, height, depth];
            int i = 0;

            for (int z = 0; z < depth; ++z)
            {
                for (int y = 0; y < height; ++y)
                {
                    for (int x = 0; x < width; ++x)
                    {
                        vals[x, y, z] = cols[i++].r;
                    }
                }
            }

            return(vals);
        }
Example #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);
        }
        /// <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>
        public static Texture2D GenerateToTexture(Graph g, GraphParamCollection c, int width, int height,
												  string outputComponents, float defaultColor,
												  TextureFormat format = TextureFormat.RGBAFloat)
        {
            //Generate a shader from the graph and have Unity compile it.
            string shaderPath = Path.Combine(Application.dataPath, "gpuNoiseShaderTemp.shader");
            Shader shader = SaveShader(g, shaderPath, "TempGPUNoiseShader", outputComponents, defaultColor);
            if (shader == null)
            {
                return null;
            }

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

            //Create the material and set its parameters.
            Material mat = new Material(shader);
            c.SetParams(mat);

            GraphUtils.GenerateToTexture(target, mat, resultTex);

            //Clean up.
            target.Release();
            if (!AssetDatabase.DeleteAsset(StringUtils.GetRelativePath(shaderPath, "Assets")))
            {
                Debug.LogError("Unable to delete temp file: " + shaderPath);
            }

            return resultTex;
        }
Example #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);
        }
Example #9
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>
        public static Texture2D GenerateToTexture(Graph g, GraphParamCollection c, int width, int height,
                                                  Gradient gradientRamp,
                                                  TextureFormat format = TextureFormat.RGBAFloat)
        {
            //Generate a shader from the graph and have Unity compile it.
            string shaderPath = Path.Combine(Application.dataPath, "gpuNoiseShaderTemp.shader");
            Shader shader     = SaveShader(g, shaderPath, "TempGPUNoiseShader", "_MyGradientRamp14123");

            if (shader == null)
            {
                return(null);
            }

            //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);

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

            target.Create();
            Texture2D resultTex = new Texture2D(width, height, format, false, true);

            //Create the material and set its parameters.
            Material mat = new Material(shader);

            mat.SetTexture("_MyGradientRamp14123", myRamp);
            c.SetParams(mat);

            GraphUtils.GenerateToTexture(target, mat, resultTex);

            //Clean up.
            target.Release();
            if (!AssetDatabase.DeleteAsset(StringUtils.GetRelativePath(shaderPath, "Assets")))
            {
                Debug.LogError("Unable to delete temp file: " + shaderPath);
            }

            return(resultTex);
        }
		/// <summary>
		/// Sets this collection's parameter values from the given collection.
		/// Ignores parameters that don't exist on this collection.
		/// </summary>
		public void SetParams(GraphParamCollection from)
		{
			for (int i = 0; i < FloatParams.Count; ++i)
			{
				var toParam = FloatParams[i];
				var fromParam = from.FindFloatParam(toParam.Name);
				if (fromParam.HasValue)
					FloatParams[i] = new FloatParamInfo(toParam, fromParam.Value.DefaultValue);
			}
			for (int i = 0; i < Tex2DParams.Count; ++i)
			{
				var toParam = Tex2DParams[i];
				var fromParam = from.FindTex2DParam(toParam.Name);
				if (fromParam.HasValue)
					Tex2DParams[i] = new Texture2DParamInfo(toParam.Name, fromParam.Value.DefaultVal);
			}
		}
Example #11
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);
        }
        /// <summary>
        /// Generates a 2D grid of noise from the given graph.
        /// If an error occurred, outputs to the Unity debug console and returns "null".
        /// </summary>
        public static float[,] GenerateToArray(Graph g, GraphParamCollection c, int width, int height)
        {
            Texture2D t = GenerateToTexture(g, c, width, height, "r", 0.0f);
            if (t == null)
            {
                return null;
            }

            Color[] cols = t.GetPixels();
            float[,] vals = new float[width, height];
            for (int i = 0; i < cols.Length; ++i)
            {
                int x = i % width,
                    y = i / width;

                vals[x, y] = cols[i].r;
            }

            return vals;
        }
Example #13
0
        /// <summary>
        /// Refreshes the list of graphs and makes sure this node is still valid.
        /// Returns whether anything changed.
        /// </summary>
        private bool CheckOutGraphs(bool warnIfNotFound)
        {
            UpdateGraphPaths();

            //See if the current sub-graph being used still exists.
            selected = guids.IndexOf(GraphGUID);
            if (selected >= 0)
            {
                Graph g = TryLoadGraph();
                if (g == null)
                {
                    selected = -1;
                    ChangeGraph();
                    return(true);
                }
                else
                {
                    //See if the number of inputs changed.
                    GraphParamCollection gParams = new GraphParamCollection(g);
                    if (convertParamsToInputs && Inputs.Count != gParams.FloatParams.Count)
                    {
                        SetInputsFrom(gParams.FloatParams);
                        return(true);
                    }
                }
            }
            else
            {
                //Couldn't find the sub-graph anymore!
                if (warnIfNotFound)
                {
                    Debug.LogWarning("Couldn't find sub-graph at " +
                                     AssetDatabase.GUIDToAssetPath(GraphGUID));
                }
                selected = -1;
                ChangeGraph();
                return(true);
            }

            return(false);
        }
Example #14
0
        /// <summary>
        /// Generates a 2D grid of noise from the given graph.
        /// If an error occurred, outputs to the Unity debug console and returns "null".
        /// </summary>
        public static float[,] GenerateToArray(Graph g, GraphParamCollection c, int width, int height)
        {
            Texture2D t = GenerateToTexture(g, c, width, height, "r", 0.0f);

            if (t == null)
            {
                return(null);
            }

            Color[] cols = t.GetPixels();
            float[,] vals = new float[width, height];
            for (int i = 0; i < cols.Length; ++i)
            {
                int x = i % width,
                    y = i / width;

                vals[x, y] = cols[i].r;
            }

            return(vals);
        }
Example #15
0
        /// <summary>
        /// Updates the given RuntimeGraph's params to be consistent with the given GPUGraph.
        /// </summary>
        private void LoadParams(RuntimeGraph gR, Graph gE)
        {
            GraphParamCollection paramSet = new GraphParamCollection(gE);

            //Get all float params for the graph.
            var newFloatParams = new List <RuntimeGraph._SerializableFloatParamKVP>();

            foreach (FloatParamInfo fp in paramSet.FloatParams)
            {
                RuntimeGraph._SerializableFloatParamKVP sfp = new RuntimeGraph._SerializableFloatParamKVP();
                sfp.Key                = fp.Name;
                sfp.Value              = new RuntimeGraph._SerializableFloatParamInfo();
                sfp.Value.IsSlider     = fp.IsSlider;
                sfp.Value.SliderMin    = fp.SliderMin;
                sfp.Value.SliderMax    = fp.SliderMax;
                sfp.Value.DefaultValue = fp.DefaultValue;

                newFloatParams.Add(sfp);
            }
            //Remove vestigial params from the RuntimeGraph.
            for (int i = 0; i < gR.FloatParams.Count; ++i)
            {
                if (!newFloatParams.Any((kvp) => kvp.Key == gR.FloatParams[i].Key))
                {
                    gR.FloatParams.RemoveAt(i);
                    gR._FloatParams.RemoveAt(i);
                    i -= 1;
                }
            }
            //Update/add the params to the RuntimeGraph.
            for (int i = 0; i < newFloatParams.Count; ++i)
            {
                var param = new FloatParamKVP(newFloatParams[i].Key,
                                              (newFloatParams[i].Value.IsSlider ?
                                               Mathf.Lerp(newFloatParams[i].Value.SliderMin,
                                                          newFloatParams[i].Value.SliderMax,
                                                          newFloatParams[i].Value.DefaultValue) :
                                               newFloatParams[i].Value.DefaultValue));

                int found = gR.FloatParams.IndexOf(p => p.Key == newFloatParams[i].Key);
                if (found == -1)
                {
                    gR.FloatParams.Add(param);
                    gR._FloatParams.Add(newFloatParams[i]);
                }
                else
                {
                    param.Value            = gR.FloatParams[found].Value;
                    gR.FloatParams[found]  = param;
                    gR._FloatParams[found] = newFloatParams[i];
                }
            }

            //Get all Tex2D params for the graph.
            var newTex2DParams = new List <RuntimeGraph._SerializableTex2DParamKVP>();

            foreach (Texture2DParamInfo tp in paramSet.Tex2DParams)
            {
                RuntimeGraph._SerializableTex2DParamKVP stp = new RuntimeGraph._SerializableTex2DParamKVP();
                stp.Key   = tp.Name;
                stp.Value = new RuntimeGraph._SerializableTex2DParamInfo();
                stp.Value.DefaultValue = tp.DefaultVal;

                newTex2DParams.Add(stp);
            }
            //Remove vestigial params from the RuntimeGraph.
            for (int i = 0; i < gR.Tex2DParams.Count; ++i)
            {
                if (!newTex2DParams.Any((kvp) => kvp.Key == gR.Tex2DParams[i].Key))
                {
                    gR.Tex2DParams.RemoveAt(i);
                    gR._Tex2DParams.RemoveAt(i);
                    i -= 1;
                }
            }
            //Update/add new params to the RuntimeGraph.
            for (int i = 0; i < newTex2DParams.Count; ++i)
            {
                var param = new Tex2DParamKVP(newTex2DParams[i].Key,
                                              newTex2DParams[i].Value.DefaultValue);

                int found = gR.Tex2DParams.IndexOf(p => p.Key == newTex2DParams[i].Key);
                if (found == -1)
                {
                    gR.Tex2DParams.Add(param);
                    gR._Tex2DParams.Add(newTex2DParams[i]);
                }
                else
                {
                    param.Value            = gR.Tex2DParams[found].Value;
                    gR.Tex2DParams[found]  = param;
                    gR._Tex2DParams[found] = newTex2DParams[i];
                }
            }
        }
Example #16
0
        /// <summary>
        /// Refreshes the list of graphs and makes sure this node is still valid.
        /// Returns whether anything changed.
        /// </summary>
        private bool CheckOutGraphs(bool warnIfNotFound)
        {
            UpdateGraphPaths();

            //See if the current sub-graph being used still exists.
            selected = guids.IndexOf(GraphGUID);
            if (selected >= 0)
            {
                Graph g = TryLoadGraph();
                if (g == null)
                {
                    selected = -1;
                    ChangeGraph();
                    return true;
                }
                else
                {
                    //See if the number of inputs changed.
                    GraphParamCollection gParams = new GraphParamCollection(g);
                    if (convertParamsToInputs && Inputs.Count != gParams.FloatParams.Count)
                    {
                        SetInputsFrom(gParams.FloatParams);
                        return true;
                    }
                }
            }
            else
            {
                //Couldn't find the sub-graph anymore!
                if (warnIfNotFound)
                {
                    Debug.LogWarning("Couldn't find sub-graph at " +
                                        AssetDatabase.GUIDToAssetPath(GraphGUID));
                }
                selected = -1;
                ChangeGraph();
                return true;
            }

            return false;
        }
        /// <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>
        public static Texture2D GenerateToTexture(Graph g, GraphParamCollection c, int width, int height,
												  Gradient gradientRamp,
												  TextureFormat format = TextureFormat.RGBAFloat)
        {
            //Generate a shader from the graph and have Unity compile it.
            string shaderPath = Path.Combine(Application.dataPath, "gpuNoiseShaderTemp.shader");
            Shader shader = SaveShader(g, shaderPath, "TempGPUNoiseShader", "_MyGradientRamp14123");
            if (shader == null)
            {
                return null;
            }

            //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);

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

            //Create the material and set its parameters.
            Material mat = new Material(shader);
            mat.SetTexture("_MyGradientRamp14123", myRamp);
            c.SetParams(mat);

            GraphUtils.GenerateToTexture(target, mat, resultTex);

            //Clean up.
            target.Release();
            if (!AssetDatabase.DeleteAsset(StringUtils.GetRelativePath(shaderPath, "Assets")))
            {
                Debug.LogError("Unable to delete temp file: " + shaderPath);
            }

            return resultTex;
        }
        void OnGUI()
        {
            GUILayout.Space(10.0f);

            X = EditorGUILayout.IntField("Width", X);
            Y = EditorGUILayout.IntField("Height", Y);

            GUILayout.Space(15.0f);

            GUILayout.Label("Gradient");
            GUILayout.BeginHorizontal();
            GUILayout.Space(15.0f);
            GUILayout.BeginVertical();
            for (int i = 0; i < GradientRamp_Colors.Count; ++i)
            {
                GUILayout.BeginHorizontal();
                GradientRamp_Colors[i] = EditorGUILayout.ColorField(GradientRamp_Colors[i]);
                if (i > 0)
                    GradientRamp_Times[i] = EditorGUILayout.Slider(GradientRamp_Times[i],
                                                                   0.0f, 1.0f);
                if (i > 0 && GUILayout.Button("+"))
                {
                    GradientRamp_Colors.Insert(i, GradientRamp_Colors[i]);
                    GradientRamp_Times.Insert(i, GradientRamp_Times[i] - 0.00000001f);
                }
                if (i > 0 && GradientRamp_Colors.Count > 2 && GUILayout.Button("-"))
                {
                    GradientRamp_Colors.RemoveAt(i);
                    GradientRamp_Times.RemoveAt(i);
                    i -= 1;
                }
                GUILayout.EndHorizontal();

                if (i > 0 && GradientRamp_Times[i] < GradientRamp_Times[i - 1])
                {
                    GradientRamp_Times[i] = GradientRamp_Times[i - 1] + 0.000001f;
                }
                else if (i < GradientRamp_Colors.Count - 1 &&
                         GradientRamp_Times[i] > GradientRamp_Times[i + 1])
                {
                    GradientRamp_Times[i] = GradientRamp_Times[i + 1] - 0.00001f;
                }
            }
            GUILayout.EndVertical();
            GUILayout.EndHorizontal();

            GUILayout.Space(15.0f);

            GUILayout.BeginHorizontal();
            GUILayout.Label("Graph:");
            int oldIndex = SelectedGraphIndex;
            SelectedGraphIndex = EditorGUILayout.Popup(SelectedGraphIndex, graphNameOptions);
            if (oldIndex != SelectedGraphIndex)
            {
                Graph g = new Graph(graphPaths[SelectedGraphIndex]);
                if (g.Load().Length == 0)
                {
                    SelectedGraphIndex = oldIndex;
                }
                else
                {
                    gParams = new GraphParamCollection(g);
                }
            }
            GUILayout.EndHorizontal();

            GUILayout.Space(10.0f);

            //Show some GUI elements for changing the parameters.
            if (graphPaths.Count > 0)
                gParams.ParamEditorGUI();

            GUILayout.Space(10.0f);

            //If a graph is selected, display a button to generate the texture.
            if (graphPaths.Count > 0)
            {
                if (GUILayout.Button("Generate Texture"))
                {
                    string savePath = EditorUtility.SaveFilePanel("Choose where to save the texture.",
                                                                  Application.dataPath, "MyTex.png", "png");
                    if (savePath.Length > 0)
                    {
                        //Load the graph.
                        Graph g = new Graph(graphPaths[SelectedGraphIndex]);
                        if (g.Load().Length > 0)
                        {
                            return;
                        }

                        //Render the gradient ramp to a texture,
                        //    then render the graph's noise to a texture.
                        Gradient grd = new Gradient();
                        grd.SetKeys(GradientRamp_Colors.Select((c, i) =>
                                        new GradientColorKey(c, GradientRamp_Times[i])).ToArray(),
                                    new GradientAlphaKey[] { new GradientAlphaKey(1.0f, 0.0f) });
                        Texture2D tex = GraphEditorUtils.GenerateToTexture(g, new GraphParamCollection(g, gParams),
                                                                           X, Y, grd);
                        if (tex == null)
                        {
                            return;
                        }

                        //Write out the texture as a PNG.
                        try
                        {
                            File.WriteAllBytes(savePath, tex.EncodeToPNG());
                        }
                        catch (Exception e)
                        {
                            Debug.LogError("Unable to save texture to file: " + e.Message);
                        }

                        //Now that we're finished, clean up.
                        AssetDatabase.ImportAsset(StringUtils.GetRelativePath(savePath, "Assets"));

                        //Finally, open explorer to show the user the texture.
                        if (Application.platform == RuntimePlatform.WindowsEditor)
                        {
                            System.Diagnostics.Process.Start("explorer.exe",
                                                             "/select," +
                                                               StringUtils.FixDirectorySeparators(savePath));
                        }
                        else if (Application.platform == RuntimePlatform.OSXEditor)
                        {
                            try
                            {
                                System.Diagnostics.Process proc = new System.Diagnostics.Process();
                                proc.StartInfo.FileName = "open";
                                proc.StartInfo.Arguments = "-n -R \"" +
                                                            StringUtils.FixDirectorySeparators(savePath) +
                                                            "\"";
                                proc.StartInfo.UseShellExecute = false;
                                proc.StartInfo.RedirectStandardError = false;
                                proc.StartInfo.RedirectStandardOutput = false;
                                proc.ErrorDataReceived += (s, a) => Debug.Log(a.Data);
                                if (proc.Start())
                                {
                                    proc.BeginErrorReadLine();
                                    proc.BeginOutputReadLine();
                                }
                                else
                                {
                                    Debug.LogError("Error opening Finder to show texture file");
                                }
                            }
                            catch (Exception e)
                            {
                                Debug.LogError("Error opening Finder to show texture file: " + e.Message);
                            }
                        }
                    }
                }
            }
            else
            {
                GUILayout.Space(15.0f);
                GUILayout.Label("No graph files detected in the project!");
            }
        }