An open-source Unity plugin for generating coherent noise on the GPU, for both editor and runtime uses. The source is available here, on Github. It is also available on the Asset Store, but that version is currently out of date.
Editor tools for this plugin are available in the "Assets/GPU Graph" section on the Unity editor's toolbar. The .unitypackage file for this plugin is stored in the root of this repo: GPUGraph.unitypackage.
This repo contains the GPUGraph plugin for Unity, which provides classes and editors for generating floating-point noise on the GPU with shaders. This leads to extremely fast noise generation compared to traditional CPU methods.
Note that because Unity no longer supports runtime compilation of shaders, Graphs can only really be used in the editor. However, shaders can be generated from the graph in the editor then used in real-time (graphs can expose float and Tex2D parameters which are changeable at run-time). A serializable class "RuntimeGraph" is provided to greatly simplify use of run-time graphs; see "SampleScene.unity" and "SampleGPUGScript.cs" for an example of how to use it (note that you need to look at the SampleGPUGScript component in the Inspector to regenerate shaders before the scene will work).
The basic structure behind GPUGraph is a "Directed Acyclic Graph" (essentially a tree whose nodes can have multiple parents) of commands that represents shader code. Every node in the graph takes some number of floats as inputs and outputs a single float as a result.
Graphs are created in a custom editor window and saved as ".gpug" files into the "Assets" folder. The editor is accessed by selecting "Assets/GPU Graph/Editor" in the Unity editor's toolbar. Here is an example of a very simple graph that generates pure white noise:
A side utility is also provided for easy random number generation on the GPU: "Assets/GPUGraph/GpuRandWithState.cginc".
In the above image, note the various aspects of the graph editor:
In order to add a new node, click the button for the node you want to place, then left-click in the graph to place it. Right-click in the graph to cancel. A node's inputs are on the left side, and its output is on the right side. Note that some nodes have no inputs at all. Each input to a node is either the output of a different node or a constant value entered in a text box.
You can add the basic arithmetic nodes by pressing their respective keys (+
, -
, *
, and /
).
All the nodes this plugin currently offers are listed here:
floor
of the seed value.Lerp
but with a smooth, third-order curve instead of a line.Several example applications are built into the editor; they are all accessible through the "Assets/GPU Graph" category in the Unity editor's toolbar.
This tool generates a shader that outputs the graph's noise. You could then create a material that uses this shader and use it in the editor or at runtime to generate noise via the GPUGraph.GraphUtils
and GPUGraph.GraphEditorUtils
classes. Fortunately, a helper class RuntimeGraph
has already been created to make this easier for you, complete with custom Inspector code, but this utility is still useful if you want to further mess with the shader after generating it.
This tool generates a 2D texture file using a graph.
This tool generates a 3D texture file (and, optionally, an accompanying normal texture) using a graph.
This is the abstract base class for Texture2DGenerator and Texture3DGenerator. It provides the bulk of their GUI.
This tool uses a graph to generate a heightmap for whichever terrain object is currently selected in the scene view.
Code is organized in the following way inside the "GPU Noise" folder:
namespace: GPUGraph
The basic system for creating and manipulating graph data. This system uses C#'s built-in serialization system to save/load graphs to/from a file.
A graph node is an instance of a class inheriting from Node
. A node is given a unique UID by the graph it is added to, which is used when serializing/deserializing node references. It also has a rectangle representing its visual position in the graph editor.
A node's inputs are stored as a list of NodeInput
instances. Each NodeInput
is either a constant float (in which case IsAConstant
returns true
and ConstantValue
is well-defined) or it is the output of another node (in which case IsAConstant
returns false
and NodeID
contains the UID of the node whose output is being read).
Graphs are represented by the Graph
class, which has a collection of nodes, the file path of the graph, and the final output of the graph (a NodeInput
instance). It exposes Save()
and Load()
methods, as well as GenerateShader()
to get shader code, and the more abstract InsertShaderCode()
to use the graph's noise output as part of a more complex shader.
The GraphEditorUtils
class provides various ways to interact with a graph in the editor, including GetAllGraphsInProject()
, SaveShader()
, GenerateToTexture()
, and GenerateToArray()
. There is a similar class GraphUtils
that can be used at runtime.
The number of Node
child classes is actually fairly small:
SimpleNode
handles any kind of one-line expression, including all the built-in shader functions like sin
, lerp
, abs
, etc. The vast majority of nodes are instances of SimpleNode
.CustomExprNode
allows the user to type a custom shader expression using any number of inputs ($1
, $2
, $3
, etc).NoiseNode
is a node that generates 1D, 2D, 3D, or 4D noise. The noise can be "White", "Blocky", "Linear", "Smooth", "Smoother", "Perlin", or "Worley". Note that "Worley" has special editing options that the other noise types don't need.TexCoordNode
represents the UV coordinates of the texture the graph noise is being rendered into. This is generally how you get the input values for a noise function. It can output the X, Y, or Z coordinate. Z coordinate is used when you want to generate a 3D texture from the graph.ParamNode_Float
is a float parameter, represented as either a text box or a slider.ParamNode_Texture2D
is a 2D texture parameter.SubGraphNode
allows graphs to be used inside other graphs.namespace: GPUGraph.Applications
This folder contains the various built-in utilities mentioned above: ShaderGenerator, Texture2DGenerator, Texture3DGenerator, and TerrainGenerator.
If anybody wants to help out with these issues (or contribute to the codebase in any other way), feel free to send a pull request or email me at manning.w27@gmail.com.
When you first click on the editor after creating a new graph, it goes back to a state of not editing anything for some reason.
The editor window's UI is pretty rough; you get what you pay for :P. You can pan the view, but you can't zoom in or out. Adding zoom functionality can most likely be done somehow with the use of the GUIUtility.ScaleAroundPivot() method.
Additionally, the lines connecting nodes don't get drawn if they go off the right side of the graph area, and they get drawn over the other panes if they go off the left side.
Features like multi-node selection/movement, comments, and pressing Ctrl+S to save would be nice.
Terrain Generator should show a preview of the generated image.
UnityEditor's Undo
class just didn't seem to work at all with the graph editor window, so I don't use it at all (although I at least got it to work with RuntimeGraph's custom inspector). However, the editor closely tracks any unsaved changes and makes sure to tell you if you're about to discard them.
There are some bugs with drawing textures in RuntimeGraph's custom Inspector code; sometimes the textures aren't visible. As far as I can tell, this is Unity's problem.
It seems impossible to use one of Unity's built-in textures as a "default" value for a Texture2D parameter because I can't serialize its asset path (they all have the same file path, "Resources/unity_buitin_extra"). Currently I log a warning if you try to use one of them.
All code belongs to William Manning. Released under the MIT License (TL;DR: use it for literally any purpose, including commercially!)
````Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
````The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
````THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.