heyx3 / GPUNoiseForUnity

A Unity plugin for generating noise on the GPU for use in the editor.
Other
109 stars 17 forks source link

GPUGraph

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.

Overview

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:

White Noise

A side utility is also provided for easy random number generation on the GPU: "Assets/GPUGraph/GpuRandWithState.cginc".

Editor

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

Nodes

All the nodes this plugin currently offers are listed here:

Applications

Several example applications are built into the editor; they are all accessible through the "Assets/GPU Graph" category in the Unity editor's toolbar.

Shader Generator

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.

Texture 2D Generator

This tool generates a 2D texture file using a graph.

Texture 3D Generator

This tool generates a 3D texture file (and, optionally, an accompanying normal texture) using a graph.

Texture Generator

This is the abstract base class for Texture2DGenerator and Texture3DGenerator. It provides the bulk of their GUI.

Terrain Generator

This tool uses a graph to generate a heightmap for whichever terrain object is currently selected in the scene view.

Code

Code is organized in the following way inside the "GPU Noise" folder:

Graph System

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:

Applications

namespace: GPUGraph.Applications

This folder contains the various built-in utilities mentioned above: ShaderGenerator, Texture2DGenerator, Texture3DGenerator, and TerrainGenerator.

Known Issues

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.

License

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.