I like to think it's pronounced Wah-zum-Noise
WasmNoise is an open source noise generation library based on the popular FastNoise Library. It is written in C++ and compiled to WebAssembly in an effort to provide faster and more diverse noise generation utilities in the browser than those that are possible with just JavaScript.
It is still early in development, but I hope to get WasmNoise to a state of parity with FastNoise in terms of features offered. WebAssembly offers near native peeds but there will always be a slight difference in terms of speed.
My intention for this library is that it can be used to accelerate generation of noise in existing and new web sites, games and applications which consist predominately of JavaScript. If you are compiling an exisiting C/C++ application which uses FastNoise you should be using Emscripten, as it will compile it into your application.
- Perlin Noise 2D, 3D
- Fractal Perlin Noise (FBM, Billow, Ridged Multi) 2D, 3D
- Simplex Noise 2D, 3D, 4D
- Fractal Simplex Noise (FBM, Billow, Ridged Multi) 2D, 3D, 4D
- Cellular Noise 2D, 3D
- Fractal Cellular Noise (FBM, Billow, Ridged Multi) 2D, 3D
- Feature parity with FastNoise
- Custom builds to remove different noise types to reduce binary size
- v0.5.0 - Value Noise
- v0.6.0 - Cubic Noise
- v0.7.0 - White Noise
- v0.8.0/v1.0.0 - Gradient Perturb
WebAssembly does not have the functionality to return arrays like JavaScript does, it is only able to return single values from exported functions. Currently there is also a noticeable overhead for calling an exported WebAssembly function, this makes the single value return functions slower than their JavaScript equivalents.
To bypass this limitation I have implemented functions which generate noise values in bulk and return a pointer (offset) to the array these values are stored in, in linear memory. Variations of these functions allow you to produce strips, squares and cubes of noise values, cubes are not available for 2D noise functions due to the obvious limitations. These functions are comparable in speed to regular FastNoise, and much faster than their JavaScript equivalents.
There are a couple of examples in the html
folder which demonstrate different usages and outputs, however these are still just the pages I use for testing build iterations and not actual polished use cases.
WebAssembly binary files (.wasm) currently need to be loaded manually, as there is no way to load them with <script>
tags as of yet. For this purpose I have written an autoloader script which is generated with each build. It contains an onLoaded
callback function which it calls once it has set up the WasmNoise object, as well as a loaded
variable which is set to true once the compilation/instantiation process is complete. It also has as some extra functionality such as wrappers for the functions which return arrays. Take a look at autoloadertest.html
for how to use the onLoaded
function and the loaded
variable to tell when the module is loaded, and play around with the different functions in the developer console through the WasmNoise
global variable.
I try to make sure the latest version is available in the Releases section, this is a "full" build with no function sets disabled with an accompanying autoloader script. It is possible, through the build steps described below, to produce a slimmer binary file by disabling function sets (such as the different noise types). If you just want to play around with the WasmNoise binary, or don't mind the increased binary size, you can just grab the full binary from the releases section.
WasmNoise is developed primarily on a Windows 7 PC, and so the build instructions below are geared towards a similar build environment, however the tools used are all (except Visual Studio) available and buildable on Mac and Linux so adjusting the instructions to suit your environment should be straightforward.
- LLVM + Clang
- Binaryen
- Wabt
- Python 3 to run the buildwasnnoise.py script
- Guy Bedford's wasm-stdlib-hack,
git clone
side-by-side with WasmNoise or tweak the clangCmd variable in buildwasmnoise.py. - The latest Visual Studio (e.g. 2017 Community)
- Optional ninja for quicker building
- Optional MingW64 for building LLVM + Clang
To build the above required tools you will need CMake
If you want to build with ninja on windows (like I do) you can get it here, the prebuilt binary is sufficient, just make sure it resides somewhere on your Path so CMake can find it.
Building with ninja requires MinGW (or theoretically Clang/Clang++) on windows, so you can grab it from here, make sure to install the latest version and set the architecture to x86_64
, leave the rest of the options the same.
You may want to disable any antivirus software you have running during compilation of these projects, as they may quarantine or interfere with execution of tools and tests. Don't worry, you can reenable them once we're finished.
LLVM can be checked out with SVN from http://llvm.org/svn/llvm-project/llvm/trunk
Clang can be checked out with SVN from http://llvm.org/svn/llvm-project/cfe/trunk
Clang should be checked out into the tools folder within the llvm svn repository. There are instructions on the llvm site for how to build various parts of llvm out of tree, if you prefer to checkout LLVM and Clang side-by-side, but it involves additional cmake flags. I recommend the process listed below.
If you don't want to use SVN you can download the source for LLVM and Clang from here. Again, clang should be extracted to the tools folder of the llvm source. There are also git mirrors out there, though these are not official and may be behind the official svn repository.
Once you have the LLVM and Clang sources, build it with CMake (I advise creating a new folder called build next to the llvm source folder to keep things neat)
I use the following in a batch file:
cmake -G "Ninja" ^
-DCMAKE_BUILD_TYPE=Release ^
-DCMAKE_INSTALL_PREFIX="C:/llvm" ^
-DLLVM_TARGETS_TO_BUILD=X86 ^
-DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=WebAssembly ^
-DLLVM_INCLUDE_TESTS=OFF ^
-DLLVM_INCLUDE_EXAMPLES=OFF ^
-DLLVM_BUILD_TESTS=OFF ^
-DLLVM_BUILD_TOOLS=ON ^
-DCMAKE_CXX_FLAGS=-std=c++11 ^
-DBUILD_SHARED_LIBS=OFF ^
C:/llvm/source
The C:/llvm/source
path should point to the folder containing CmakeLists.txt for LLVM
To build LLVM and Clang with Visual Studio 2017 you can use this cmake command:
cmake -G "Visual Studio 15 2017 Win64" ^
-DCMAKE_BUILD_TYPE=Release ^
-DCMAKE_INSTALL_PREFIX="C:/llvm" ^
-DLLVM_TARGETS_TO_BUILD=X86 ^
-DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=WebAssembly ^
-DLLVM_INCLUDE_TESTS=OFF ^
-DLLVM_INCLUDE_EXAMPLES=OFF ^
-DLLVM_BUILD_TESTS=OFF ^
-DLLVM_BUILD_TOOLS=ON ^
-DBUILD_SHARED_LIBS=OFF ^
C:/llvm/source
This also includes the X86 target which will let clang & clang++ produce executables, this is not a requirement and can be removed, although clang isn't the most reliable on Windows it is handy to be able to check if the code you're writing for WebAssembly is valid for native executables and it's quicker than creating a VS project.
If it compiles correctly make sure to add the bin folder in your build directory to your Path variable.
The best way to build Binaryen is with Visual Studio, and is relatively painless.
The following command should handle using git to checkout binaryen and building it with MSBuild
git clone http://github.com/WebAssembly/binaryen.git && cd binaryen && mkdir build && cd build && cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_BUILD_TYPE=Release .. && cmake --build . --config Release
You can also use Visual Studio to build with the solution file produced by cmake if you prefer, just omit the && cmake --build .
from the above command.
Once it's finished compiling, remember to add the bin folder to your Path variable like before.
Again, Wabt is best built with Visual Studio.
The following command should handle checking out wabt and compiling it
git clone http://github.com/WebAssembly/wabt.git && cd wabt && mkdir build && cd build && cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTS=OFF .. && cmake --build . --config Release
Add the bin folder to your Path and you should have all the necessary tools.
If you have all the correct bin directories added to your path, cd into the root wasmnoise directory and run buildwasmnoise.py
. This requires Python 3, and if you have both python 2 and python 3 installed your system may try running the build script with python 2, which will of course fail. As a work around on my system I have renamed the python 3 executable (located at C:\Users\<Me>\AppData\Local\Programs\Python\Python36-32
) to python3, and so execute the build script with the command python3 buildwasmnoise.py
.
This will, on a first build, create a bin directory and within it a folder with the name in the format of wasmnoise-major-minor-patch-build
(e.g. wasmnoise-0.0.0.b158
). Within this folder will be a number of build files:
.bc Files:
WasmNoise.bc - bitcode produced by clang++ when compiling WasmNoise.cpp
WasmNoiseInterface.bc - bitcode produced by clang++ when compiling WasmNoiseInterface.cpp
wasmnoise-0.0.0.bc - bitcode produced by llvm-link when linking WasmNoise.bc,
WasmNoiceInterface.bc and memory.bc (located at
source/memory-bitcode)
.s file:
wasmnoise-0.0.0.s - produced by llc from wasmnoise-0.0.0.bc
.wat Files:
wasmnoise-0.0.0.wat - produced by s2wasm from wasmnoise-0.0.0.s
wasmnoise-0.0.0.cleanexports.wat - processed version of wasmnoise-0.0.0.wat
produced as part of a build step using
functions in removeextraexports.py
.wasm files:
wasmnoise-0.0.0.wasm - compiled wasm file produced by wat2wasm from
wasmnoise-0.0.0.cleanexports.wat
wasmnoise-0.0.0.opt.wasm - optimised wasm file produced by wasm-opt from
wasmnoise-0.0.0.wasm, removing unused functions