├── LICENSE ├── README.md ├── _config.yml ├── benchmark ├── Linux │ └── Makefile ├── MacOSX │ ├── Makefile │ └── bundle.sh ├── Makefile ├── README ├── Win32 │ ├── GL │ │ ├── glext.h │ │ └── glfw.h │ ├── Makefile │ └── libglfw.a └── common │ ├── Makefile │ ├── commonShader.frag │ ├── constant.frag │ ├── noisebench.c │ └── noisebench.vert ├── demo ├── Linux │ └── Makefile ├── MacOSX │ ├── Makefile │ └── bundle.sh ├── Makefile ├── README ├── Win32 │ ├── GL │ │ ├── glext.h │ │ └── glfw.h │ ├── Makefile │ └── libglfw.a └── common │ ├── Makefile │ ├── noisedemo.c │ ├── noisedemo.vert │ └── noisedemoMain.frag ├── src ├── README ├── cellular2D.glsl ├── cellular2x2.glsl ├── cellular2x2x2.glsl ├── cellular3D.glsl ├── classicnoise2D.glsl ├── classicnoise3D.glsl ├── classicnoise4D.glsl ├── noise2D.glsl ├── noise3D.glsl ├── noise3Dgrad.glsl ├── noise4D.glsl └── psrdnoise2D.glsl └── webdemo ├── cellular.html ├── index.html ├── noisedemo.js ├── periodic.html └── style.css /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2011 by Ashima Arts (Simplex noise) 2 | Copyright (C) 2011-2016 by Stefan Gustavson (Classic noise and others) 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Noise for GLSL 1.20 2 | 3 | Note that newer, faster and more versatile versions of 2-D and 3-D simplex noise were published in 2022. They can be found on https://github.com/stegu/psrdnoise/. This repository is still relevant, though, because it has 4-D noise, classic Perlin noise and Worley noise, neither of which are in the new repository. 4 | 5 | Many other noise implementations make heavy use of a texture lookup table and are texture bandwidth limited. The noise functions in this library, however, are completely self contained with no dependency on external data. While not quite as fast as texture-based implementations on typical current desktop GPUs, they are more scalable to massive parallelism and much more convenient to use, and 6 | they can make good use of unused ALU resources when run concurrently with a typical texture-intensive rendering. 7 | 8 | 2016-05-13: Ashima Arts is now defunct as a company, so I cloned this repository from ashima/webgl-noise to here. 9 | 10 | This repository contains GLSL source code for Perlin noise in 2D, 3D and 4D, both the modern simplex versions and the classic versions, including periodic noise similar to the `pnoise()` function in RenderMan SL. The functions have very good performance and no dependencies on external data. The code is open source, licensed under the terms of the OSI-approved and very permissive MIT license. For licensing details, please refer to the LICENSE file in the repository. 11 | 12 | * Simplex noise functions are (C) Ashima Arts and Stefan Gustavson 13 | * Classic noise functions are (C) Stefan Gustavson 14 | * Cellular ("Worley") noise functions are (C) Stefan Gustavson 15 | * The "psrdnoise" functions are (C) Stefan Gustavson 16 | 17 | The simplex noise functions follow Ken Perlin's original idea, more clearly explained in Stefan Gustavson's paper "Simplex noise demystified" https://itn-web.it.liu.se/~stegu76/simplexnoise/simplexnoise.pdf but without using any uniform arrays or texture lookups. 18 | 19 | A scientific paper about this was accepted for publication in JGT, (Journal of Graphics Tools), and after a long delay it finally appeared in print in June 2012: http://dx.doi.org/10.1080/2151237X.2012.649621. You are also welcome to read our preprint on https://itn-web.it.liu.se/~stegu76/jgt2012/, which is not locked up behind a paywall. 20 | 21 | You can of course use the functions without reading any part of the article. They require no setup or external data, just the GLSL source provided here, and they should work on any current OpenGL platform, including OpenGL 2.1, OpenGL 3.x and 4.x, OpenGL ES 2.x and WebGL 1.0. They will also work in limited vertex shader environments where texture lookup is not available. In WebGL and OpenGL ES, you will need to use high precision (`precision highp float`) for any of the functions to work. 22 | 23 | **_NOTE: You don't need a super fast GPU to use these functions. They are useful even on low end hardware, old hardware and embedded OpenGL ES hardware with low performance. Support for "highp" precision is required, though._** 24 | ## Live demo! 25 | 26 | A WebGL live demo of many of the functions provided are here: https://stegu.github.io/webgl-noise/webdemo/ 27 | 28 | ## Dead demo 29 | 30 | The repository also contains an old and, sadly, long outdated and abandoned C code for a cross-platform benchmark and a demo. To compile and run these programs, you need a desktop OS like Linux, Windows, MacOSX or some flavor of Unix with OpenGL support, and the GLFW library (http://glfw.sourceforge.net). Makefiles are provided for Linux, Windows and MacOS X. The demo is many years old and might be tricky to compile because it uses GLFW 2.x and old school OpenGL 2.1 calls (because that's what MacOS X required back in 2011), and I would advise against resurrecting the demo and benchmarking code. The CPU code is old and stale. However, the GLSL noise functions as such have aged well, and they are perfectly useful even in OpenGL 4.x, not only in WebGL. 31 | 32 | ## List of functions 33 | 34 | The GLSL source files and the noise functions that were originally published here were: 35 | 36 | * **noise2D.glsl** - 2D simplex noise `float snoise(vec2 x)`. Very fast, very compact code. 37 | 38 | * **noise3D.glsl** - 3D simplex noise `float snoise(vec3 x)`. Fast, compact code. 39 | 40 | * **noise4D.glsl** - 4D simplex noise `float snoise(vec4 x)`. Reasonably fast, reasonably compact code. 41 | 42 | * **classicnoise2D.glsl** - 2D classic Perlin noise `float cnoise(vec2 x)`, and a periodic variant `float pnoise(vec2 x, vec2 period)`. Fast and compact code, only slightly slower than 2D simplex noise. 43 | 44 | * **classicnoise3D.glsl** - 3D classic Perlin noise `float cnoise(vec3 x)`, and a periodic variant `float pnoise(vec3 x, vec3 period)`. Reasonably fast but not very compact code. Not quite as fast as 3D simplex noise. 45 | 46 | * **classicnoise4D.glsl** - 4D classic Perlin noise `float cnoise(vec4 x)`, and a periodic variant `float pnoise(vec4 x, vec4 period)`. Only about half as fast as 4D simplex noise, and rather bloated code, but still useful. 47 | 48 | The versions here are further optimized compared to the versions in the published JGT paper. Not by a lot, but they are somewhat faster still. 49 | 50 | All the noise functions return values in the range -1 to 1, with a more or less bell-shaped distribution around a zero mean. 51 | 52 | ## N-D return types 53 | 54 | All classic and simplex noise functions above return a single float. For the equivalents of the GLSL native functions `noise2()`, `noise3()`and `noise4()` that are still unimplemented on every relevant platform, you need to call these noise functions several times with different constant offsets for the arguments, e.g. `vec3(snoise(P), snoise(P+17.0), snoise(P-43.0))`. People have different opinions on whether these offsets should be integers for the classic noise functions to match the spacing of the zeroes, so we have left that for you to decide for yourself. For most applications, the exact offsets don't really matter as long as they are not too small or too close to the noise lattice period (289 in our implementation). 55 | 56 | # Other noise implementations 57 | 58 | The motivation for these functions not using any textures or arrays is ease of use, self-sufficiency and scalability for massively parallel execution. Noise is seldom used by itself, and these functions can make use of the often untapped ALU resources when run concurrently with traditional texture-intensive real time rendering tasks. However, if you are generating noise by itself and using a lot of it, the texture-intensive noise implementations this work was based on are still up to twice as fast on current generation desktop GPU hardware with lots of texture units and smart texture caching. You can find the original release of the old noise code on https://itn-web.it.liu.se/~stegu76/simplexnoise/GLSL-noise.zip (Windows binary, Windows-dependent source code using legacy OpenGL). A cross platform benchmark comparing it to this new version is on https://itn-web.it.liu.se/~stegu76/simplexnoise/GLSL-noise-vs-noise.zip. For the convenience of Windows users, a version with a precompiled Windows binary is in https://itn-web.it.liu.se/~stegu76/simplexnoise/GLSL-noise-vs-noise-Win32.zip. Note that the demo is more than a decade old and uses long deprecated OpenGL functions on the CPU side. The GPU code is still useful, though. 59 | 60 | # Cellular (Worley) noise in GLSL 61 | 62 | A few GLSL 1.20 compatible implementations of cellular noise ("Worley noise") are available in this repository, and also on https://itn-web.it.liu.se/~stegu76/GLSL-cellular/. It is a straightforward but non-trivial implementation of previous ideas from software procedural shading, using the ideas for pseudo-random permutation from the computational Perlin noise originally presented here, with some optional shortcuts for situations where speed is more important than accuracy. 63 | 64 | # Tiling 2-D simplex noise with analytic derivatives and rotating gradients 65 | 66 | In May 2016, another newly written variation on 2-D simplex noise was uploaded here, with eight separate but similar functions: 67 | 68 | * **psrdnoise2D.glsl** 69 | 70 | `vec3 psrdnoise(vec2 pos, vec2 per, float rot)` 71 | 72 | `vec3 psdnoise(vec2 pos, vec2 per)` 73 | 74 | `float psrnoise(vec2 pos, vec2 per, float rot)` 75 | 76 | `float psnoise(vec2 pos, vec2 per)` 77 | 78 | `vec3 srdnoise(vec2 pos, float rot)` 79 | 80 | `vec3 sdnoise(vec2 pos)` 81 | 82 | `float srnoise(vec2 pos, float rot)` 83 | 84 | `float snoise(vec2 pos)` 85 | 86 | This version has a different, slightly stretched simplex grid which permits tiling in x and y, similarly to the periodic versions of classic noise. These functions also compute an analytical derivative of the noise function, which is useful for creating bump maps and normal maps, for texture domain distortion, and for tricks like "flow noise" and "curl noise". The animated rotation of the underlying gradients is a component of flow noise, as presented by Perlin and Neyret. For details, have a look at the source code. The comments should contain what you need to use these functions. 87 | 88 | # Flow noise 89 | 90 | "Flow noise" is a neat trick for 2-D noise, where you rotate the gradients at the grid points and displace later terms in a fractal sum by the accumulated gradients of previous terms. It's a cheat with no strong connection to physics, but it can create a visual impression of turbulent flow. The functions in "psrdnoise" can be used to create flow noise. 91 | 92 | Another, earlier GLSL 1.20 compatible implementation of "flow noise" using the original, non-tiling simplex grid is available as part of this demo: https://itn-web.it.liu.se/~stegu76/gpunoise/. It's undocumented, but the example and the original Siggraph publication below should be enough to use it: 93 | http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.141.5266&rep=rep1&type=pdf 94 | 95 | # Demos and Applications of webgl-noise 96 | 97 | * Our own [local demo](https://stegu.github.io/webgl-noise/webdemo/) 98 | * **[Altered Qualia](http://alteredqualia.com/)**'s Noise Shader Demo Pages: [flesh](http://alteredqualia.com/three/examples/webgl_shader_flesh.html), [slime](http://alteredqualia.com/three/examples/webgl_shader_slime.html), [copper](http://alteredqualia.com/three/examples/webgl_shader_copper.html), [mercury](http://alteredqualia.com/three/examples/webgl_shader_mercury.html), [gold](http://alteredqualia.com/three/examples/webgl_shader_gold.html), [stucco](http://alteredqualia.com/three/examples/webgl_shader_stucco.html), [amber](http://alteredqualia.com/three/examples/webgl_shader_amber.html), [sparks](http://alteredqualia.com/three/examples/webgl_shader_sparks.html) 99 | * Miaumiau Labs' [Curl Noise + Volume Shadow particles demonstration](http://www.miaumiau.cat/2011/08/curl-noise-volume-shadow-particles/) 100 | 101 | Do you have a WebGL application or demonstration that uses this noise library? Let us know and we will add it to this list. 102 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-minimal -------------------------------------------------------------------------------- /benchmark/Linux/Makefile: -------------------------------------------------------------------------------- 1 | SHADERS=noisebench.vert simplexnoise2D.frag simplexnoise3D.frag\ 2 | simplexnoise4D.frag classicnoise2D.frag classicnoise3D.frag\ 3 | classicnoise4D.frag constant.frag 4 | COMDIR=../common 5 | VPATH=$(COMDIR) 6 | EXECNAME=noisebench 7 | OUTPUTFILE=ashimanoise.log 8 | 9 | all: $(EXECNAME) links_done 10 | 11 | $(EXECNAME): noisebench.c 12 | gcc -I. -I/usr/X11/include $^ -lglfw -lGLU -lGL -o $@ 13 | 14 | links_done: $(SHADERS) 15 | ln -s $? . ; touch links_done 16 | 17 | clean: 18 | - rm $(EXECNAME) $(SHADERS) links_done $(OUTPUTFILE) 19 | 20 | run: 21 | ./$(EXECNAME) 22 | cat $(OUTPUTFILE) 23 | -------------------------------------------------------------------------------- /benchmark/MacOSX/Makefile: -------------------------------------------------------------------------------- 1 | EXECNAME=noisebench 2 | OUTPUTFILE=ashimanoise.log 3 | COMDIR=../common 4 | 5 | OBJS=noisebench.o 6 | SHADERS=noisebench.vert simplexnoise2D.frag simplexnoise3D.frag\ 7 | simplexnoise4D.frag classicnoise2D.frag classicnoise3D.frag\ 8 | classicnoise4D.frag constant.frag 9 | 10 | VPATH=$(COMDIR) 11 | CFLAGS=-I. -I/usr/X11/include 12 | LDFLAGS=-framework Cocoa -framework OpenGL -lglfw 13 | 14 | .PHONY: all clean run 15 | 16 | all: $(EXECNAME).app links_done 17 | 18 | links_done: $(SHADERS) 19 | ln -s $? . ; touch links_done 20 | 21 | $(EXECNAME).app: $(EXECNAME) 22 | ./bundle.sh $@ $^ ; chmod a-x $^ 23 | 24 | $(EXECNAME): $(OBJS) 25 | 26 | clean: 27 | - rm -r $(EXECNAME).app 28 | - rm $(EXECNAME) links_done $(OBJS) $(SHADERS) $(OUTPUTFILE) 29 | 30 | run: 31 | open -W ./$(EXECNAME).app 32 | cat $(OUTPUTFILE) 33 | -------------------------------------------------------------------------------- /benchmark/MacOSX/bundle.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Creates application bundles for use on Mac OS X. 4 | 5 | if [ -z "$1" ]; then 6 | echo "usage: `basename $0` BUNDLE-NAME exec-name" 7 | exit 1 8 | fi 9 | 10 | bundle_name="$1" 11 | exec_file="$2" 12 | exec_name=`basename $bundle_name .app` 13 | 14 | if [ ! -f $exec_file ]; then 15 | echo "Can't find $exec_file" 16 | exit 1 17 | fi 18 | 19 | if [ ! -d "${bundle_name}/Contents/MacOS" ]; then 20 | mkdir -p "${bundle_name}/Contents/MacOS" 21 | fi 22 | 23 | cp $exec_file "${bundle_name}/Contents/MacOS/" 24 | 25 | touch "${bundle_name}" 26 | 27 | if [ ! -d "${bundle_name}/Contents/Resources" ]; then 28 | mkdir -p "${bundle_name}/Contents/Resources" 29 | fi 30 | 31 | if [ ! -f "${bundle_name}/Contents/PkgInfo" ]; then 32 | echo -n "APPL????" > "${bundle_name}/Contents/PkgInfo" 33 | fi 34 | 35 | if [ ! -f "${bundle_name}/Contents/Info.plist" ]; then 36 | cat > "${bundle_name}/Contents/Info.plist" < 38 | 39 | 40 | 41 | CFBundleName ${exec_name} 42 | CFBundleExecutable ${exec_name} 43 | CFBundleIdentifier com.ashimaarts.${exec_name} 44 | CFBundleVersion 0.1 45 | 46 | CFBundlePackageType APPL 47 | CFBundleDevelopmentRegion English 48 | CFBundleSignature ???? 49 | CFBundleInfoDictionaryVersion 6.0 50 | 51 | 52 | EOF 53 | fi 54 | -------------------------------------------------------------------------------- /benchmark/Makefile: -------------------------------------------------------------------------------- 1 | WINMAKE = mingw32-make 2 | 3 | .PHONY: default clean Linux MacOSX Win32 clean-Win32 4 | 5 | default: 6 | @echo "Usage:" 7 | @echo "make [ Linux | MacOSX | Win32 | clean | clean-Win32]" 8 | 9 | clean: 10 | cd common ; make clean 11 | cd Linux ; make clean 12 | cd MacOSX ; make clean 13 | 14 | Linux: 15 | cd common ; make 16 | cd $@ ; make ; make run 17 | 18 | MacOSX: 19 | cd common ; make 20 | cd $@ ; make ; make run 21 | 22 | Win32: 23 | cd common && $(WINMAKE) 24 | cd $@ && $(WINMAKE) && $(WINMAKE) run 25 | 26 | clean-Win32: 27 | cd common && $(WINMAKE) clean 28 | cd Win32 && $(WINMAKE) clean 29 | -------------------------------------------------------------------------------- /benchmark/README: -------------------------------------------------------------------------------- 1 | This is a benchmark for the noise functions, but it was written in 2011 2 | to be compatible with MacOS X, which was still stuck at OpenGL 2.1 at the time. 3 | The code hasn't aged well. In addition to using legacy OpenGL 2.1, it uses 4 | the old version 2 of the GLFW library, which is still available but no longer 5 | maintained. Trying to resurrect this code might prove painful. 6 | In any case, this is not code you should learn from or build upon. 7 | -------------------------------------------------------------------------------- /benchmark/Win32/GL/glfw.h: -------------------------------------------------------------------------------- 1 | //======================================================================== 2 | // GLFW - An OpenGL framework 3 | // File: glfw.h 4 | // API version: 2.6 5 | // WWW: http://glfw.sourceforge.net 6 | //------------------------------------------------------------------------ 7 | // Copyright (c) 2002-2006 Camilla Berglund 8 | // 9 | // This software is provided 'as-is', without any express or implied 10 | // warranty. In no event will the authors be held liable for any damages 11 | // arising from the use of this software. 12 | // 13 | // Permission is granted to anyone to use this software for any purpose, 14 | // including commercial applications, and to alter it and redistribute it 15 | // freely, subject to the following restrictions: 16 | // 17 | // 1. The origin of this software must not be misrepresented; you must not 18 | // claim that you wrote the original software. If you use this software 19 | // in a product, an acknowledgment in the product documentation would 20 | // be appreciated but is not required. 21 | // 22 | // 2. Altered source versions must be plainly marked as such, and must not 23 | // be misrepresented as being the original software. 24 | // 25 | // 3. This notice may not be removed or altered from any source 26 | // distribution. 27 | // 28 | //======================================================================== 29 | 30 | #ifndef __glfw_h_ 31 | #define __glfw_h_ 32 | 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | 38 | //======================================================================== 39 | // Global definitions 40 | //======================================================================== 41 | 42 | // We need a NULL pointer from time to time 43 | #ifndef NULL 44 | #ifdef __cplusplus 45 | #define NULL 0 46 | #else 47 | #define NULL ((void *)0) 48 | #endif 49 | #endif // NULL 50 | 51 | 52 | // ------------------- BEGIN SYSTEM/COMPILER SPECIFIC -------------------- 53 | 54 | // Please report any probles that you find with your compiler, which may 55 | // be solved in this section! There are several compilers that I have not 56 | // been able to test this file with yet. 57 | 58 | // First: If we are we on Windows, we want a single define for it (_WIN32) 59 | // (Note: For Cygwin the compiler flag -mwin32 should be used, but to 60 | // make sure that things run smoothly for Cygwin users, we add __CYGWIN__ 61 | // to the list of "valid Win32 identifiers", which removes the need for 62 | // -mwin32) 63 | #if !defined(_WIN32) && (defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__)) 64 | #define _WIN32 65 | #endif // _WIN32 66 | 67 | // In order for extension support to be portable, we need to define an 68 | // OpenGL function call method. We use the keyword APIENTRY, which is 69 | // defined for Win32. (Note: Windows also needs this for ) 70 | #ifndef APIENTRY 71 | #ifdef _WIN32 72 | #define APIENTRY __stdcall 73 | #else 74 | #define APIENTRY 75 | #endif 76 | #define GL_APIENTRY_DEFINED 77 | #endif // APIENTRY 78 | 79 | 80 | // The following three defines are here solely to make some Windows-based 81 | // files happy. Theoretically we could include , but 82 | // it has the major drawback of severely polluting our namespace. 83 | 84 | // Under Windows, we need WINGDIAPI defined 85 | #if !defined(WINGDIAPI) && defined(_WIN32) 86 | #if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__POCC__) 87 | // Microsoft Visual C++, Borland C++ Builder and Pelles C 88 | #define WINGDIAPI __declspec(dllimport) 89 | #elif defined(__LCC__) 90 | // LCC-Win32 91 | #define WINGDIAPI __stdcall 92 | #else 93 | // Others (e.g. MinGW, Cygwin) 94 | #define WINGDIAPI extern 95 | #endif 96 | #define GL_WINGDIAPI_DEFINED 97 | #endif // WINGDIAPI 98 | 99 | // Some files also need CALLBACK defined 100 | #if !defined(CALLBACK) && defined(_WIN32) 101 | #if defined(_MSC_VER) 102 | // Microsoft Visual C++ 103 | #if (defined(_M_MRX000) || defined(_M_IX86) || defined(_M_ALPHA) || defined(_M_PPC)) && !defined(MIDL_PASS) 104 | #define CALLBACK __stdcall 105 | #else 106 | #define CALLBACK 107 | #endif 108 | #else 109 | // Other Windows compilers 110 | #define CALLBACK __stdcall 111 | #endif 112 | #define GLU_CALLBACK_DEFINED 113 | #endif // CALLBACK 114 | 115 | // Microsoft Visual C++, Borland C++ and Pelles C needs wchar_t 116 | #if defined(_WIN32) && (defined(_MSC_VER) || defined(__BORLANDC__) || defined(__POCC__)) && !defined(_WCHAR_T_DEFINED) 117 | typedef unsigned short wchar_t; 118 | #define _WCHAR_T_DEFINED 119 | #endif // _WCHAR_T_DEFINED 120 | 121 | 122 | // ---------------- GLFW related system specific defines ----------------- 123 | 124 | #if defined(_WIN32) && defined(GLFW_BUILD_DLL) 125 | 126 | // We are building a Win32 DLL 127 | #define GLFWAPI __declspec(dllexport) 128 | #define GLFWAPIENTRY __stdcall 129 | #define GLFWCALL __stdcall 130 | 131 | #elif defined(_WIN32) && defined(GLFW_DLL) 132 | 133 | // We are calling a Win32 DLL 134 | #if defined(__LCC__) 135 | #define GLFWAPI extern 136 | #else 137 | #define GLFWAPI __declspec(dllimport) 138 | #endif 139 | #define GLFWAPIENTRY __stdcall 140 | #define GLFWCALL __stdcall 141 | 142 | #else 143 | 144 | // We are either building/calling a static lib or we are non-win32 145 | #define GLFWAPIENTRY 146 | #define GLFWAPI 147 | #define GLFWCALL 148 | 149 | #endif 150 | 151 | // -------------------- END SYSTEM/COMPILER SPECIFIC --------------------- 152 | 153 | // Include standard OpenGL headers: GLFW uses GL_FALSE/GL_TRUE, and it is 154 | // convenient for the user to only have to include . This also 155 | // solves the problem with Windows and needing some 156 | // special defines which normally requires the user to include 157 | // (which is not a nice solution for portable programs). 158 | #if defined(__APPLE_CC__) 159 | #include 160 | #include 161 | #else 162 | #include 163 | #include 164 | #endif 165 | 166 | 167 | //======================================================================== 168 | // GLFW version 169 | //======================================================================== 170 | 171 | #define GLFW_VERSION_MAJOR 2 172 | #define GLFW_VERSION_MINOR 6 173 | #define GLFW_VERSION_REVISION 0 174 | 175 | 176 | //======================================================================== 177 | // Input handling definitions 178 | //======================================================================== 179 | 180 | // Key and button state/action definitions 181 | #define GLFW_RELEASE 0 182 | #define GLFW_PRESS 1 183 | 184 | // Keyboard key definitions: 8-bit ISO-8859-1 (Latin 1) encoding is used 185 | // for printable keys (such as A-Z, 0-9 etc), and values above 256 186 | // represent special (non-printable) keys (e.g. F1, Page Up etc). 187 | #define GLFW_KEY_UNKNOWN -1 188 | #define GLFW_KEY_SPACE 32 189 | #define GLFW_KEY_SPECIAL 256 190 | #define GLFW_KEY_ESC (GLFW_KEY_SPECIAL+1) 191 | #define GLFW_KEY_F1 (GLFW_KEY_SPECIAL+2) 192 | #define GLFW_KEY_F2 (GLFW_KEY_SPECIAL+3) 193 | #define GLFW_KEY_F3 (GLFW_KEY_SPECIAL+4) 194 | #define GLFW_KEY_F4 (GLFW_KEY_SPECIAL+5) 195 | #define GLFW_KEY_F5 (GLFW_KEY_SPECIAL+6) 196 | #define GLFW_KEY_F6 (GLFW_KEY_SPECIAL+7) 197 | #define GLFW_KEY_F7 (GLFW_KEY_SPECIAL+8) 198 | #define GLFW_KEY_F8 (GLFW_KEY_SPECIAL+9) 199 | #define GLFW_KEY_F9 (GLFW_KEY_SPECIAL+10) 200 | #define GLFW_KEY_F10 (GLFW_KEY_SPECIAL+11) 201 | #define GLFW_KEY_F11 (GLFW_KEY_SPECIAL+12) 202 | #define GLFW_KEY_F12 (GLFW_KEY_SPECIAL+13) 203 | #define GLFW_KEY_F13 (GLFW_KEY_SPECIAL+14) 204 | #define GLFW_KEY_F14 (GLFW_KEY_SPECIAL+15) 205 | #define GLFW_KEY_F15 (GLFW_KEY_SPECIAL+16) 206 | #define GLFW_KEY_F16 (GLFW_KEY_SPECIAL+17) 207 | #define GLFW_KEY_F17 (GLFW_KEY_SPECIAL+18) 208 | #define GLFW_KEY_F18 (GLFW_KEY_SPECIAL+19) 209 | #define GLFW_KEY_F19 (GLFW_KEY_SPECIAL+20) 210 | #define GLFW_KEY_F20 (GLFW_KEY_SPECIAL+21) 211 | #define GLFW_KEY_F21 (GLFW_KEY_SPECIAL+22) 212 | #define GLFW_KEY_F22 (GLFW_KEY_SPECIAL+23) 213 | #define GLFW_KEY_F23 (GLFW_KEY_SPECIAL+24) 214 | #define GLFW_KEY_F24 (GLFW_KEY_SPECIAL+25) 215 | #define GLFW_KEY_F25 (GLFW_KEY_SPECIAL+26) 216 | #define GLFW_KEY_UP (GLFW_KEY_SPECIAL+27) 217 | #define GLFW_KEY_DOWN (GLFW_KEY_SPECIAL+28) 218 | #define GLFW_KEY_LEFT (GLFW_KEY_SPECIAL+29) 219 | #define GLFW_KEY_RIGHT (GLFW_KEY_SPECIAL+30) 220 | #define GLFW_KEY_LSHIFT (GLFW_KEY_SPECIAL+31) 221 | #define GLFW_KEY_RSHIFT (GLFW_KEY_SPECIAL+32) 222 | #define GLFW_KEY_LCTRL (GLFW_KEY_SPECIAL+33) 223 | #define GLFW_KEY_RCTRL (GLFW_KEY_SPECIAL+34) 224 | #define GLFW_KEY_LALT (GLFW_KEY_SPECIAL+35) 225 | #define GLFW_KEY_RALT (GLFW_KEY_SPECIAL+36) 226 | #define GLFW_KEY_TAB (GLFW_KEY_SPECIAL+37) 227 | #define GLFW_KEY_ENTER (GLFW_KEY_SPECIAL+38) 228 | #define GLFW_KEY_BACKSPACE (GLFW_KEY_SPECIAL+39) 229 | #define GLFW_KEY_INSERT (GLFW_KEY_SPECIAL+40) 230 | #define GLFW_KEY_DEL (GLFW_KEY_SPECIAL+41) 231 | #define GLFW_KEY_PAGEUP (GLFW_KEY_SPECIAL+42) 232 | #define GLFW_KEY_PAGEDOWN (GLFW_KEY_SPECIAL+43) 233 | #define GLFW_KEY_HOME (GLFW_KEY_SPECIAL+44) 234 | #define GLFW_KEY_END (GLFW_KEY_SPECIAL+45) 235 | #define GLFW_KEY_KP_0 (GLFW_KEY_SPECIAL+46) 236 | #define GLFW_KEY_KP_1 (GLFW_KEY_SPECIAL+47) 237 | #define GLFW_KEY_KP_2 (GLFW_KEY_SPECIAL+48) 238 | #define GLFW_KEY_KP_3 (GLFW_KEY_SPECIAL+49) 239 | #define GLFW_KEY_KP_4 (GLFW_KEY_SPECIAL+50) 240 | #define GLFW_KEY_KP_5 (GLFW_KEY_SPECIAL+51) 241 | #define GLFW_KEY_KP_6 (GLFW_KEY_SPECIAL+52) 242 | #define GLFW_KEY_KP_7 (GLFW_KEY_SPECIAL+53) 243 | #define GLFW_KEY_KP_8 (GLFW_KEY_SPECIAL+54) 244 | #define GLFW_KEY_KP_9 (GLFW_KEY_SPECIAL+55) 245 | #define GLFW_KEY_KP_DIVIDE (GLFW_KEY_SPECIAL+56) 246 | #define GLFW_KEY_KP_MULTIPLY (GLFW_KEY_SPECIAL+57) 247 | #define GLFW_KEY_KP_SUBTRACT (GLFW_KEY_SPECIAL+58) 248 | #define GLFW_KEY_KP_ADD (GLFW_KEY_SPECIAL+59) 249 | #define GLFW_KEY_KP_DECIMAL (GLFW_KEY_SPECIAL+60) 250 | #define GLFW_KEY_KP_EQUAL (GLFW_KEY_SPECIAL+61) 251 | #define GLFW_KEY_KP_ENTER (GLFW_KEY_SPECIAL+62) 252 | #define GLFW_KEY_LAST GLFW_KEY_KP_ENTER 253 | 254 | // Mouse button definitions 255 | #define GLFW_MOUSE_BUTTON_1 0 256 | #define GLFW_MOUSE_BUTTON_2 1 257 | #define GLFW_MOUSE_BUTTON_3 2 258 | #define GLFW_MOUSE_BUTTON_4 3 259 | #define GLFW_MOUSE_BUTTON_5 4 260 | #define GLFW_MOUSE_BUTTON_6 5 261 | #define GLFW_MOUSE_BUTTON_7 6 262 | #define GLFW_MOUSE_BUTTON_8 7 263 | #define GLFW_MOUSE_BUTTON_LAST GLFW_MOUSE_BUTTON_8 264 | 265 | // Mouse button aliases 266 | #define GLFW_MOUSE_BUTTON_LEFT GLFW_MOUSE_BUTTON_1 267 | #define GLFW_MOUSE_BUTTON_RIGHT GLFW_MOUSE_BUTTON_2 268 | #define GLFW_MOUSE_BUTTON_MIDDLE GLFW_MOUSE_BUTTON_3 269 | 270 | 271 | // Joystick identifiers 272 | #define GLFW_JOYSTICK_1 0 273 | #define GLFW_JOYSTICK_2 1 274 | #define GLFW_JOYSTICK_3 2 275 | #define GLFW_JOYSTICK_4 3 276 | #define GLFW_JOYSTICK_5 4 277 | #define GLFW_JOYSTICK_6 5 278 | #define GLFW_JOYSTICK_7 6 279 | #define GLFW_JOYSTICK_8 7 280 | #define GLFW_JOYSTICK_9 8 281 | #define GLFW_JOYSTICK_10 9 282 | #define GLFW_JOYSTICK_11 10 283 | #define GLFW_JOYSTICK_12 11 284 | #define GLFW_JOYSTICK_13 12 285 | #define GLFW_JOYSTICK_14 13 286 | #define GLFW_JOYSTICK_15 14 287 | #define GLFW_JOYSTICK_16 15 288 | #define GLFW_JOYSTICK_LAST GLFW_JOYSTICK_16 289 | 290 | 291 | //======================================================================== 292 | // Other definitions 293 | //======================================================================== 294 | 295 | // glfwOpenWindow modes 296 | #define GLFW_WINDOW 0x00010001 297 | #define GLFW_FULLSCREEN 0x00010002 298 | 299 | // glfwGetWindowParam tokens 300 | #define GLFW_OPENED 0x00020001 301 | #define GLFW_ACTIVE 0x00020002 302 | #define GLFW_ICONIFIED 0x00020003 303 | #define GLFW_ACCELERATED 0x00020004 304 | #define GLFW_RED_BITS 0x00020005 305 | #define GLFW_GREEN_BITS 0x00020006 306 | #define GLFW_BLUE_BITS 0x00020007 307 | #define GLFW_ALPHA_BITS 0x00020008 308 | #define GLFW_DEPTH_BITS 0x00020009 309 | #define GLFW_STENCIL_BITS 0x0002000A 310 | 311 | // The following constants are used for both glfwGetWindowParam 312 | // and glfwOpenWindowHint 313 | #define GLFW_REFRESH_RATE 0x0002000B 314 | #define GLFW_ACCUM_RED_BITS 0x0002000C 315 | #define GLFW_ACCUM_GREEN_BITS 0x0002000D 316 | #define GLFW_ACCUM_BLUE_BITS 0x0002000E 317 | #define GLFW_ACCUM_ALPHA_BITS 0x0002000F 318 | #define GLFW_AUX_BUFFERS 0x00020010 319 | #define GLFW_STEREO 0x00020011 320 | #define GLFW_WINDOW_NO_RESIZE 0x00020012 321 | #define GLFW_FSAA_SAMPLES 0x00020013 322 | 323 | // glfwEnable/glfwDisable tokens 324 | #define GLFW_MOUSE_CURSOR 0x00030001 325 | #define GLFW_STICKY_KEYS 0x00030002 326 | #define GLFW_STICKY_MOUSE_BUTTONS 0x00030003 327 | #define GLFW_SYSTEM_KEYS 0x00030004 328 | #define GLFW_KEY_REPEAT 0x00030005 329 | #define GLFW_AUTO_POLL_EVENTS 0x00030006 330 | 331 | // glfwWaitThread wait modes 332 | #define GLFW_WAIT 0x00040001 333 | #define GLFW_NOWAIT 0x00040002 334 | 335 | // glfwGetJoystickParam tokens 336 | #define GLFW_PRESENT 0x00050001 337 | #define GLFW_AXES 0x00050002 338 | #define GLFW_BUTTONS 0x00050003 339 | 340 | // glfwReadImage/glfwLoadTexture2D flags 341 | #define GLFW_NO_RESCALE_BIT 0x00000001 // Only for glfwReadImage 342 | #define GLFW_ORIGIN_UL_BIT 0x00000002 343 | #define GLFW_BUILD_MIPMAPS_BIT 0x00000004 // Only for glfwLoadTexture2D 344 | #define GLFW_ALPHA_MAP_BIT 0x00000008 345 | 346 | // Time spans longer than this (seconds) are considered to be infinity 347 | #define GLFW_INFINITY 100000.0 348 | 349 | 350 | //======================================================================== 351 | // Typedefs 352 | //======================================================================== 353 | 354 | // The video mode structure used by glfwGetVideoModes() 355 | typedef struct { 356 | int Width, Height; 357 | int RedBits, BlueBits, GreenBits; 358 | } GLFWvidmode; 359 | 360 | // Image/texture information 361 | typedef struct { 362 | int Width, Height; 363 | int Format; 364 | int BytesPerPixel; 365 | unsigned char *Data; 366 | } GLFWimage; 367 | 368 | // Thread ID 369 | typedef int GLFWthread; 370 | 371 | // Mutex object 372 | typedef void * GLFWmutex; 373 | 374 | // Condition variable object 375 | typedef void * GLFWcond; 376 | 377 | // Function pointer types 378 | typedef void (GLFWCALL * GLFWwindowsizefun)(int,int); 379 | typedef int (GLFWCALL * GLFWwindowclosefun)(void); 380 | typedef void (GLFWCALL * GLFWwindowrefreshfun)(void); 381 | typedef void (GLFWCALL * GLFWmousebuttonfun)(int,int); 382 | typedef void (GLFWCALL * GLFWmouseposfun)(int,int); 383 | typedef void (GLFWCALL * GLFWmousewheelfun)(int); 384 | typedef void (GLFWCALL * GLFWkeyfun)(int,int); 385 | typedef void (GLFWCALL * GLFWcharfun)(int,int); 386 | typedef void (GLFWCALL * GLFWthreadfun)(void *); 387 | 388 | 389 | //======================================================================== 390 | // Prototypes 391 | //======================================================================== 392 | 393 | /*! @file glfw.h 394 | */ 395 | // GLFW initialization, termination and version querying 396 | /*! @fn glfwInit 397 | */ 398 | GLFWAPI int GLFWAPIENTRY glfwInit( void ); 399 | GLFWAPI void GLFWAPIENTRY glfwTerminate( void ); 400 | GLFWAPI void GLFWAPIENTRY glfwGetVersion( int *major, int *minor, int *rev ); 401 | 402 | // Window handling 403 | GLFWAPI int GLFWAPIENTRY glfwOpenWindow( int width, int height, int redbits, int greenbits, int bluebits, int alphabits, int depthbits, int stencilbits, int mode ); 404 | GLFWAPI void GLFWAPIENTRY glfwOpenWindowHint( int target, int hint ); 405 | GLFWAPI void GLFWAPIENTRY glfwCloseWindow( void ); 406 | GLFWAPI void GLFWAPIENTRY glfwSetWindowTitle( const char *title ); 407 | GLFWAPI void GLFWAPIENTRY glfwGetWindowSize( int *width, int *height ); 408 | GLFWAPI void GLFWAPIENTRY glfwSetWindowSize( int width, int height ); 409 | GLFWAPI void GLFWAPIENTRY glfwSetWindowPos( int x, int y ); 410 | GLFWAPI void GLFWAPIENTRY glfwIconifyWindow( void ); 411 | GLFWAPI void GLFWAPIENTRY glfwRestoreWindow( void ); 412 | GLFWAPI void GLFWAPIENTRY glfwSwapBuffers( void ); 413 | GLFWAPI void GLFWAPIENTRY glfwSwapInterval( int interval ); 414 | GLFWAPI int GLFWAPIENTRY glfwGetWindowParam( int param ); 415 | GLFWAPI void GLFWAPIENTRY glfwSetWindowSizeCallback( GLFWwindowsizefun cbfun ); 416 | GLFWAPI void GLFWAPIENTRY glfwSetWindowCloseCallback( GLFWwindowclosefun cbfun ); 417 | GLFWAPI void GLFWAPIENTRY glfwSetWindowRefreshCallback( GLFWwindowrefreshfun cbfun ); 418 | 419 | // Video mode functions 420 | GLFWAPI int GLFWAPIENTRY glfwGetVideoModes( GLFWvidmode *list, int maxcount ); 421 | GLFWAPI void GLFWAPIENTRY glfwGetDesktopMode( GLFWvidmode *mode ); 422 | 423 | // Input handling 424 | GLFWAPI void GLFWAPIENTRY glfwPollEvents( void ); 425 | GLFWAPI void GLFWAPIENTRY glfwWaitEvents( void ); 426 | GLFWAPI int GLFWAPIENTRY glfwGetKey( int key ); 427 | GLFWAPI int GLFWAPIENTRY glfwGetMouseButton( int button ); 428 | GLFWAPI void GLFWAPIENTRY glfwGetMousePos( int *xpos, int *ypos ); 429 | GLFWAPI void GLFWAPIENTRY glfwSetMousePos( int xpos, int ypos ); 430 | GLFWAPI int GLFWAPIENTRY glfwGetMouseWheel( void ); 431 | GLFWAPI void GLFWAPIENTRY glfwSetMouseWheel( int pos ); 432 | GLFWAPI void GLFWAPIENTRY glfwSetKeyCallback( GLFWkeyfun cbfun ); 433 | GLFWAPI void GLFWAPIENTRY glfwSetCharCallback( GLFWcharfun cbfun ); 434 | GLFWAPI void GLFWAPIENTRY glfwSetMouseButtonCallback( GLFWmousebuttonfun cbfun ); 435 | GLFWAPI void GLFWAPIENTRY glfwSetMousePosCallback( GLFWmouseposfun cbfun ); 436 | GLFWAPI void GLFWAPIENTRY glfwSetMouseWheelCallback( GLFWmousewheelfun cbfun ); 437 | 438 | // Joystick input 439 | GLFWAPI int GLFWAPIENTRY glfwGetJoystickParam( int joy, int param ); 440 | GLFWAPI int GLFWAPIENTRY glfwGetJoystickPos( int joy, float *pos, int numaxes ); 441 | GLFWAPI int GLFWAPIENTRY glfwGetJoystickButtons( int joy, unsigned char *buttons, int numbuttons ); 442 | 443 | // Time 444 | GLFWAPI double GLFWAPIENTRY glfwGetTime( void ); 445 | GLFWAPI void GLFWAPIENTRY glfwSetTime( double time ); 446 | GLFWAPI void GLFWAPIENTRY glfwSleep( double time ); 447 | 448 | // Extension support 449 | GLFWAPI int GLFWAPIENTRY glfwExtensionSupported( const char *extension ); 450 | GLFWAPI void* GLFWAPIENTRY glfwGetProcAddress( const char *procname ); 451 | GLFWAPI void GLFWAPIENTRY glfwGetGLVersion( int *major, int *minor, int *rev ); 452 | 453 | // Threading support 454 | GLFWAPI GLFWthread GLFWAPIENTRY glfwCreateThread( GLFWthreadfun fun, void *arg ); 455 | GLFWAPI void GLFWAPIENTRY glfwDestroyThread( GLFWthread ID ); 456 | GLFWAPI int GLFWAPIENTRY glfwWaitThread( GLFWthread ID, int waitmode ); 457 | GLFWAPI GLFWthread GLFWAPIENTRY glfwGetThreadID( void ); 458 | GLFWAPI GLFWmutex GLFWAPIENTRY glfwCreateMutex( void ); 459 | GLFWAPI void GLFWAPIENTRY glfwDestroyMutex( GLFWmutex mutex ); 460 | GLFWAPI void GLFWAPIENTRY glfwLockMutex( GLFWmutex mutex ); 461 | GLFWAPI void GLFWAPIENTRY glfwUnlockMutex( GLFWmutex mutex ); 462 | GLFWAPI GLFWcond GLFWAPIENTRY glfwCreateCond( void ); 463 | GLFWAPI void GLFWAPIENTRY glfwDestroyCond( GLFWcond cond ); 464 | GLFWAPI void GLFWAPIENTRY glfwWaitCond( GLFWcond cond, GLFWmutex mutex, double timeout ); 465 | GLFWAPI void GLFWAPIENTRY glfwSignalCond( GLFWcond cond ); 466 | GLFWAPI void GLFWAPIENTRY glfwBroadcastCond( GLFWcond cond ); 467 | GLFWAPI int GLFWAPIENTRY glfwGetNumberOfProcessors( void ); 468 | 469 | // Enable/disable functions 470 | GLFWAPI void GLFWAPIENTRY glfwEnable( int token ); 471 | GLFWAPI void GLFWAPIENTRY glfwDisable( int token ); 472 | 473 | // Image/texture I/O support 474 | GLFWAPI int GLFWAPIENTRY glfwReadImage( const char *name, GLFWimage *img, int flags ); 475 | GLFWAPI int GLFWAPIENTRY glfwReadMemoryImage( const void *data, long size, GLFWimage *img, int flags ); 476 | GLFWAPI void GLFWAPIENTRY glfwFreeImage( GLFWimage *img ); 477 | GLFWAPI int GLFWAPIENTRY glfwLoadTexture2D( const char *name, int flags ); 478 | GLFWAPI int GLFWAPIENTRY glfwLoadMemoryTexture2D( const void *data, long size, int flags ); 479 | GLFWAPI int GLFWAPIENTRY glfwLoadTextureImage2D( GLFWimage *img, int flags ); 480 | 481 | 482 | #ifdef __cplusplus 483 | } 484 | #endif 485 | 486 | #endif // __glfw_h_ 487 | -------------------------------------------------------------------------------- /benchmark/Win32/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for bare-bones Mingw32 from a Windows command shell (no bash, no Cygwin) 2 | MINGW32 = C:/Dev-Cpp 3 | #MINGW32 = C:/mingw 4 | CC = gcc.exe 5 | SRC = noisebench.c 6 | SHADERS = noisebench.vert constant.frag simplexnoise2D.frag simplexnoise3D.frag\ 7 | simplexnoise4D.frag classicnoise2D.frag classicnoise3D.frag classicnoise4D.frag 8 | OBJ = noisebench.o 9 | LINKOBJ = noisebench.o 10 | LIBS = -L$(MINGW32)/lib -mwindows -lglfw -lopengl32 -lglu32 -mconsole -g3 11 | INCS = -I. -I$(MINGW32)/include 12 | CFLAGS = $(INCS) -Wall -O3 -ffast-math -g3 13 | EXECNAME = noisebench.exe 14 | OUTPUTFILE = ashimanoise.log 15 | 16 | all: $(EXECNAME) 17 | 18 | clean: 19 | del $(OBJ) $(EXECNAME) $(SHADERS) $(OUTPUTFILE) $(SRC) 20 | 21 | noisebench.vert: 22 | copy ..\common\noisebench.vert . 23 | 24 | constant.frag: 25 | copy ..\common\constant.frag . 26 | 27 | simplexnoise2D.frag: 28 | copy ..\common\simplexnoise2D.frag . 29 | 30 | simplexnoise3D.frag: 31 | copy ..\common\simplexnoise3D.frag . 32 | 33 | simplexnoise4D.frag: 34 | copy ..\common\simplexnoise4D.frag . 35 | 36 | classicnoise2D.frag: 37 | copy ..\common\classicnoise2D.frag . 38 | 39 | classicnoise3D.frag: 40 | copy ..\common\classicnoise3D.frag . 41 | 42 | classicnoise4D.frag: 43 | copy ..\common\classicnoise4D.frag . 44 | 45 | $(SRC): 46 | copy ..\common\$(SRC) . 47 | 48 | $(OBJ): $(SRC) 49 | $(CC) -c $(SRC) -o $(OBJ) $(CFLAGS) 50 | 51 | $(EXECNAME): $(OBJ) $(SHADERS) 52 | $(CC) $(OBJ) -o $(EXECNAME) $(LIBS) 53 | 54 | run: $(EXECNAME) 55 | ./$(EXECNAME) 56 | type $(OUTPUTFILE) 57 | -------------------------------------------------------------------------------- /benchmark/Win32/libglfw.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stegu/webgl-noise/22434e04d7753f7e949e8d724ab3da2864c17a0f/benchmark/Win32/libglfw.a -------------------------------------------------------------------------------- /benchmark/common/Makefile: -------------------------------------------------------------------------------- 1 | OPTIONS= 2 | SRCDIR=../../src 3 | COMMON=commonShader.frag 4 | SHADERS=simplexnoise2D.frag simplexnoise3D.frag simplexnoise4D.frag \ 5 | classicnoise2D.frag classicnoise3D.frag classicnoise4D.frag 6 | 7 | all: $(SHADERS) 8 | 9 | clean: 10 | - rm $(SHADERS) 11 | 12 | simplexnoise2D.frag: $(SRCDIR)/noise2D.glsl $(COMMON) 13 | cpp -P -I$(SRCDIR) -DSHADER=\"noise2D.glsl\" \ 14 | -DVTYPE=vec2 -DVNAME=v_texCoord2D -DNOISEFUN=snoise\ 15 | $(OPTIONS) -DVERSION='#version 120' commonShader.frag $@ 16 | 17 | simplexnoise3D.frag: $(SRCDIR)/noise3D.glsl $(COMMON) 18 | cpp -P -I$(SRCDIR) -DSHADER=\"noise3D.glsl\" \ 19 | -DVTYPE=vec3 -DVNAME=v_texCoord3D -DNOISEFUN=snoise\ 20 | $(OPTIONS) -DVERSION='#version 120' commonShader.frag $@ 21 | 22 | simplexnoise4D.frag: $(SRCDIR)/noise4D.glsl $(COMMON) 23 | cpp -P -I$(SRCDIR) -DSHADER=\"noise4D.glsl\" \ 24 | -DVTYPE=vec4 -DVNAME=v_texCoord4D -DNOISEFUN=snoise\ 25 | $(OPTIONS) -DVERSION='#version 120' commonShader.frag $@ 26 | 27 | classicnoise2D.frag: $(SRCDIR)/classicnoise2D.glsl $(COMMON) 28 | cpp -P -I$(SRCDIR) -DSHADER=\"classicnoise2D.glsl\" \ 29 | -DVTYPE=vec2 -DVNAME=v_texCoord2D -DNOISEFUN=cnoise\ 30 | $(OPTIONS) -DVERSION='#version 120' commonShader.frag $@ 31 | 32 | classicnoise3D.frag: $(SRCDIR)/classicnoise3D.glsl $(COMMON) 33 | cpp -P -I$(SRCDIR) -DSHADER=\"classicnoise3D.glsl\" \ 34 | -DVTYPE=vec3 -DVNAME=v_texCoord3D -DNOISEFUN=cnoise\ 35 | $(OPTIONS) -DVERSION='#version 120' commonShader.frag $@ 36 | 37 | classicnoise4D.frag: $(SRCDIR)/classicnoise4D.glsl $(COMMON) 38 | cpp -P -I$(SRCDIR) -DSHADER=\"classicnoise4D.glsl\" \ 39 | -DVTYPE=vec4 -DVNAME=v_texCoord4D -DNOISEFUN=cnoise\ 40 | $(OPTIONS) -DVERSION='#version 120' commonShader.frag $@ 41 | -------------------------------------------------------------------------------- /benchmark/common/commonShader.frag: -------------------------------------------------------------------------------- 1 | VERSION 2 | 3 | #include SHADER 4 | 5 | uniform float time; // Used for texture animation 6 | 7 | varying VTYPE VNAME ; 8 | 9 | // 10 | // main() 11 | // 12 | void main( void ) 13 | { 14 | float n = NOISEFUN(VNAME); 15 | gl_FragColor = vec4(vec3(n * 0.5 + 0.5), 1.0); 16 | } 17 | -------------------------------------------------------------------------------- /benchmark/common/constant.frag: -------------------------------------------------------------------------------- 1 | #version 120 2 | 3 | uniform float time; 4 | 5 | void main( void ) 6 | { 7 | float n = 0.0; 8 | gl_FragColor = vec4(0.5 + 0.5 * vec3(n, n, n), 1.0); 9 | } 10 | -------------------------------------------------------------------------------- /benchmark/common/noisebench.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Benchmark for GLSL procedural noise functions. 3 | * 4 | * Shaders are loaded from external files, named in 5 | * the macro definitions VERTSHADERFILE and FRAGSHADERFILE*. 6 | * The main program draws a flat plane covering the 7 | * viewport, activates each of six fragment shaders in turn 8 | * and reports the fragment shading performance in Msamples/s 9 | * for each. 10 | * 11 | * This program uses GLFW for convenience, to handle the OS-specific 12 | * window management stuff. Some Windows-specific stuff for extension 13 | * loading is still here, but that code is short-circuited on other 14 | * platforms - this file compiles unedited on Windows, Linux and MacOS X, 15 | * provided you have the relevant libraries and header files installed 16 | * and set up your compilation to include the GLFW and OpenGL libraries. 17 | * 18 | * Author: Stefan Gustavson (stefan.gustavson@liu.se) 2004, 2005, 2010, 2011 19 | * This code is in the public domain. 20 | */ 21 | 22 | // Identify the exact version of noise being benchmarked 23 | #define NOISEVERSION "2011-04-03" 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #ifdef __WIN32__ 31 | // The system level include file for GL extensions might not be up to date. 32 | #include "GL/glext.h" 33 | #else 34 | #include 35 | #endif 36 | 37 | 38 | #ifdef __APPLE__ 39 | // MacOS application bundles have the executable inside a directory structure 40 | #define VERTSHADERFILE "../../../noisebench.vert" 41 | #define FRAGSHADERFILE_S2D "../../../simplexnoise2D.frag" 42 | #define FRAGSHADERFILE_S3D "../../../simplexnoise3D.frag" 43 | #define FRAGSHADERFILE_S4D "../../../simplexnoise4D.frag" 44 | #define FRAGSHADERFILE_C2D "../../../classicnoise2D.frag" 45 | #define FRAGSHADERFILE_C3D "../../../classicnoise3D.frag" 46 | #define FRAGSHADERFILE_C4D "../../../classicnoise4D.frag" 47 | #define FRAGSHADERFILE_CONST "../../../constant.frag" 48 | #define LOGFILENAME "../../../ashimanoise.log" 49 | #else 50 | // Windows, Linux and other Unix systems expose executables as naked files 51 | #define VERTSHADERFILE "noisebench.vert" 52 | #define FRAGSHADERFILE_S2D "simplexnoise2D.frag" 53 | #define FRAGSHADERFILE_S3D "simplexnoise3D.frag" 54 | #define FRAGSHADERFILE_S4D "simplexnoise4D.frag" 55 | #define FRAGSHADERFILE_C2D "classicnoise2D.frag" 56 | #define FRAGSHADERFILE_C3D "classicnoise3D.frag" 57 | #define FRAGSHADERFILE_C4D "classicnoise4D.frag" 58 | #define FRAGSHADERFILE_CONST "constant.frag" 59 | #define LOGFILENAME "ashimanoise.log" 60 | #endif 61 | 62 | #ifdef __WIN32__ 63 | /* Global function pointers for everything we need beyond OpenGL 1.1 */ 64 | PFNGLCREATEPROGRAMPROC glCreateProgram = NULL; 65 | PFNGLDELETEPROGRAMPROC glDeleteProgram = NULL; 66 | PFNGLUSEPROGRAMPROC glUseProgram = NULL; 67 | PFNGLCREATESHADERPROC glCreateShader = NULL; 68 | PFNGLDELETESHADERPROC glDeleteShader = NULL; 69 | PFNGLSHADERSOURCEPROC glShaderSource = NULL; 70 | PFNGLCOMPILESHADERPROC glCompileShader = NULL; 71 | PFNGLGETSHADERIVPROC glGetShaderiv = NULL; 72 | PFNGLGETPROGRAMIVPROC glGetProgramiv = NULL; 73 | PFNGLATTACHSHADERPROC glAttachShader = NULL; 74 | PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog = NULL; 75 | PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog = NULL; 76 | PFNGLLINKPROGRAMPROC glLinkProgram = NULL; 77 | PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation = NULL; 78 | PFNGLUNIFORM1FVPROC glUniform1fv = NULL; 79 | #endif 80 | 81 | /* 82 | * printError() - Signal an error. 83 | * Simple printf() to console for portability. 84 | */ 85 | void printError(const char *errtype, const char *errmsg) { 86 | fprintf(stderr, "%s: %s\n", errtype, errmsg); 87 | } 88 | 89 | 90 | /* 91 | * Override the Win32 filelength() function with 92 | * a version that takes a Unix-style file handle as 93 | * input instead of a file ID number, and which works 94 | * on platforms other than Windows. 95 | */ 96 | long filelength(FILE *file) { 97 | long numbytes; 98 | long savedpos = ftell(file); 99 | fseek(file, 0, SEEK_END); 100 | numbytes = ftell(file); 101 | fseek(file, savedpos, SEEK_SET); 102 | return numbytes; 103 | } 104 | 105 | 106 | /* 107 | * loadExtensions() - Load OpenGL extensions for anything above OpenGL 108 | * version 1.1. (This is a requirement only on Windows, so on other 109 | * platforms, this function just checks for the required extensions.) 110 | */ 111 | void loadExtensions() { 112 | //These extension strings indicate that the OpenGL Shading Language 113 | // and GLSL shader objects are supported. 114 | if(!glfwExtensionSupported("GL_ARB_shading_language_100")) 115 | { 116 | printError("GL init error", "GL_ARB_shading_language_100 extension was not found"); 117 | return; 118 | } 119 | if(!glfwExtensionSupported("GL_ARB_shader_objects")) 120 | { 121 | printError("GL init error", "GL_ARB_shader_objects extension was not found"); 122 | return; 123 | } 124 | else 125 | { 126 | #ifdef __WIN32__ 127 | glCreateProgram = (PFNGLCREATEPROGRAMPROC)glfwGetProcAddress("glCreateProgram"); 128 | glDeleteProgram = (PFNGLDELETEPROGRAMPROC)glfwGetProcAddress("glDeleteProgram"); 129 | glUseProgram = (PFNGLUSEPROGRAMPROC)glfwGetProcAddress("glUseProgram"); 130 | glCreateShader = (PFNGLCREATESHADERPROC)glfwGetProcAddress("glCreateShader"); 131 | glDeleteShader = (PFNGLDELETESHADERPROC)glfwGetProcAddress("glDeleteShader"); 132 | glShaderSource = (PFNGLSHADERSOURCEPROC)glfwGetProcAddress("glShaderSource"); 133 | glCompileShader = (PFNGLCOMPILESHADERPROC)glfwGetProcAddress("glCompileShader"); 134 | glGetShaderiv = (PFNGLGETSHADERIVPROC)glfwGetProcAddress("glGetShaderiv"); 135 | glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)glfwGetProcAddress("glGetShaderInfoLog"); 136 | glAttachShader = (PFNGLATTACHSHADERPROC)glfwGetProcAddress("glAttachShader"); 137 | glLinkProgram = (PFNGLLINKPROGRAMPROC)glfwGetProcAddress("glLinkProgram"); 138 | glGetProgramiv = (PFNGLGETPROGRAMIVPROC)glfwGetProcAddress("glGetProgramiv"); 139 | glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)glfwGetProcAddress("glGetProgramInfoLog"); 140 | glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)glfwGetProcAddress("glGetUniformLocation"); 141 | glUniform1fv = (PFNGLUNIFORM1FVPROC)glfwGetProcAddress("glUniform1fv"); 142 | 143 | if( !glCreateProgram || !glDeleteProgram || !glUseProgram || 144 | !glCreateShader || !glDeleteShader || !glShaderSource || !glCompileShader || 145 | !glGetShaderiv || !glGetShaderInfoLog || !glAttachShader || !glLinkProgram || 146 | !glGetProgramiv || !glGetProgramInfoLog || !glGetUniformLocation || 147 | !glUniform1fv ) 148 | { 149 | printError("GL init error", "One or more required OpenGL functions were not found"); 150 | return; 151 | } 152 | #endif 153 | } 154 | } 155 | 156 | 157 | /* 158 | * readShaderFile(filename) - read a shader source string from a file 159 | */ 160 | unsigned char* readShaderFile(const char *filename) { 161 | FILE *file = fopen(filename, "r"); 162 | if(file == NULL) 163 | { 164 | printError("ERROR", "Cannot open shader file!"); 165 | return 0; 166 | } 167 | int bytesinfile = filelength(file); 168 | unsigned char *buffer = (unsigned char*)malloc(bytesinfile+1); 169 | int bytesread = fread( buffer, 1, bytesinfile, file); 170 | buffer[bytesread] = 0; // Terminate the string with 0 171 | fclose(file); 172 | 173 | return buffer; 174 | } 175 | 176 | 177 | /* 178 | * createShaders() - create, load, compile and link the GLSL shader objects. 179 | */ 180 | void createShader(GLuint *programObject, char *vertexshaderfile, char *fragmentshaderfile) { 181 | GLuint vertexShader; 182 | GLuint fragmentShader; 183 | 184 | const char *vertexShaderStrings[1]; 185 | const char *fragmentShaderStrings[1]; 186 | GLint vertexCompiled; 187 | GLint fragmentCompiled; 188 | GLint shadersLinked; 189 | char str[4096]; // For error messages from the GLSL compiler and linker 190 | 191 | // Create the vertex shader. 192 | vertexShader = glCreateShader(GL_VERTEX_SHADER); 193 | 194 | unsigned char *vertexShaderAssembly = readShaderFile( vertexshaderfile ); 195 | vertexShaderStrings[0] = (char*)vertexShaderAssembly; 196 | glShaderSource( vertexShader, 1, vertexShaderStrings, NULL ); 197 | glCompileShader( vertexShader); 198 | free((void *)vertexShaderAssembly); 199 | 200 | glGetShaderiv( vertexShader, GL_COMPILE_STATUS, 201 | &vertexCompiled ); 202 | if(vertexCompiled == GL_FALSE) 203 | { 204 | glGetShaderInfoLog(vertexShader, sizeof(str), NULL, str); 205 | printError("Vertex shader compile error", str); 206 | } 207 | 208 | // Create the fragment shader. 209 | fragmentShader = glCreateShader( GL_FRAGMENT_SHADER ); 210 | 211 | unsigned char *fragmentShaderAssembly = readShaderFile( fragmentshaderfile ); 212 | fragmentShaderStrings[0] = (char*)fragmentShaderAssembly; 213 | glShaderSource( fragmentShader, 1, fragmentShaderStrings, NULL ); 214 | glCompileShader( fragmentShader ); 215 | free((void *)fragmentShaderAssembly); 216 | 217 | glGetProgramiv( fragmentShader, GL_COMPILE_STATUS, 218 | &fragmentCompiled ); 219 | if(fragmentCompiled == GL_FALSE) 220 | { 221 | glGetShaderInfoLog( fragmentShader, sizeof(str), NULL, str ); 222 | printError("Fragment shader compile error", str); 223 | } 224 | 225 | // Create a program object and attach the two compiled shaders. 226 | *programObject = glCreateProgram(); 227 | glAttachShader( *programObject, vertexShader ); 228 | glAttachShader( *programObject, fragmentShader ); 229 | 230 | // Link the program object and print out the info log. 231 | glLinkProgram( *programObject ); 232 | glGetProgramiv( *programObject, GL_LINK_STATUS, &shadersLinked ); 233 | 234 | if( shadersLinked == GL_FALSE ) 235 | { 236 | glGetProgramInfoLog( *programObject, sizeof(str), NULL, str ); 237 | printError("Program object linking error", str); 238 | } 239 | } 240 | 241 | 242 | /* 243 | * computeFPS() - Calculate, display and return samples per second. 244 | * Stats are recomputed only once per second. 245 | */ 246 | double computeFPS() { 247 | 248 | static double t0 = 0.0; 249 | static int frames = 0; 250 | static double Msamplespersecond = 0.0; 251 | static char titlestring[200]; 252 | 253 | double t, fps; 254 | int width, height; 255 | 256 | // Get current time 257 | t = glfwGetTime(); // Gets number of seconds since glfwInit() 258 | // If one second has passed, or if this is the very first frame 259 | if( (t-t0) > 1.0 || frames == 0 ) 260 | { 261 | fps = (double)frames / (t-t0); 262 | glfwGetWindowSize( &width, &height ); 263 | // This assumes that multisampling for FSAA is disabled. 264 | Msamplespersecond = 1e-6*fps*width*height; 265 | sprintf(titlestring, "GLSL simplex noise (%.1f M samples/s)", Msamplespersecond); 266 | glfwSetWindowTitle(titlestring); 267 | printf("Speed: %.1f M samples/s\n", Msamplespersecond); 268 | t0 = t; 269 | frames = 0; 270 | } 271 | frames ++; 272 | return Msamplespersecond; 273 | } 274 | 275 | 276 | /* 277 | * setupCamera() - set up the OpenGL projection and (model)view matrices 278 | */ 279 | void setupCamera() { 280 | 281 | int width, height; 282 | 283 | // Get window size. It may start out different from the requested 284 | // size, and will change if the user resizes the window. 285 | glfwGetWindowSize( &width, &height ); 286 | if(height<=0) height=1; // Safeguard against iconified/closed window 287 | 288 | // Set viewport. This is the pixel rectangle we want to draw into. 289 | glViewport( 0, 0, width, height ); // The entire window 290 | 291 | // Select and setup the projection matrix. 292 | glMatrixMode(GL_PROJECTION); // "We want to edit the projection matrix" 293 | glLoadIdentity(); // Reset the matrix to identity 294 | // 45 degrees FOV, same aspect ratio as viewport, depth range 1 to 100 295 | glOrtho( -1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f ); 296 | 297 | // Select and setup the modelview matrix. 298 | glMatrixMode( GL_MODELVIEW ); // "We want to edit the modelview matrix" 299 | glLoadIdentity(); // Reset the matrix to identity 300 | } 301 | 302 | 303 | /* 304 | * initDisplayList(GLuint *listID, GLdouble scale) - create a display list 305 | * to render the demo geometry more efficently than by glVertex() calls. 306 | * (This is currently just as fast as a VBO, and I'm a bit lazy.) 307 | */ 308 | void initDisplayList(GLuint *listID) 309 | { 310 | *listID = glGenLists(1); 311 | 312 | glNewList(*listID, GL_COMPILE); 313 | glColor3f(1.0f, 1.0f, 1.0f); // White base color 314 | glBegin(GL_TRIANGLE_STRIP); 315 | glTexCoord2f(0.0f, 0.0f); 316 | glVertex3f(-1.0f, -1.0f, 0.0f); 317 | glTexCoord2f(1.0f, 0.0f); 318 | glVertex3f(1.0f, -1.0f, 0.0f); 319 | glTexCoord2f(0.0f, 1.0f); 320 | glVertex3f(-1.0f, 1.0f, 0.0f); 321 | glTexCoord2f(1.0f, 1.0f); 322 | glVertex3f(1.0f, 1.0f, 0.0f); 323 | glEnd(); 324 | glEndList(); 325 | } 326 | 327 | 328 | /* 329 | * renderScene() - draw the scene with the shader active 330 | */ 331 | void renderScene( GLuint listID, GLuint programObject ) 332 | { 333 | GLint location_time = -1; 334 | float time = 0.0f; 335 | 336 | // Use vertex and fragment shaders. 337 | glUseProgram( programObject ); 338 | // Update the uniform time variable. 339 | location_time = glGetUniformLocation( programObject, "time" ); 340 | // glUniform1f() is bugged in Linux Nvidia driver 260.19.06, 341 | // so we use glUniform1fv() instead to work around the bug. 342 | if ( location_time != -1 ) { 343 | time = (float)glfwGetTime(); 344 | glUniform1fv( location_time, 1, &time ); 345 | } 346 | // Render with the shaders active. 347 | glCallList( listID ); 348 | // Deactivate the shaders. 349 | glUseProgram(0); 350 | } 351 | 352 | 353 | /* 354 | * main(argc, argv) - the standard C entry point for the program 355 | */ 356 | int main(int argc, char *argv[]) { 357 | 358 | GLuint displayList; 359 | GLuint programObject; 360 | double performance = 0.0; 361 | int activeshader = 0; // Currently active version of noise shader 362 | FILE *logfile; 363 | GLFWvidmode vidmode; 364 | 365 | GLboolean running = GL_TRUE; // Main loop exits when this is set to GL_FALSE 366 | 367 | // Initialise GLFW 368 | glfwInit(); 369 | 370 | // Open a temporary OpenGL window just to determine the desktop size 371 | if( !glfwOpenWindow(256, 256, 8,8,8,8, 32,0, GLFW_WINDOW) ) 372 | { 373 | glfwTerminate(); // glfwOpenWindow failed, quit the program. 374 | return 1; 375 | } 376 | glfwGetDesktopMode(&vidmode); 377 | glfwCloseWindow(); 378 | 379 | // Open a fullscreen window using the current desktop resolution 380 | if( !glfwOpenWindow(vidmode.Width, vidmode.Height, 8,8,8,8, 32,0, GLFW_FULLSCREEN) ) 381 | { 382 | glfwTerminate(); // glfwOpenWindow failed, quit the program. 383 | return 1; 384 | } 385 | 386 | // Load the extensions for GLSL - note that this has to be done 387 | // *after* the window has been opened, or we won't have a GL context 388 | // to query for those extensions and connect to instances of them. 389 | loadExtensions(); 390 | 391 | logfile = fopen(LOGFILENAME, "w"); 392 | 393 | fprintf(logfile, "GL vendor: %s\n", glGetString(GL_VENDOR)); 394 | fprintf(logfile, "GL renderer: %s\n", glGetString(GL_RENDERER)); 395 | fprintf(logfile, "GL version: %s\n", glGetString(GL_VERSION)); 396 | fprintf(logfile, "Desktop size: %d x %d pixels\n", vidmode.Width, vidmode.Height); 397 | fprintf(logfile, "Noise version: %s\n\n", NOISEVERSION); 398 | 399 | // Disable Z buffering for this simple 2D shader benchmark 400 | glDisable(GL_DEPTH_TEST); // Use the Z buffer 401 | 402 | glfwSwapInterval(0); // Do not wait for screen refresh between frames 403 | 404 | // Compile a display list for the demo geometry, to render it efficiently 405 | initDisplayList(&displayList); 406 | 407 | // Main loop 408 | while(running) 409 | { 410 | double benchmarktime = 3.0; // Total time to run each shader 411 | // Switch between the different versions of noise 412 | if(activeshader == 0) { 413 | createShader(&programObject, VERTSHADERFILE, FRAGSHADERFILE_CONST); 414 | activeshader++; 415 | fprintf(logfile, "Constant shading, "); 416 | } 417 | if((activeshader == 1) && (glfwGetTime() > benchmarktime * activeshader)) { 418 | fprintf(logfile, "%.1f Msamples/s\n", performance); 419 | createShader(&programObject, VERTSHADERFILE, FRAGSHADERFILE_S2D); 420 | activeshader++; 421 | fprintf(logfile, "2D simplex noise, "); 422 | } 423 | if((activeshader == 2) && (glfwGetTime() > benchmarktime * activeshader)) { 424 | fprintf(logfile, "%.1f Msamples/s\n", performance); 425 | createShader(&programObject, VERTSHADERFILE, FRAGSHADERFILE_S3D); 426 | activeshader++; 427 | fprintf(logfile, "3D simplex noise, "); 428 | } 429 | if((activeshader == 3) && (glfwGetTime() > benchmarktime * activeshader)) { 430 | fprintf(logfile, "%.1f Msamples/s\n", performance); 431 | createShader(&programObject, VERTSHADERFILE, FRAGSHADERFILE_S4D); 432 | activeshader++; 433 | fprintf(logfile, "4D simplex noise, "); 434 | } 435 | if((activeshader == 4) && (glfwGetTime() > benchmarktime * activeshader)) { 436 | fprintf(logfile, "%.1f Msamples/s\n", performance); 437 | createShader(&programObject, VERTSHADERFILE, FRAGSHADERFILE_C2D); 438 | activeshader++; 439 | fprintf(logfile, "2D classic noise, "); 440 | } 441 | if((activeshader == 5) && (glfwGetTime() > benchmarktime * activeshader)) { 442 | fprintf(logfile, "%.1f Msamples/s\n", performance); 443 | createShader(&programObject, VERTSHADERFILE, FRAGSHADERFILE_C3D); 444 | activeshader++; 445 | fprintf(logfile, "3D classic noise, "); 446 | } 447 | if((activeshader == 6) && (glfwGetTime() > benchmarktime * activeshader)) { 448 | fprintf(logfile, "%.1f Msamples/s\n", performance); 449 | createShader(&programObject, VERTSHADERFILE, FRAGSHADERFILE_C4D); 450 | activeshader++; 451 | fprintf(logfile, "4D classic noise, "); 452 | } 453 | if((activeshader == 7) && (glfwGetTime() > benchmarktime * activeshader)) { 454 | fprintf(logfile, "%.1f Msamples/s\n", performance); 455 | running = GL_FALSE; 456 | } 457 | 458 | // Exit prematurely if the ESC key is pressed or the window is closed. 459 | if(glfwGetKey(GLFW_KEY_ESC) || !glfwGetWindowParam(GLFW_OPENED)) { 460 | running = GL_FALSE; 461 | } 462 | 463 | // Calculate and update the frames per second (FPS) display 464 | performance = computeFPS(); 465 | 466 | // Do not clear the buffers - this is a raw shader benchmark. 467 | //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 468 | 469 | // Set up the camera projection. 470 | setupCamera(); 471 | 472 | // Draw the scene. 473 | renderScene(displayList, programObject); 474 | 475 | // Swap buffers, i.e. display the image and prepare for next frame. 476 | glfwSwapBuffers(); 477 | } 478 | 479 | // Close the OpenGL window and terminate GLFW. 480 | glfwTerminate(); 481 | 482 | fclose(logfile); 483 | 484 | return 0; 485 | } 486 | -------------------------------------------------------------------------------- /benchmark/common/noisebench.vert: -------------------------------------------------------------------------------- 1 | #version 120 2 | 3 | uniform float time; 4 | 5 | /* 6 | * Both 2D, 3D and 4D texture coordinates are defined, for testing purposes. 7 | */ 8 | varying vec2 v_texCoord2D; 9 | varying vec3 v_texCoord3D; 10 | varying vec4 v_texCoord4D; 11 | 12 | void main( void ) 13 | { 14 | gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; 15 | v_texCoord2D = gl_MultiTexCoord0.xy * 16.0 + vec2(0.0, time); 16 | v_texCoord3D = vec3(gl_MultiTexCoord0.xy * 16.0, time); 17 | v_texCoord4D = vec4(gl_MultiTexCoord0.xy * 16.0, 0.0, time); 18 | } 19 | -------------------------------------------------------------------------------- /demo/Linux/Makefile: -------------------------------------------------------------------------------- 1 | SHADERS=noisedemo.vert noisedemo.frag 2 | COMDIR=../common 3 | VPATH=$(COMDIR) 4 | EXECNAME=noisedemo 5 | 6 | all: $(EXECNAME) links_done 7 | 8 | $(EXECNAME): noisedemo.c 9 | gcc -I. -I/usr/X11/include $^ -lglfw -lGLU -lGL -lm -o $@ 10 | 11 | links_done: $(SHADERS) 12 | ln -s $? . ; touch links_done 13 | 14 | clean: 15 | - rm $(EXECNAME) $(SHADERS) links_done 16 | 17 | run: 18 | ./$(EXECNAME) 19 | -------------------------------------------------------------------------------- /demo/MacOSX/Makefile: -------------------------------------------------------------------------------- 1 | EXECNAME=noisedemo 2 | COMDIR=../common 3 | 4 | OBJS=noisedemo.o 5 | SHADERS=noisedemo.vert noisedemo.frag 6 | 7 | VPATH=$(COMDIR) 8 | CFLAGS=-I. -I/usr/X11/include 9 | LDFLAGS=-framework Cocoa -framework OpenGL -lglfw 10 | 11 | .PHONY: all clean run 12 | 13 | all: $(EXECNAME).app links_done 14 | 15 | links_done: $(SHADERS) 16 | ln -s $? . ; touch links_done 17 | 18 | $(EXECNAME).app: $(EXECNAME) 19 | ./bundle.sh $@ $^ ; chmod a-x $^ 20 | 21 | $(EXECNAME): $(OBJS) 22 | 23 | clean: 24 | - rm -r $(EXECNAME).app 25 | - rm $(EXECNAME) links_done $(OBJS) $(SHADERS) 26 | 27 | run: 28 | open -W ./$(EXECNAME).app 29 | -------------------------------------------------------------------------------- /demo/MacOSX/bundle.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Creates application bundles for use on Mac OS X. 4 | 5 | if [ -z "$1" ]; then 6 | echo "usage: `basename $0` BUNDLE-NAME exec-name" 7 | exit 1 8 | fi 9 | 10 | bundle_name="$1" 11 | exec_file="$2" 12 | exec_name=`basename $bundle_name .app` 13 | 14 | if [ ! -f $exec_file ]; then 15 | echo "Can't find $exec_file" 16 | exit 1 17 | fi 18 | 19 | if [ ! -d "${bundle_name}/Contents/MacOS" ]; then 20 | mkdir -p "${bundle_name}/Contents/MacOS" 21 | fi 22 | 23 | cp $exec_file "${bundle_name}/Contents/MacOS/" 24 | 25 | touch "${bundle_name}" 26 | 27 | if [ ! -d "${bundle_name}/Contents/Resources" ]; then 28 | mkdir -p "${bundle_name}/Contents/Resources" 29 | fi 30 | 31 | if [ ! -f "${bundle_name}/Contents/PkgInfo" ]; then 32 | echo -n "APPL????" > "${bundle_name}/Contents/PkgInfo" 33 | fi 34 | 35 | if [ ! -f "${bundle_name}/Contents/Info.plist" ]; then 36 | cat > "${bundle_name}/Contents/Info.plist" < 38 | 39 | 40 | 41 | CFBundleName ${exec_name} 42 | CFBundleExecutable ${exec_name} 43 | CFBundleIdentifier com.ashimaarts.${exec_name} 44 | CFBundleVersion 0.1 45 | 46 | CFBundlePackageType APPL 47 | CFBundleDevelopmentRegion English 48 | CFBundleSignature ???? 49 | CFBundleInfoDictionaryVersion 6.0 50 | 51 | 52 | EOF 53 | fi 54 | -------------------------------------------------------------------------------- /demo/Makefile: -------------------------------------------------------------------------------- 1 | WINMAKE = mingw32-make 2 | 3 | .PHONY: default clean Linux MacOSX Win32 clean-Win32 4 | 5 | default: 6 | @echo "Usage:" 7 | @echo "make [ Linux | MacOSX | Win32 | clean | clean-Win32]" 8 | 9 | clean: 10 | cd common ; make clean 11 | cd Linux ; make clean 12 | cd MacOSX ; make clean 13 | 14 | Linux: 15 | cd common ; make 16 | cd $@ ; make ; make run 17 | 18 | MacOSX: 19 | cd common ; make 20 | cd $@ ; make ; make run 21 | 22 | Win32: 23 | cd common && $(WINMAKE) 24 | cd $@ && $(WINMAKE) && $(WINMAKE) run 25 | 26 | clean-Win32: 27 | cd common && $(WINMAKE) clean 28 | cd Win32 && $(WINMAKE) clean 29 | -------------------------------------------------------------------------------- /demo/README: -------------------------------------------------------------------------------- 1 | This is a visual demo for some of the noise functions, but it was written in 2011 2 | to be compatible with MacOS X, which was still stuck at OpenGL 2.1 at the time. 3 | The code hasn't aged well. In addition to using legacy OpenGL, it uses 4 | the old version 2 of the GLFW library, which is still available but no longer 5 | maintained. Trying to resurrect this code might prove painful. 6 | In any case, this is not code you should learn from or build upon. 7 | -------------------------------------------------------------------------------- /demo/Win32/GL/glfw.h: -------------------------------------------------------------------------------- 1 | //======================================================================== 2 | // GLFW - An OpenGL framework 3 | // File: glfw.h 4 | // API version: 2.6 5 | // WWW: http://glfw.sourceforge.net 6 | //------------------------------------------------------------------------ 7 | // Copyright (c) 2002-2006 Camilla Berglund 8 | // 9 | // This software is provided 'as-is', without any express or implied 10 | // warranty. In no event will the authors be held liable for any damages 11 | // arising from the use of this software. 12 | // 13 | // Permission is granted to anyone to use this software for any purpose, 14 | // including commercial applications, and to alter it and redistribute it 15 | // freely, subject to the following restrictions: 16 | // 17 | // 1. The origin of this software must not be misrepresented; you must not 18 | // claim that you wrote the original software. If you use this software 19 | // in a product, an acknowledgment in the product documentation would 20 | // be appreciated but is not required. 21 | // 22 | // 2. Altered source versions must be plainly marked as such, and must not 23 | // be misrepresented as being the original software. 24 | // 25 | // 3. This notice may not be removed or altered from any source 26 | // distribution. 27 | // 28 | //======================================================================== 29 | 30 | #ifndef __glfw_h_ 31 | #define __glfw_h_ 32 | 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | 38 | //======================================================================== 39 | // Global definitions 40 | //======================================================================== 41 | 42 | // We need a NULL pointer from time to time 43 | #ifndef NULL 44 | #ifdef __cplusplus 45 | #define NULL 0 46 | #else 47 | #define NULL ((void *)0) 48 | #endif 49 | #endif // NULL 50 | 51 | 52 | // ------------------- BEGIN SYSTEM/COMPILER SPECIFIC -------------------- 53 | 54 | // Please report any probles that you find with your compiler, which may 55 | // be solved in this section! There are several compilers that I have not 56 | // been able to test this file with yet. 57 | 58 | // First: If we are we on Windows, we want a single define for it (_WIN32) 59 | // (Note: For Cygwin the compiler flag -mwin32 should be used, but to 60 | // make sure that things run smoothly for Cygwin users, we add __CYGWIN__ 61 | // to the list of "valid Win32 identifiers", which removes the need for 62 | // -mwin32) 63 | #if !defined(_WIN32) && (defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__)) 64 | #define _WIN32 65 | #endif // _WIN32 66 | 67 | // In order for extension support to be portable, we need to define an 68 | // OpenGL function call method. We use the keyword APIENTRY, which is 69 | // defined for Win32. (Note: Windows also needs this for ) 70 | #ifndef APIENTRY 71 | #ifdef _WIN32 72 | #define APIENTRY __stdcall 73 | #else 74 | #define APIENTRY 75 | #endif 76 | #define GL_APIENTRY_DEFINED 77 | #endif // APIENTRY 78 | 79 | 80 | // The following three defines are here solely to make some Windows-based 81 | // files happy. Theoretically we could include , but 82 | // it has the major drawback of severely polluting our namespace. 83 | 84 | // Under Windows, we need WINGDIAPI defined 85 | #if !defined(WINGDIAPI) && defined(_WIN32) 86 | #if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__POCC__) 87 | // Microsoft Visual C++, Borland C++ Builder and Pelles C 88 | #define WINGDIAPI __declspec(dllimport) 89 | #elif defined(__LCC__) 90 | // LCC-Win32 91 | #define WINGDIAPI __stdcall 92 | #else 93 | // Others (e.g. MinGW, Cygwin) 94 | #define WINGDIAPI extern 95 | #endif 96 | #define GL_WINGDIAPI_DEFINED 97 | #endif // WINGDIAPI 98 | 99 | // Some files also need CALLBACK defined 100 | #if !defined(CALLBACK) && defined(_WIN32) 101 | #if defined(_MSC_VER) 102 | // Microsoft Visual C++ 103 | #if (defined(_M_MRX000) || defined(_M_IX86) || defined(_M_ALPHA) || defined(_M_PPC)) && !defined(MIDL_PASS) 104 | #define CALLBACK __stdcall 105 | #else 106 | #define CALLBACK 107 | #endif 108 | #else 109 | // Other Windows compilers 110 | #define CALLBACK __stdcall 111 | #endif 112 | #define GLU_CALLBACK_DEFINED 113 | #endif // CALLBACK 114 | 115 | // Microsoft Visual C++, Borland C++ and Pelles C needs wchar_t 116 | #if defined(_WIN32) && (defined(_MSC_VER) || defined(__BORLANDC__) || defined(__POCC__)) && !defined(_WCHAR_T_DEFINED) 117 | typedef unsigned short wchar_t; 118 | #define _WCHAR_T_DEFINED 119 | #endif // _WCHAR_T_DEFINED 120 | 121 | 122 | // ---------------- GLFW related system specific defines ----------------- 123 | 124 | #if defined(_WIN32) && defined(GLFW_BUILD_DLL) 125 | 126 | // We are building a Win32 DLL 127 | #define GLFWAPI __declspec(dllexport) 128 | #define GLFWAPIENTRY __stdcall 129 | #define GLFWCALL __stdcall 130 | 131 | #elif defined(_WIN32) && defined(GLFW_DLL) 132 | 133 | // We are calling a Win32 DLL 134 | #if defined(__LCC__) 135 | #define GLFWAPI extern 136 | #else 137 | #define GLFWAPI __declspec(dllimport) 138 | #endif 139 | #define GLFWAPIENTRY __stdcall 140 | #define GLFWCALL __stdcall 141 | 142 | #else 143 | 144 | // We are either building/calling a static lib or we are non-win32 145 | #define GLFWAPIENTRY 146 | #define GLFWAPI 147 | #define GLFWCALL 148 | 149 | #endif 150 | 151 | // -------------------- END SYSTEM/COMPILER SPECIFIC --------------------- 152 | 153 | // Include standard OpenGL headers: GLFW uses GL_FALSE/GL_TRUE, and it is 154 | // convenient for the user to only have to include . This also 155 | // solves the problem with Windows and needing some 156 | // special defines which normally requires the user to include 157 | // (which is not a nice solution for portable programs). 158 | #if defined(__APPLE_CC__) 159 | #include 160 | #include 161 | #else 162 | #include 163 | #include 164 | #endif 165 | 166 | 167 | //======================================================================== 168 | // GLFW version 169 | //======================================================================== 170 | 171 | #define GLFW_VERSION_MAJOR 2 172 | #define GLFW_VERSION_MINOR 6 173 | #define GLFW_VERSION_REVISION 0 174 | 175 | 176 | //======================================================================== 177 | // Input handling definitions 178 | //======================================================================== 179 | 180 | // Key and button state/action definitions 181 | #define GLFW_RELEASE 0 182 | #define GLFW_PRESS 1 183 | 184 | // Keyboard key definitions: 8-bit ISO-8859-1 (Latin 1) encoding is used 185 | // for printable keys (such as A-Z, 0-9 etc), and values above 256 186 | // represent special (non-printable) keys (e.g. F1, Page Up etc). 187 | #define GLFW_KEY_UNKNOWN -1 188 | #define GLFW_KEY_SPACE 32 189 | #define GLFW_KEY_SPECIAL 256 190 | #define GLFW_KEY_ESC (GLFW_KEY_SPECIAL+1) 191 | #define GLFW_KEY_F1 (GLFW_KEY_SPECIAL+2) 192 | #define GLFW_KEY_F2 (GLFW_KEY_SPECIAL+3) 193 | #define GLFW_KEY_F3 (GLFW_KEY_SPECIAL+4) 194 | #define GLFW_KEY_F4 (GLFW_KEY_SPECIAL+5) 195 | #define GLFW_KEY_F5 (GLFW_KEY_SPECIAL+6) 196 | #define GLFW_KEY_F6 (GLFW_KEY_SPECIAL+7) 197 | #define GLFW_KEY_F7 (GLFW_KEY_SPECIAL+8) 198 | #define GLFW_KEY_F8 (GLFW_KEY_SPECIAL+9) 199 | #define GLFW_KEY_F9 (GLFW_KEY_SPECIAL+10) 200 | #define GLFW_KEY_F10 (GLFW_KEY_SPECIAL+11) 201 | #define GLFW_KEY_F11 (GLFW_KEY_SPECIAL+12) 202 | #define GLFW_KEY_F12 (GLFW_KEY_SPECIAL+13) 203 | #define GLFW_KEY_F13 (GLFW_KEY_SPECIAL+14) 204 | #define GLFW_KEY_F14 (GLFW_KEY_SPECIAL+15) 205 | #define GLFW_KEY_F15 (GLFW_KEY_SPECIAL+16) 206 | #define GLFW_KEY_F16 (GLFW_KEY_SPECIAL+17) 207 | #define GLFW_KEY_F17 (GLFW_KEY_SPECIAL+18) 208 | #define GLFW_KEY_F18 (GLFW_KEY_SPECIAL+19) 209 | #define GLFW_KEY_F19 (GLFW_KEY_SPECIAL+20) 210 | #define GLFW_KEY_F20 (GLFW_KEY_SPECIAL+21) 211 | #define GLFW_KEY_F21 (GLFW_KEY_SPECIAL+22) 212 | #define GLFW_KEY_F22 (GLFW_KEY_SPECIAL+23) 213 | #define GLFW_KEY_F23 (GLFW_KEY_SPECIAL+24) 214 | #define GLFW_KEY_F24 (GLFW_KEY_SPECIAL+25) 215 | #define GLFW_KEY_F25 (GLFW_KEY_SPECIAL+26) 216 | #define GLFW_KEY_UP (GLFW_KEY_SPECIAL+27) 217 | #define GLFW_KEY_DOWN (GLFW_KEY_SPECIAL+28) 218 | #define GLFW_KEY_LEFT (GLFW_KEY_SPECIAL+29) 219 | #define GLFW_KEY_RIGHT (GLFW_KEY_SPECIAL+30) 220 | #define GLFW_KEY_LSHIFT (GLFW_KEY_SPECIAL+31) 221 | #define GLFW_KEY_RSHIFT (GLFW_KEY_SPECIAL+32) 222 | #define GLFW_KEY_LCTRL (GLFW_KEY_SPECIAL+33) 223 | #define GLFW_KEY_RCTRL (GLFW_KEY_SPECIAL+34) 224 | #define GLFW_KEY_LALT (GLFW_KEY_SPECIAL+35) 225 | #define GLFW_KEY_RALT (GLFW_KEY_SPECIAL+36) 226 | #define GLFW_KEY_TAB (GLFW_KEY_SPECIAL+37) 227 | #define GLFW_KEY_ENTER (GLFW_KEY_SPECIAL+38) 228 | #define GLFW_KEY_BACKSPACE (GLFW_KEY_SPECIAL+39) 229 | #define GLFW_KEY_INSERT (GLFW_KEY_SPECIAL+40) 230 | #define GLFW_KEY_DEL (GLFW_KEY_SPECIAL+41) 231 | #define GLFW_KEY_PAGEUP (GLFW_KEY_SPECIAL+42) 232 | #define GLFW_KEY_PAGEDOWN (GLFW_KEY_SPECIAL+43) 233 | #define GLFW_KEY_HOME (GLFW_KEY_SPECIAL+44) 234 | #define GLFW_KEY_END (GLFW_KEY_SPECIAL+45) 235 | #define GLFW_KEY_KP_0 (GLFW_KEY_SPECIAL+46) 236 | #define GLFW_KEY_KP_1 (GLFW_KEY_SPECIAL+47) 237 | #define GLFW_KEY_KP_2 (GLFW_KEY_SPECIAL+48) 238 | #define GLFW_KEY_KP_3 (GLFW_KEY_SPECIAL+49) 239 | #define GLFW_KEY_KP_4 (GLFW_KEY_SPECIAL+50) 240 | #define GLFW_KEY_KP_5 (GLFW_KEY_SPECIAL+51) 241 | #define GLFW_KEY_KP_6 (GLFW_KEY_SPECIAL+52) 242 | #define GLFW_KEY_KP_7 (GLFW_KEY_SPECIAL+53) 243 | #define GLFW_KEY_KP_8 (GLFW_KEY_SPECIAL+54) 244 | #define GLFW_KEY_KP_9 (GLFW_KEY_SPECIAL+55) 245 | #define GLFW_KEY_KP_DIVIDE (GLFW_KEY_SPECIAL+56) 246 | #define GLFW_KEY_KP_MULTIPLY (GLFW_KEY_SPECIAL+57) 247 | #define GLFW_KEY_KP_SUBTRACT (GLFW_KEY_SPECIAL+58) 248 | #define GLFW_KEY_KP_ADD (GLFW_KEY_SPECIAL+59) 249 | #define GLFW_KEY_KP_DECIMAL (GLFW_KEY_SPECIAL+60) 250 | #define GLFW_KEY_KP_EQUAL (GLFW_KEY_SPECIAL+61) 251 | #define GLFW_KEY_KP_ENTER (GLFW_KEY_SPECIAL+62) 252 | #define GLFW_KEY_LAST GLFW_KEY_KP_ENTER 253 | 254 | // Mouse button definitions 255 | #define GLFW_MOUSE_BUTTON_1 0 256 | #define GLFW_MOUSE_BUTTON_2 1 257 | #define GLFW_MOUSE_BUTTON_3 2 258 | #define GLFW_MOUSE_BUTTON_4 3 259 | #define GLFW_MOUSE_BUTTON_5 4 260 | #define GLFW_MOUSE_BUTTON_6 5 261 | #define GLFW_MOUSE_BUTTON_7 6 262 | #define GLFW_MOUSE_BUTTON_8 7 263 | #define GLFW_MOUSE_BUTTON_LAST GLFW_MOUSE_BUTTON_8 264 | 265 | // Mouse button aliases 266 | #define GLFW_MOUSE_BUTTON_LEFT GLFW_MOUSE_BUTTON_1 267 | #define GLFW_MOUSE_BUTTON_RIGHT GLFW_MOUSE_BUTTON_2 268 | #define GLFW_MOUSE_BUTTON_MIDDLE GLFW_MOUSE_BUTTON_3 269 | 270 | 271 | // Joystick identifiers 272 | #define GLFW_JOYSTICK_1 0 273 | #define GLFW_JOYSTICK_2 1 274 | #define GLFW_JOYSTICK_3 2 275 | #define GLFW_JOYSTICK_4 3 276 | #define GLFW_JOYSTICK_5 4 277 | #define GLFW_JOYSTICK_6 5 278 | #define GLFW_JOYSTICK_7 6 279 | #define GLFW_JOYSTICK_8 7 280 | #define GLFW_JOYSTICK_9 8 281 | #define GLFW_JOYSTICK_10 9 282 | #define GLFW_JOYSTICK_11 10 283 | #define GLFW_JOYSTICK_12 11 284 | #define GLFW_JOYSTICK_13 12 285 | #define GLFW_JOYSTICK_14 13 286 | #define GLFW_JOYSTICK_15 14 287 | #define GLFW_JOYSTICK_16 15 288 | #define GLFW_JOYSTICK_LAST GLFW_JOYSTICK_16 289 | 290 | 291 | //======================================================================== 292 | // Other definitions 293 | //======================================================================== 294 | 295 | // glfwOpenWindow modes 296 | #define GLFW_WINDOW 0x00010001 297 | #define GLFW_FULLSCREEN 0x00010002 298 | 299 | // glfwGetWindowParam tokens 300 | #define GLFW_OPENED 0x00020001 301 | #define GLFW_ACTIVE 0x00020002 302 | #define GLFW_ICONIFIED 0x00020003 303 | #define GLFW_ACCELERATED 0x00020004 304 | #define GLFW_RED_BITS 0x00020005 305 | #define GLFW_GREEN_BITS 0x00020006 306 | #define GLFW_BLUE_BITS 0x00020007 307 | #define GLFW_ALPHA_BITS 0x00020008 308 | #define GLFW_DEPTH_BITS 0x00020009 309 | #define GLFW_STENCIL_BITS 0x0002000A 310 | 311 | // The following constants are used for both glfwGetWindowParam 312 | // and glfwOpenWindowHint 313 | #define GLFW_REFRESH_RATE 0x0002000B 314 | #define GLFW_ACCUM_RED_BITS 0x0002000C 315 | #define GLFW_ACCUM_GREEN_BITS 0x0002000D 316 | #define GLFW_ACCUM_BLUE_BITS 0x0002000E 317 | #define GLFW_ACCUM_ALPHA_BITS 0x0002000F 318 | #define GLFW_AUX_BUFFERS 0x00020010 319 | #define GLFW_STEREO 0x00020011 320 | #define GLFW_WINDOW_NO_RESIZE 0x00020012 321 | #define GLFW_FSAA_SAMPLES 0x00020013 322 | 323 | // glfwEnable/glfwDisable tokens 324 | #define GLFW_MOUSE_CURSOR 0x00030001 325 | #define GLFW_STICKY_KEYS 0x00030002 326 | #define GLFW_STICKY_MOUSE_BUTTONS 0x00030003 327 | #define GLFW_SYSTEM_KEYS 0x00030004 328 | #define GLFW_KEY_REPEAT 0x00030005 329 | #define GLFW_AUTO_POLL_EVENTS 0x00030006 330 | 331 | // glfwWaitThread wait modes 332 | #define GLFW_WAIT 0x00040001 333 | #define GLFW_NOWAIT 0x00040002 334 | 335 | // glfwGetJoystickParam tokens 336 | #define GLFW_PRESENT 0x00050001 337 | #define GLFW_AXES 0x00050002 338 | #define GLFW_BUTTONS 0x00050003 339 | 340 | // glfwReadImage/glfwLoadTexture2D flags 341 | #define GLFW_NO_RESCALE_BIT 0x00000001 // Only for glfwReadImage 342 | #define GLFW_ORIGIN_UL_BIT 0x00000002 343 | #define GLFW_BUILD_MIPMAPS_BIT 0x00000004 // Only for glfwLoadTexture2D 344 | #define GLFW_ALPHA_MAP_BIT 0x00000008 345 | 346 | // Time spans longer than this (seconds) are considered to be infinity 347 | #define GLFW_INFINITY 100000.0 348 | 349 | 350 | //======================================================================== 351 | // Typedefs 352 | //======================================================================== 353 | 354 | // The video mode structure used by glfwGetVideoModes() 355 | typedef struct { 356 | int Width, Height; 357 | int RedBits, BlueBits, GreenBits; 358 | } GLFWvidmode; 359 | 360 | // Image/texture information 361 | typedef struct { 362 | int Width, Height; 363 | int Format; 364 | int BytesPerPixel; 365 | unsigned char *Data; 366 | } GLFWimage; 367 | 368 | // Thread ID 369 | typedef int GLFWthread; 370 | 371 | // Mutex object 372 | typedef void * GLFWmutex; 373 | 374 | // Condition variable object 375 | typedef void * GLFWcond; 376 | 377 | // Function pointer types 378 | typedef void (GLFWCALL * GLFWwindowsizefun)(int,int); 379 | typedef int (GLFWCALL * GLFWwindowclosefun)(void); 380 | typedef void (GLFWCALL * GLFWwindowrefreshfun)(void); 381 | typedef void (GLFWCALL * GLFWmousebuttonfun)(int,int); 382 | typedef void (GLFWCALL * GLFWmouseposfun)(int,int); 383 | typedef void (GLFWCALL * GLFWmousewheelfun)(int); 384 | typedef void (GLFWCALL * GLFWkeyfun)(int,int); 385 | typedef void (GLFWCALL * GLFWcharfun)(int,int); 386 | typedef void (GLFWCALL * GLFWthreadfun)(void *); 387 | 388 | 389 | //======================================================================== 390 | // Prototypes 391 | //======================================================================== 392 | 393 | /*! @file glfw.h 394 | */ 395 | // GLFW initialization, termination and version querying 396 | /*! @fn glfwInit 397 | */ 398 | GLFWAPI int GLFWAPIENTRY glfwInit( void ); 399 | GLFWAPI void GLFWAPIENTRY glfwTerminate( void ); 400 | GLFWAPI void GLFWAPIENTRY glfwGetVersion( int *major, int *minor, int *rev ); 401 | 402 | // Window handling 403 | GLFWAPI int GLFWAPIENTRY glfwOpenWindow( int width, int height, int redbits, int greenbits, int bluebits, int alphabits, int depthbits, int stencilbits, int mode ); 404 | GLFWAPI void GLFWAPIENTRY glfwOpenWindowHint( int target, int hint ); 405 | GLFWAPI void GLFWAPIENTRY glfwCloseWindow( void ); 406 | GLFWAPI void GLFWAPIENTRY glfwSetWindowTitle( const char *title ); 407 | GLFWAPI void GLFWAPIENTRY glfwGetWindowSize( int *width, int *height ); 408 | GLFWAPI void GLFWAPIENTRY glfwSetWindowSize( int width, int height ); 409 | GLFWAPI void GLFWAPIENTRY glfwSetWindowPos( int x, int y ); 410 | GLFWAPI void GLFWAPIENTRY glfwIconifyWindow( void ); 411 | GLFWAPI void GLFWAPIENTRY glfwRestoreWindow( void ); 412 | GLFWAPI void GLFWAPIENTRY glfwSwapBuffers( void ); 413 | GLFWAPI void GLFWAPIENTRY glfwSwapInterval( int interval ); 414 | GLFWAPI int GLFWAPIENTRY glfwGetWindowParam( int param ); 415 | GLFWAPI void GLFWAPIENTRY glfwSetWindowSizeCallback( GLFWwindowsizefun cbfun ); 416 | GLFWAPI void GLFWAPIENTRY glfwSetWindowCloseCallback( GLFWwindowclosefun cbfun ); 417 | GLFWAPI void GLFWAPIENTRY glfwSetWindowRefreshCallback( GLFWwindowrefreshfun cbfun ); 418 | 419 | // Video mode functions 420 | GLFWAPI int GLFWAPIENTRY glfwGetVideoModes( GLFWvidmode *list, int maxcount ); 421 | GLFWAPI void GLFWAPIENTRY glfwGetDesktopMode( GLFWvidmode *mode ); 422 | 423 | // Input handling 424 | GLFWAPI void GLFWAPIENTRY glfwPollEvents( void ); 425 | GLFWAPI void GLFWAPIENTRY glfwWaitEvents( void ); 426 | GLFWAPI int GLFWAPIENTRY glfwGetKey( int key ); 427 | GLFWAPI int GLFWAPIENTRY glfwGetMouseButton( int button ); 428 | GLFWAPI void GLFWAPIENTRY glfwGetMousePos( int *xpos, int *ypos ); 429 | GLFWAPI void GLFWAPIENTRY glfwSetMousePos( int xpos, int ypos ); 430 | GLFWAPI int GLFWAPIENTRY glfwGetMouseWheel( void ); 431 | GLFWAPI void GLFWAPIENTRY glfwSetMouseWheel( int pos ); 432 | GLFWAPI void GLFWAPIENTRY glfwSetKeyCallback( GLFWkeyfun cbfun ); 433 | GLFWAPI void GLFWAPIENTRY glfwSetCharCallback( GLFWcharfun cbfun ); 434 | GLFWAPI void GLFWAPIENTRY glfwSetMouseButtonCallback( GLFWmousebuttonfun cbfun ); 435 | GLFWAPI void GLFWAPIENTRY glfwSetMousePosCallback( GLFWmouseposfun cbfun ); 436 | GLFWAPI void GLFWAPIENTRY glfwSetMouseWheelCallback( GLFWmousewheelfun cbfun ); 437 | 438 | // Joystick input 439 | GLFWAPI int GLFWAPIENTRY glfwGetJoystickParam( int joy, int param ); 440 | GLFWAPI int GLFWAPIENTRY glfwGetJoystickPos( int joy, float *pos, int numaxes ); 441 | GLFWAPI int GLFWAPIENTRY glfwGetJoystickButtons( int joy, unsigned char *buttons, int numbuttons ); 442 | 443 | // Time 444 | GLFWAPI double GLFWAPIENTRY glfwGetTime( void ); 445 | GLFWAPI void GLFWAPIENTRY glfwSetTime( double time ); 446 | GLFWAPI void GLFWAPIENTRY glfwSleep( double time ); 447 | 448 | // Extension support 449 | GLFWAPI int GLFWAPIENTRY glfwExtensionSupported( const char *extension ); 450 | GLFWAPI void* GLFWAPIENTRY glfwGetProcAddress( const char *procname ); 451 | GLFWAPI void GLFWAPIENTRY glfwGetGLVersion( int *major, int *minor, int *rev ); 452 | 453 | // Threading support 454 | GLFWAPI GLFWthread GLFWAPIENTRY glfwCreateThread( GLFWthreadfun fun, void *arg ); 455 | GLFWAPI void GLFWAPIENTRY glfwDestroyThread( GLFWthread ID ); 456 | GLFWAPI int GLFWAPIENTRY glfwWaitThread( GLFWthread ID, int waitmode ); 457 | GLFWAPI GLFWthread GLFWAPIENTRY glfwGetThreadID( void ); 458 | GLFWAPI GLFWmutex GLFWAPIENTRY glfwCreateMutex( void ); 459 | GLFWAPI void GLFWAPIENTRY glfwDestroyMutex( GLFWmutex mutex ); 460 | GLFWAPI void GLFWAPIENTRY glfwLockMutex( GLFWmutex mutex ); 461 | GLFWAPI void GLFWAPIENTRY glfwUnlockMutex( GLFWmutex mutex ); 462 | GLFWAPI GLFWcond GLFWAPIENTRY glfwCreateCond( void ); 463 | GLFWAPI void GLFWAPIENTRY glfwDestroyCond( GLFWcond cond ); 464 | GLFWAPI void GLFWAPIENTRY glfwWaitCond( GLFWcond cond, GLFWmutex mutex, double timeout ); 465 | GLFWAPI void GLFWAPIENTRY glfwSignalCond( GLFWcond cond ); 466 | GLFWAPI void GLFWAPIENTRY glfwBroadcastCond( GLFWcond cond ); 467 | GLFWAPI int GLFWAPIENTRY glfwGetNumberOfProcessors( void ); 468 | 469 | // Enable/disable functions 470 | GLFWAPI void GLFWAPIENTRY glfwEnable( int token ); 471 | GLFWAPI void GLFWAPIENTRY glfwDisable( int token ); 472 | 473 | // Image/texture I/O support 474 | GLFWAPI int GLFWAPIENTRY glfwReadImage( const char *name, GLFWimage *img, int flags ); 475 | GLFWAPI int GLFWAPIENTRY glfwReadMemoryImage( const void *data, long size, GLFWimage *img, int flags ); 476 | GLFWAPI void GLFWAPIENTRY glfwFreeImage( GLFWimage *img ); 477 | GLFWAPI int GLFWAPIENTRY glfwLoadTexture2D( const char *name, int flags ); 478 | GLFWAPI int GLFWAPIENTRY glfwLoadMemoryTexture2D( const void *data, long size, int flags ); 479 | GLFWAPI int GLFWAPIENTRY glfwLoadTextureImage2D( GLFWimage *img, int flags ); 480 | 481 | 482 | #ifdef __cplusplus 483 | } 484 | #endif 485 | 486 | #endif // __glfw_h_ 487 | -------------------------------------------------------------------------------- /demo/Win32/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for bare-bones Mingw32 from a Windows command shell (no bash, no Cygwin) 2 | MINGW32 = C:/Dev-Cpp 3 | #MINGW32 = C:/mingw 4 | CC = gcc.exe 5 | SRC = noisedemo.c 6 | SHADERS = noisedemo.vert noisedemo.frag 7 | OBJ = noisedemo.o 8 | LINKOBJ = noisedemo.o 9 | LIBS = -L$(MINGW32)/lib -mwindows -lglfw -lopengl32 -lglu32 -mconsole -g3 10 | INCS = -I. -I$(MINGW32)/include 11 | CFLAGS = $(INCS) -Wall -O3 -ffast-math -g3 12 | EXECNAME = noisedemo.exe 13 | 14 | all: $(EXECNAME) 15 | 16 | clean: 17 | del $(OBJ) $(EXECNAME) $(SHADERS) $(OUTPUTFILE) $(SRC) 18 | 19 | noisedemo.vert: 20 | copy ..\common\noisedemo.vert . 21 | 22 | noisedemo.frag: 23 | copy ..\common\noisedemo.frag . 24 | 25 | $(SRC): 26 | copy ..\common\$(SRC) . 27 | 28 | $(OBJ): $(SRC) 29 | $(CC) -c $(SRC) -o $(OBJ) $(CFLAGS) 30 | 31 | $(EXECNAME): $(OBJ) $(SHADERS) 32 | $(CC) $(OBJ) -o $(EXECNAME) $(LIBS) 33 | 34 | run: $(EXECNAME) 35 | ./$(EXECNAME) 36 | -------------------------------------------------------------------------------- /demo/Win32/libglfw.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stegu/webgl-noise/22434e04d7753f7e949e8d724ab3da2864c17a0f/demo/Win32/libglfw.a -------------------------------------------------------------------------------- /demo/common/Makefile: -------------------------------------------------------------------------------- 1 | SRCDIR=../../src 2 | MAIN=noisedemoMain.frag 3 | SHADERS=noisedemo.frag 4 | 5 | all: $(SHADERS) 6 | 7 | clean: 8 | - rm $(SHADERS) 9 | 10 | noisedemo.frag: $(SRCDIR)/noise3D.glsl $(MAIN) 11 | cpp -P -I$(SRCDIR) -DSHADER=\"noise3D.glsl\" \ 12 | -DVERSION='#version 120' noisedemoMain.frag $@ 13 | -------------------------------------------------------------------------------- /demo/common/noisedemo.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Demo for GLSL procedural noise. 3 | * 4 | * The shaders are loaded from external files, named in 5 | * the macro definitions VERTSHADERFILE and FRAGSHADERFILE. 6 | * The main program draws a sphere covering most of the 7 | * viewport, activates the demo shader and runs indefinitely, 8 | * reporting the fragment shading performance in Msamples/s 9 | * while it executes. 10 | * 11 | * This program uses GLFW for convenience, to handle the OS-specific 12 | * window management stuff. Some Windows-specific stuff for extension 13 | * loading is still here, but that code is short-circuited on other 14 | * platforms - this file compiles unedited on Windows, Linux and MacOS X, 15 | * provided you have the relevant libraries and header files installed 16 | * and set up your compilation to include the GLFW and OpenGL libraries. 17 | * 18 | * Author: Stefan Gustavson (stefan.gustavson@liu.se) 2004, 2005, 2010, 2011 19 | * This code is in the public domain. 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #ifdef __WIN32__ 28 | // The system level include file for GL extensions might not be up to date. 29 | #include "GL/glext.h" 30 | #else 31 | #include 32 | #endif 33 | 34 | 35 | #ifdef __APPLE__ 36 | // MacOS application bundles have the executable inside a directory structure 37 | #define VERTSHADERFILE "../../../noisedemo.vert" 38 | #define FRAGSHADERFILE "../../../noisedemo.frag" 39 | #else 40 | // Windows, Linux and other Unix systems expose executables as naked files 41 | #define VERTSHADERFILE "noisedemo.vert" 42 | #define FRAGSHADERFILE "noisedemo.frag" 43 | #endif 44 | 45 | #ifdef __WIN32__ 46 | /* Global function pointers for everything we need beyond OpenGL 1.1 */ 47 | PFNGLCREATEPROGRAMPROC glCreateProgram = NULL; 48 | PFNGLDELETEPROGRAMPROC glDeleteProgram = NULL; 49 | PFNGLUSEPROGRAMPROC glUseProgram = NULL; 50 | PFNGLCREATESHADERPROC glCreateShader = NULL; 51 | PFNGLDELETESHADERPROC glDeleteShader = NULL; 52 | PFNGLSHADERSOURCEPROC glShaderSource = NULL; 53 | PFNGLCOMPILESHADERPROC glCompileShader = NULL; 54 | PFNGLGETSHADERIVPROC glGetShaderiv = NULL; 55 | PFNGLGETPROGRAMIVPROC glGetProgramiv = NULL; 56 | PFNGLATTACHSHADERPROC glAttachShader = NULL; 57 | PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog = NULL; 58 | PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog = NULL; 59 | PFNGLLINKPROGRAMPROC glLinkProgram = NULL; 60 | PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation = NULL; 61 | PFNGLUNIFORM1FVPROC glUniform1fv = NULL; 62 | #endif 63 | 64 | /* 65 | * printError() - Signal an error. 66 | * Simple printf() to console for portability. 67 | */ 68 | void printError(const char *errtype, const char *errmsg) { 69 | fprintf(stderr, "%s: %s\n", errtype, errmsg); 70 | } 71 | 72 | 73 | /* 74 | * Override the Win32 filelength() function with 75 | * a version that takes a Unix-style file handle as 76 | * input instead of a file ID number, and which works 77 | * on platforms other than Windows. 78 | */ 79 | long filelength(FILE *file) { 80 | long numbytes; 81 | long savedpos = ftell(file); 82 | fseek(file, 0, SEEK_END); 83 | numbytes = ftell(file); 84 | fseek(file, savedpos, SEEK_SET); 85 | return numbytes; 86 | } 87 | 88 | 89 | /* 90 | * loadExtensions() - Load OpenGL extensions for anything above OpenGL 91 | * version 1.1. (This is a requirement only on Windows, so on other 92 | * platforms, this function just checks for the required extensions.) 93 | */ 94 | void loadExtensions() { 95 | //These extension strings indicate that the OpenGL Shading Language 96 | // and GLSL shader objects are supported. 97 | if(!glfwExtensionSupported("GL_ARB_shading_language_100")) 98 | { 99 | printError("GL init error", "GL_ARB_shading_language_100 extension was not found"); 100 | return; 101 | } 102 | if(!glfwExtensionSupported("GL_ARB_shader_objects")) 103 | { 104 | printError("GL init error", "GL_ARB_shader_objects extension was not found"); 105 | return; 106 | } 107 | else 108 | { 109 | #ifdef __WIN32__ 110 | glCreateProgram = (PFNGLCREATEPROGRAMPROC)glfwGetProcAddress("glCreateProgram"); 111 | glDeleteProgram = (PFNGLDELETEPROGRAMPROC)glfwGetProcAddress("glDeleteProgram"); 112 | glUseProgram = (PFNGLUSEPROGRAMPROC)glfwGetProcAddress("glUseProgram"); 113 | glCreateShader = (PFNGLCREATESHADERPROC)glfwGetProcAddress("glCreateShader"); 114 | glDeleteShader = (PFNGLDELETESHADERPROC)glfwGetProcAddress("glDeleteShader"); 115 | glShaderSource = (PFNGLSHADERSOURCEPROC)glfwGetProcAddress("glShaderSource"); 116 | glCompileShader = (PFNGLCOMPILESHADERPROC)glfwGetProcAddress("glCompileShader"); 117 | glGetShaderiv = (PFNGLGETSHADERIVPROC)glfwGetProcAddress("glGetShaderiv"); 118 | glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)glfwGetProcAddress("glGetShaderInfoLog"); 119 | glAttachShader = (PFNGLATTACHSHADERPROC)glfwGetProcAddress("glAttachShader"); 120 | glLinkProgram = (PFNGLLINKPROGRAMPROC)glfwGetProcAddress("glLinkProgram"); 121 | glGetProgramiv = (PFNGLGETPROGRAMIVPROC)glfwGetProcAddress("glGetProgramiv"); 122 | glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)glfwGetProcAddress("glGetProgramInfoLog"); 123 | glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)glfwGetProcAddress("glGetUniformLocation"); 124 | glUniform1fv = (PFNGLUNIFORM1FVPROC)glfwGetProcAddress("glUniform1fv"); 125 | 126 | if( !glCreateProgram || !glDeleteProgram || !glUseProgram || 127 | !glCreateShader || !glDeleteShader || !glShaderSource || !glCompileShader || 128 | !glGetShaderiv || !glGetShaderInfoLog || !glAttachShader || !glLinkProgram || 129 | !glGetProgramiv || !glGetProgramInfoLog || !glGetUniformLocation || 130 | !glUniform1fv ) 131 | { 132 | printError("GL init error", "One or more required OpenGL functions were not found"); 133 | return; 134 | } 135 | #endif 136 | } 137 | } 138 | 139 | 140 | /* 141 | * readShaderFile(filename) - read a shader source string from a file 142 | */ 143 | unsigned char* readShaderFile(const char *filename) { 144 | FILE *file = fopen(filename, "r"); 145 | if(file == NULL) 146 | { 147 | printError("ERROR", "Cannot open shader file!"); 148 | return 0; 149 | } 150 | int bytesinfile = filelength(file); 151 | unsigned char *buffer = (unsigned char*)malloc(bytesinfile+1); 152 | int bytesread = fread( buffer, 1, bytesinfile, file); 153 | buffer[bytesread] = 0; // Terminate the string with 0 154 | fclose(file); 155 | 156 | return buffer; 157 | } 158 | 159 | 160 | /* 161 | * createShaders() - create, load, compile and link the GLSL shader objects. 162 | */ 163 | void createShader(GLuint *programObject, char *vertexshaderfile, char *fragmentshaderfile) { 164 | GLuint vertexShader; 165 | GLuint fragmentShader; 166 | 167 | const char *vertexShaderStrings[1]; 168 | const char *fragmentShaderStrings[1]; 169 | GLint vertexCompiled; 170 | GLint fragmentCompiled; 171 | GLint shadersLinked; 172 | char str[4096]; // For error messages from the GLSL compiler and linker 173 | 174 | // Create the vertex shader. 175 | vertexShader = glCreateShader(GL_VERTEX_SHADER); 176 | 177 | unsigned char *vertexShaderAssembly = readShaderFile( vertexshaderfile ); 178 | vertexShaderStrings[0] = (char*)vertexShaderAssembly; 179 | glShaderSource( vertexShader, 1, vertexShaderStrings, NULL ); 180 | glCompileShader( vertexShader); 181 | free((void *)vertexShaderAssembly); 182 | 183 | glGetShaderiv( vertexShader, GL_COMPILE_STATUS, 184 | &vertexCompiled ); 185 | if(vertexCompiled == GL_FALSE) 186 | { 187 | glGetShaderInfoLog(vertexShader, sizeof(str), NULL, str); 188 | printError("Vertex shader compile error", str); 189 | } 190 | 191 | // Create the fragment shader. 192 | fragmentShader = glCreateShader( GL_FRAGMENT_SHADER ); 193 | 194 | unsigned char *fragmentShaderAssembly = readShaderFile( fragmentshaderfile ); 195 | fragmentShaderStrings[0] = (char*)fragmentShaderAssembly; 196 | glShaderSource( fragmentShader, 1, fragmentShaderStrings, NULL ); 197 | glCompileShader( fragmentShader ); 198 | free((void *)fragmentShaderAssembly); 199 | 200 | glGetProgramiv( fragmentShader, GL_COMPILE_STATUS, 201 | &fragmentCompiled ); 202 | if(fragmentCompiled == GL_FALSE) 203 | { 204 | glGetShaderInfoLog( fragmentShader, sizeof(str), NULL, str ); 205 | printError("Fragment shader compile error", str); 206 | } 207 | 208 | // Create a program object and attach the two compiled shaders. 209 | *programObject = glCreateProgram(); 210 | glAttachShader( *programObject, vertexShader ); 211 | glAttachShader( *programObject, fragmentShader ); 212 | 213 | // Link the program object and print out the info log. 214 | glLinkProgram( *programObject ); 215 | glGetProgramiv( *programObject, GL_LINK_STATUS, &shadersLinked ); 216 | 217 | if( shadersLinked == GL_FALSE ) 218 | { 219 | glGetProgramInfoLog( *programObject, sizeof(str), NULL, str ); 220 | printError("Program object linking error", str); 221 | } 222 | } 223 | 224 | 225 | /* 226 | * computeFPS() - Calculate, display and return samples per second. 227 | * Stats are recomputed only once per second. 228 | */ 229 | double computeFPS() { 230 | 231 | static double t0 = 0.0; 232 | static int frames = 0; 233 | static double fps = 0.0; 234 | static char titlestring[200]; 235 | 236 | double t; 237 | int width, height; 238 | 239 | // Get current time 240 | t = glfwGetTime(); // Gets number of seconds since glfwInit() 241 | // If one second has passed, or if this is the very first frame 242 | if( (t-t0) > 1.0 || frames == 0 ) 243 | { 244 | fps = (double)frames / (t-t0); 245 | sprintf(titlestring, "GLSL noise demo (%.1f FPS)", fps); 246 | glfwSetWindowTitle(titlestring); 247 | t0 = t; 248 | frames = 0; 249 | } 250 | frames ++; 251 | return fps; 252 | } 253 | 254 | 255 | /* 256 | * drawTexturedSphere(r, segs) - Draw a sphere centered on the local 257 | * origin, with radius r and approximated by segs polygon segments, 258 | * having texture coordinates with a latitude-longitude mapping. 259 | * Yes, this is ugly old school immediate mode, but this is being 260 | * baked to a display list anyway, and that ends up being sent 261 | * to the GPU as a VBO. Desides, I had this code written already. 262 | */ 263 | void drawTexturedSphere(float r, int segs) { 264 | int i, j; 265 | float x, y, z, z1, z2, R, R1, R2; 266 | 267 | // Top cap 268 | glBegin(GL_TRIANGLE_FAN); 269 | glNormal3f(0,0,1); 270 | glTexCoord2f(0.5f,1.0f); // This is an ugly (u,v)-mapping singularity 271 | glVertex3f(0,0,r); 272 | z = cos(M_PI/segs); 273 | R = sin(M_PI/segs); 274 | for(i = 0; i <= 2*segs; i++) { 275 | x = R*cos(i*2.0*M_PI/(2*segs)); 276 | y = R*sin(i*2.0*M_PI/(2*segs)); 277 | glNormal3f(x, y, z); 278 | glTexCoord2f((float)i/(2*segs), 1.0f-1.0f/segs); 279 | glVertex3f(r*x, r*y, r*z); 280 | } 281 | glEnd(); 282 | 283 | // Height segments 284 | for(j = 1; j < segs-1; j++) { 285 | z1 = cos(j*M_PI/segs); 286 | R1 = sin(j*M_PI/segs); 287 | z2 = cos((j+1)*M_PI/segs); 288 | R2 = sin((j+1)*M_PI/segs); 289 | glBegin(GL_TRIANGLE_STRIP); 290 | for(i = 0; i <= 2*segs; i++) { 291 | x = R1*cos(i*2.0*M_PI/(2*segs)); 292 | y = R1*sin(i*2.0*M_PI/(2*segs)); 293 | glNormal3f(x, y, z1); 294 | glTexCoord2f((float)i/(2*segs), 1.0f-(float)j/segs); 295 | glVertex3f(r*x, r*y, r*z1); 296 | x = R2*cos(i*2.0*M_PI/(2*segs)); 297 | y = R2*sin(i*2.0*M_PI/(2*segs)); 298 | glNormal3f(x, y, z2); 299 | glTexCoord2f((float)i/(2*segs), 1.0f-(float)(j+1)/segs); 300 | glVertex3f(r*x, r*y, r*z2); 301 | } 302 | glEnd(); 303 | } 304 | 305 | // Bottom cap 306 | glBegin(GL_TRIANGLE_FAN); 307 | glNormal3f(0,0,-1); 308 | glTexCoord2f(0.5f, 1.0f); // This is an ugly (u,v)-mapping singularity 309 | glVertex3f(0,0,-r); 310 | z = -cos(M_PI/segs); 311 | R = sin(M_PI/segs); 312 | for(i = 2*segs; i >= 0; i--) { 313 | x = R*cos(i*2.0*M_PI/(2*segs)); 314 | y = R*sin(i*2.0*M_PI/(2*segs)); 315 | glNormal3f(x, y, z); 316 | glTexCoord2f(1.0f-(float)i/(2*segs), 1.0f/segs); 317 | glVertex3f(r*x, r*y, r*z); 318 | } 319 | glEnd(); 320 | } 321 | 322 | 323 | /* 324 | * initDisplayList(GLuint *listID, GLdouble scale) - create a display list 325 | * to render the demo geometry more efficently than by glVertex() calls. 326 | * (This is currently just as fast as a VBO, and I'm a bit lazy.) 327 | */ 328 | void initDisplayList(GLuint *listID) 329 | { 330 | *listID = glGenLists(1); 331 | 332 | glNewList(*listID, GL_COMPILE); 333 | glColor3f(1.0f, 1.0f, 1.0f); // White base color 334 | drawTexturedSphere(1.0, 20); 335 | glEndList(); 336 | } 337 | 338 | 339 | /* 340 | * setupCamera() - set up the OpenGL projection and (model)view matrices 341 | */ 342 | void setupCamera() { 343 | 344 | int width, height; 345 | 346 | // Get window size. It may start out different from the requested 347 | // size, and will change if the user resizes the window. 348 | glfwGetWindowSize( &width, &height ); 349 | if(height<=0) height=1; // Safeguard against iconified/closed window 350 | 351 | // Set viewport. This is the pixel rectangle we want to draw into. 352 | glViewport( 0, 0, width, height ); // The entire window 353 | 354 | // Select and setup the projection matrix. 355 | glMatrixMode(GL_PROJECTION); // "We want to edit the projection matrix" 356 | glLoadIdentity(); // Reset the matrix to identity 357 | // 45 degrees FOV, same aspect ratio as viewport, depth range 1 to 100 358 | gluPerspective( 45.0f, (GLfloat)width/(GLfloat)height, 1.0f, 100.0f ); 359 | 360 | // Select and setup the modelview matrix. 361 | glMatrixMode( GL_MODELVIEW ); // "We want to edit the modelview matrix" 362 | glLoadIdentity(); // Reset the matrix to identity 363 | // Look from 0,-3,0 towards 0,0,0 with Z as "up" in the image 364 | gluLookAt( 0.0f, -3.0f, 0.0f, // Eye position 365 | 0.0f, 0.0f, 0.0f, // View point 366 | 0.0f, 0.0f, 1.0f ); // Up vector 367 | } 368 | 369 | 370 | /* 371 | * renderScene() - draw the scene with the shader active 372 | */ 373 | void renderScene( GLuint listID, GLuint programObject ) 374 | { 375 | GLint location_time = -1; 376 | float time = 0.0f; 377 | 378 | // Use vertex and fragment shaders. 379 | glUseProgram( programObject ); 380 | // Update the uniform time variable. 381 | location_time = glGetUniformLocation( programObject, "time" ); 382 | // glUniform1f() is bugged in Linux Nvidia driver 260.19.06, 383 | // so we use glUniform1fv() instead to work around the bug. 384 | if ( location_time != -1 ) { 385 | time = (float)glfwGetTime(); 386 | glUniform1fv( location_time, 1, &time ); 387 | } 388 | glRotatef(30.0f, 1.0f, 0.0f, 0.0f); 389 | // Render with the shaders active. 390 | glCallList( listID ); 391 | // Deactivate the shaders. 392 | glUseProgram(0); 393 | } 394 | 395 | 396 | /* 397 | * main(argc, argv) - the standard C entry point for the program 398 | */ 399 | int main(int argc, char *argv[]) { 400 | 401 | GLuint displayList; 402 | GLuint programObject; 403 | double performance = 0.0; 404 | 405 | GLboolean running = GL_TRUE; // Main loop exits when this is set to GL_FALSE 406 | 407 | // Initialise GLFW 408 | glfwInit(); 409 | 410 | // Open an OpenGL window 411 | if( !glfwOpenWindow(512, 512, 8,8,8,8, 32,0, GLFW_WINDOW) ) 412 | { 413 | glfwTerminate(); // glfwOpenWindow failed, quit the program. 414 | return 1; 415 | } 416 | 417 | // Load the extensions for GLSL - note that this has to be done 418 | // *after* the window has been opened, or we won't have a GL context 419 | // to query for those extensions and connect to instances of them. 420 | loadExtensions(); 421 | 422 | // Enable Z buffering (not needed for the sphere, but play nice) 423 | glEnable(GL_DEPTH_TEST); // Use the Z buffer 424 | 425 | glfwSwapInterval(0); // Do not wait for screen refresh between frames 426 | 427 | // Compile a display list for the demo geometry, to render it efficiently 428 | initDisplayList(&displayList); 429 | 430 | // Create the shader we are going to use 431 | createShader(&programObject, VERTSHADERFILE, FRAGSHADERFILE); 432 | 433 | // Main loop 434 | while(running) 435 | { 436 | // Calculate and update the frames per second (FPS) display 437 | performance = computeFPS(); 438 | 439 | // Clear the frame buffer 440 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 441 | 442 | // Set up the camera projection. 443 | setupCamera(); 444 | 445 | // Draw the scene. 446 | renderScene(displayList, programObject); 447 | 448 | // Swap buffers, i.e. display the image and prepare for next frame. 449 | glfwSwapBuffers(); 450 | 451 | // Exit if the ESC key is pressed or the window is closed. 452 | if(glfwGetKey(GLFW_KEY_ESC) || !glfwGetWindowParam(GLFW_OPENED)) { 453 | running = GL_FALSE; 454 | } 455 | 456 | } 457 | 458 | // Close the OpenGL window and terminate GLFW. 459 | glfwTerminate(); 460 | 461 | return 0; 462 | } 463 | -------------------------------------------------------------------------------- /demo/common/noisedemo.vert: -------------------------------------------------------------------------------- 1 | #version 120 2 | 3 | uniform float time; 4 | varying vec3 v_texCoord3D; 5 | 6 | void main( void ) 7 | { 8 | gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; 9 | v_texCoord3D = gl_Vertex.xyz; 10 | } 11 | -------------------------------------------------------------------------------- /demo/common/noisedemoMain.frag: -------------------------------------------------------------------------------- 1 | VERSION 2 | 3 | #include SHADER 4 | 5 | uniform float time; // Used for texture animation 6 | 7 | varying vec3 v_texCoord3D; 8 | 9 | // 10 | // main() 11 | // 12 | void main( void ) 13 | { 14 | #if (1) 15 | // Perturb the texcoords with three components of noise 16 | vec3 uvw = v_texCoord3D + 0.1*vec3(snoise(v_texCoord3D + vec3(0.0, 0.0, time)), 17 | snoise(v_texCoord3D + vec3(43.0, 17.0, time)), 18 | snoise(v_texCoord3D + vec3(-17.0, -43.0, time))); 19 | // Six components of noise in a fractal sum 20 | float n = snoise(uvw - vec3(0.0, 0.0, time)); 21 | n += 0.5 * snoise(uvw * 2.0 - vec3(0.0, 0.0, time*1.4)); 22 | n += 0.25 * snoise(uvw * 4.0 - vec3(0.0, 0.0, time*2.0)); 23 | n += 0.125 * snoise(uvw * 8.0 - vec3(0.0, 0.0, time*2.8)); 24 | n += 0.0625 * snoise(uvw * 16.0 - vec3(0.0, 0.0, time*4.0)); 25 | n += 0.03125 * snoise(uvw * 32.0 - vec3(0.0, 0.0, time*5.6)); 26 | n = n * 0.7; 27 | // A "hot" colormap - cheesy but effective 28 | gl_FragColor = vec4(vec3(1.0, 0.5, 0.0) + vec3(n, n, n), 1.0); 29 | #else 30 | // A very plain monochrome noise 31 | float n = snoise(v_texCoord3D * 6.0); 32 | gl_FragColor = vec4(0.5 + 0.5 * vec3(n, n, n), 1.0); 33 | #endif 34 | } 35 | -------------------------------------------------------------------------------- /src/README: -------------------------------------------------------------------------------- 1 | These files contain noise functions that are compatible with all 2 | current versions of GLSL (1.20 and up), and all you need to use them 3 | is provided in the source file. There is no external data, and no 4 | setup procedure. Just cut and paste and call the function. 5 | 6 | GLSL has a very rudimentary linker, so some helper functions are 7 | included in several of the files with the same name. If you want to 8 | use more than one of these functions in the same shader, you may run 9 | into problems with redefinition of the functions mod289() and permute(). 10 | If that happens, just delete any superfluous definitions. 11 | -------------------------------------------------------------------------------- /src/cellular2D.glsl: -------------------------------------------------------------------------------- 1 | #version 120 2 | 3 | // Cellular noise ("Worley noise") in 2D in GLSL. 4 | // Copyright (c) Stefan Gustavson 2011-04-19. All rights reserved. 5 | // This code is released under the conditions of the MIT license. 6 | // See LICENSE file for details. 7 | // https://github.com/stegu/webgl-noise 8 | 9 | // Modulo 289 without a division (only multiplications) 10 | vec3 mod289(vec3 x) { 11 | return x - floor(x * (1.0 / 289.0)) * 289.0; 12 | } 13 | 14 | vec2 mod289(vec2 x) { 15 | return x - floor(x * (1.0 / 289.0)) * 289.0; 16 | } 17 | 18 | // Modulo 7 without a division 19 | vec3 mod7(vec3 x) { 20 | return x - floor(x * (1.0 / 7.0)) * 7.0; 21 | } 22 | 23 | // Permutation polynomial: (34x^2 + 10x) mod 289 24 | vec3 permute(vec3 x) { 25 | return mod289((34.0 * x + 10.0) * x); 26 | } 27 | 28 | // Cellular noise, returning F1 and F2 in a vec2. 29 | // Standard 3x3 search window for good F1 and F2 values 30 | vec2 cellular(vec2 P) { 31 | #define K 0.142857142857 // 1/7 32 | #define Ko 0.428571428571 // 3/7 33 | #define jitter 1.0 // Less gives more regular pattern 34 | vec2 Pi = mod289(floor(P)); 35 | vec2 Pf = fract(P); 36 | vec3 oi = vec3(-1.0, 0.0, 1.0); 37 | vec3 of = vec3(-0.5, 0.5, 1.5); 38 | vec3 px = permute(Pi.x + oi); 39 | vec3 p = permute(px.x + Pi.y + oi); // p11, p12, p13 40 | vec3 ox = fract(p*K) - Ko; 41 | vec3 oy = mod7(floor(p*K))*K - Ko; 42 | vec3 dx = Pf.x + 0.5 + jitter*ox; 43 | vec3 dy = Pf.y - of + jitter*oy; 44 | vec3 d1 = dx * dx + dy * dy; // d11, d12 and d13, squared 45 | p = permute(px.y + Pi.y + oi); // p21, p22, p23 46 | ox = fract(p*K) - Ko; 47 | oy = mod7(floor(p*K))*K - Ko; 48 | dx = Pf.x - 0.5 + jitter*ox; 49 | dy = Pf.y - of + jitter*oy; 50 | vec3 d2 = dx * dx + dy * dy; // d21, d22 and d23, squared 51 | p = permute(px.z + Pi.y + oi); // p31, p32, p33 52 | ox = fract(p*K) - Ko; 53 | oy = mod7(floor(p*K))*K - Ko; 54 | dx = Pf.x - 1.5 + jitter*ox; 55 | dy = Pf.y - of + jitter*oy; 56 | vec3 d3 = dx * dx + dy * dy; // d31, d32 and d33, squared 57 | // Sort out the two smallest distances (F1, F2) 58 | vec3 d1a = min(d1, d2); 59 | d2 = max(d1, d2); // Swap to keep candidates for F2 60 | d2 = min(d2, d3); // neither F1 nor F2 are now in d3 61 | d1 = min(d1a, d2); // F1 is now in d1 62 | d2 = max(d1a, d2); // Swap to keep candidates for F2 63 | d1.xy = (d1.x < d1.y) ? d1.xy : d1.yx; // Swap if smaller 64 | d1.xz = (d1.x < d1.z) ? d1.xz : d1.zx; // F1 is in d1.x 65 | d1.yz = min(d1.yz, d2.yz); // F2 is now not in d2.yz 66 | d1.y = min(d1.y, d1.z); // nor in d1.z 67 | d1.y = min(d1.y, d2.x); // F2 is in d1.y, we're done. 68 | return sqrt(d1.xy); 69 | } 70 | -------------------------------------------------------------------------------- /src/cellular2x2.glsl: -------------------------------------------------------------------------------- 1 | #version 120 2 | 3 | // Cellular noise ("Worley noise") in 2D in GLSL. 4 | // Copyright (c) Stefan Gustavson 2011-04-19. All rights reserved. 5 | // This code is released under the conditions of the MIT license. 6 | // See LICENSE file for details. 7 | // https://github.com/stegu/webgl-noise 8 | 9 | // Modulo 289 without a division (only multiplications) 10 | vec2 mod289(vec2 x) { 11 | return x - floor(x * (1.0 / 289.0)) * 289.0; 12 | } 13 | 14 | vec4 mod289(vec4 x) { 15 | return x - floor(x * (1.0 / 289.0)) * 289.0; 16 | } 17 | 18 | // Modulo 7 without a division 19 | vec4 mod7(vec4 x) { 20 | return x - floor(x * (1.0 / 7.0)) * 7.0; 21 | } 22 | 23 | // Permutation polynomial: (34x^2 + 6x) mod 289 24 | vec4 permute(vec4 x) { 25 | return mod289((34.0 * x + 10.0) * x); 26 | } 27 | 28 | // Cellular noise, returning F1 and F2 in a vec2. 29 | // Speeded up by using 2x2 search window instead of 3x3, 30 | // at the expense of some strong pattern artifacts. 31 | // F2 is often wrong and has sharp discontinuities. 32 | // If you need a smooth F2, use the slower 3x3 version. 33 | // F1 is sometimes wrong, too, but OK for most purposes. 34 | vec2 cellular2x2(vec2 P) { 35 | #define K 0.142857142857 // 1/7 36 | #define K2 0.0714285714285 // K/2 37 | #define jitter 0.8 // jitter 1.0 makes F1 wrong more often 38 | vec2 Pi = mod289(floor(P)); 39 | vec2 Pf = fract(P); 40 | vec4 Pfx = Pf.x + vec4(-0.5, -1.5, -0.5, -1.5); 41 | vec4 Pfy = Pf.y + vec4(-0.5, -0.5, -1.5, -1.5); 42 | vec4 p = permute(Pi.x + vec4(0.0, 1.0, 0.0, 1.0)); 43 | p = permute(p + Pi.y + vec4(0.0, 0.0, 1.0, 1.0)); 44 | vec4 ox = mod7(p)*K+K2; 45 | vec4 oy = mod7(floor(p*K))*K+K2; 46 | vec4 dx = Pfx + jitter*ox; 47 | vec4 dy = Pfy + jitter*oy; 48 | vec4 d = dx * dx + dy * dy; // d11, d12, d21 and d22, squared 49 | // Sort out the two smallest distances 50 | #if 0 51 | // Cheat and pick only F1 52 | d.xy = min(d.xy, d.zw); 53 | d.x = min(d.x, d.y); 54 | return vec2(sqrt(d.x)); // F1 duplicated, F2 not computed 55 | #else 56 | // Do it right and find both F1 and F2 57 | d.xy = (d.x < d.y) ? d.xy : d.yx; // Swap if smaller 58 | d.xz = (d.x < d.z) ? d.xz : d.zx; 59 | d.xw = (d.x < d.w) ? d.xw : d.wx; 60 | d.y = min(d.y, d.z); 61 | d.y = min(d.y, d.w); 62 | return sqrt(d.xy); 63 | #endif 64 | } 65 | -------------------------------------------------------------------------------- /src/cellular2x2x2.glsl: -------------------------------------------------------------------------------- 1 | #version 120 2 | 3 | // Cellular noise ("Worley noise") in 3D in GLSL. 4 | // Copyright (c) Stefan Gustavson 2011-04-19. All rights reserved. 5 | // This code is released under the conditions of the MIT license. 6 | // See LICENSE file for details. 7 | // https://github.com/stegu/webgl-noise 8 | 9 | // Modulo 289 without a division (only multiplications) 10 | vec3 mod289(vec3 x) { 11 | return x - floor(x * (1.0 / 289.0)) * 289.0; 12 | } 13 | 14 | vec4 mod289(vec4 x) { 15 | return x - floor(x * (1.0 / 289.0)) * 289.0; 16 | } 17 | 18 | // Modulo 7 without a division 19 | vec4 mod7(vec4 x) { 20 | return x - floor(x * (1.0 / 7.0)) * 7.0; 21 | } 22 | 23 | 24 | // Permutation polynomial: (34x^2 + 6x) mod 289 25 | vec3 permute(vec3 x) { 26 | return mod289((34.0 * x + 10.0) * x); 27 | } 28 | 29 | vec4 permute(vec4 x) { 30 | return mod289((34.0 * x + 10.0) * x); 31 | } 32 | 33 | // Cellular noise, returning F1 and F2 in a vec2. 34 | // Speeded up by using 2x2x2 search window instead of 3x3x3, 35 | // at the expense of some pattern artifacts. 36 | // F2 is often wrong and has sharp discontinuities. 37 | // If you need a good F2, use the slower 3x3x3 version. 38 | vec2 cellular2x2x2(vec3 P) { 39 | #define K 0.142857142857 // 1/7 40 | #define Ko 0.428571428571 // 1/2-K/2 41 | #define K2 0.020408163265306 // 1/(7*7) 42 | #define Kz 0.166666666667 // 1/6 43 | #define Kzo 0.416666666667 // 1/2-1/6*2 44 | #define jitter 0.8 // smaller jitter gives less errors in F2 45 | vec3 Pi = mod289(floor(P)); 46 | vec3 Pf = fract(P); 47 | vec4 Pfx = Pf.x + vec4(0.0, -1.0, 0.0, -1.0); 48 | vec4 Pfy = Pf.y + vec4(0.0, 0.0, -1.0, -1.0); 49 | vec4 p = permute(Pi.x + vec4(0.0, 1.0, 0.0, 1.0)); 50 | p = permute(p + Pi.y + vec4(0.0, 0.0, 1.0, 1.0)); 51 | vec4 p1 = permute(p + Pi.z); // z+0 52 | vec4 p2 = permute(p + Pi.z + vec4(1.0)); // z+1 53 | vec4 ox1 = fract(p1*K) - Ko; 54 | vec4 oy1 = mod7(floor(p1*K))*K - Ko; 55 | vec4 oz1 = floor(p1*K2)*Kz - Kzo; // p1 < 289 guaranteed 56 | vec4 ox2 = fract(p2*K) - Ko; 57 | vec4 oy2 = mod7(floor(p2*K))*K - Ko; 58 | vec4 oz2 = floor(p2*K2)*Kz - Kzo; 59 | vec4 dx1 = Pfx + jitter*ox1; 60 | vec4 dy1 = Pfy + jitter*oy1; 61 | vec4 dz1 = Pf.z + jitter*oz1; 62 | vec4 dx2 = Pfx + jitter*ox2; 63 | vec4 dy2 = Pfy + jitter*oy2; 64 | vec4 dz2 = Pf.z - 1.0 + jitter*oz2; 65 | vec4 d1 = dx1 * dx1 + dy1 * dy1 + dz1 * dz1; // z+0 66 | vec4 d2 = dx2 * dx2 + dy2 * dy2 + dz2 * dz2; // z+1 67 | 68 | // Sort out the two smallest distances (F1, F2) 69 | #if 0 70 | // Cheat and sort out only F1 71 | d1 = min(d1, d2); 72 | d1.xy = min(d1.xy, d1.wz); 73 | d1.x = min(d1.x, d1.y); 74 | return vec2(sqrt(d1.x)); 75 | #else 76 | // Do it right and sort out both F1 and F2 77 | vec4 d = min(d1,d2); // F1 is now in d 78 | d2 = max(d1,d2); // Make sure we keep all candidates for F2 79 | d.xy = (d.x < d.y) ? d.xy : d.yx; // Swap smallest to d.x 80 | d.xz = (d.x < d.z) ? d.xz : d.zx; 81 | d.xw = (d.x < d.w) ? d.xw : d.wx; // F1 is now in d.x 82 | d.yzw = min(d.yzw, d2.yzw); // F2 now not in d2.yzw 83 | d.y = min(d.y, d.z); // nor in d.z 84 | d.y = min(d.y, d.w); // nor in d.w 85 | d.y = min(d.y, d2.x); // F2 is now in d.y 86 | return sqrt(d.xy); // F1 and F2 87 | #endif 88 | } 89 | -------------------------------------------------------------------------------- /src/cellular3D.glsl: -------------------------------------------------------------------------------- 1 | #version 120 2 | 3 | // Cellular noise ("Worley noise") in 3D in GLSL. 4 | // Copyright (c) Stefan Gustavson 2011-04-19. All rights reserved. 5 | // This code is released under the conditions of the MIT license. 6 | // See LICENSE file for details. 7 | // https://github.com/stegu/webgl-noise 8 | 9 | // Modulo 289 without a division (only multiplications) 10 | vec3 mod289(vec3 x) { 11 | return x - floor(x * (1.0 / 289.0)) * 289.0; 12 | } 13 | 14 | // Modulo 7 without a division 15 | vec3 mod7(vec3 x) { 16 | return x - floor(x * (1.0 / 7.0)) * 7.0; 17 | } 18 | 19 | // Permutation polynomial: (34x^2 + 6x) mod 289 20 | vec3 permute(vec3 x) { 21 | return mod289((34.0 * x + 10.0) * x); 22 | } 23 | 24 | // Cellular noise, returning F1 and F2 in a vec2. 25 | // 3x3x3 search region for good F2 everywhere, but a lot 26 | // slower than the 2x2x2 version. 27 | // The code below is a bit scary even to its author, 28 | // but it has at least half decent performance on a 29 | // modern GPU. In any case, it beats any software 30 | // implementation of Worley noise hands down. 31 | 32 | vec2 cellular(vec3 P) { 33 | #define K 0.142857142857 // 1/7 34 | #define Ko 0.428571428571 // 1/2-K/2 35 | #define K2 0.020408163265306 // 1/(7*7) 36 | #define Kz 0.166666666667 // 1/6 37 | #define Kzo 0.416666666667 // 1/2-1/6*2 38 | #define jitter 1.0 // smaller jitter gives more regular pattern 39 | 40 | vec3 Pi = mod289(floor(P)); 41 | vec3 Pf = fract(P) - 0.5; 42 | 43 | vec3 Pfx = Pf.x + vec3(1.0, 0.0, -1.0); 44 | vec3 Pfy = Pf.y + vec3(1.0, 0.0, -1.0); 45 | vec3 Pfz = Pf.z + vec3(1.0, 0.0, -1.0); 46 | 47 | vec3 p = permute(Pi.x + vec3(-1.0, 0.0, 1.0)); 48 | vec3 p1 = permute(p + Pi.y - 1.0); 49 | vec3 p2 = permute(p + Pi.y); 50 | vec3 p3 = permute(p + Pi.y + 1.0); 51 | 52 | vec3 p11 = permute(p1 + Pi.z - 1.0); 53 | vec3 p12 = permute(p1 + Pi.z); 54 | vec3 p13 = permute(p1 + Pi.z + 1.0); 55 | 56 | vec3 p21 = permute(p2 + Pi.z - 1.0); 57 | vec3 p22 = permute(p2 + Pi.z); 58 | vec3 p23 = permute(p2 + Pi.z + 1.0); 59 | 60 | vec3 p31 = permute(p3 + Pi.z - 1.0); 61 | vec3 p32 = permute(p3 + Pi.z); 62 | vec3 p33 = permute(p3 + Pi.z + 1.0); 63 | 64 | vec3 ox11 = fract(p11*K) - Ko; 65 | vec3 oy11 = mod7(floor(p11*K))*K - Ko; 66 | vec3 oz11 = floor(p11*K2)*Kz - Kzo; // p11 < 289 guaranteed 67 | 68 | vec3 ox12 = fract(p12*K) - Ko; 69 | vec3 oy12 = mod7(floor(p12*K))*K - Ko; 70 | vec3 oz12 = floor(p12*K2)*Kz - Kzo; 71 | 72 | vec3 ox13 = fract(p13*K) - Ko; 73 | vec3 oy13 = mod7(floor(p13*K))*K - Ko; 74 | vec3 oz13 = floor(p13*K2)*Kz - Kzo; 75 | 76 | vec3 ox21 = fract(p21*K) - Ko; 77 | vec3 oy21 = mod7(floor(p21*K))*K - Ko; 78 | vec3 oz21 = floor(p21*K2)*Kz - Kzo; 79 | 80 | vec3 ox22 = fract(p22*K) - Ko; 81 | vec3 oy22 = mod7(floor(p22*K))*K - Ko; 82 | vec3 oz22 = floor(p22*K2)*Kz - Kzo; 83 | 84 | vec3 ox23 = fract(p23*K) - Ko; 85 | vec3 oy23 = mod7(floor(p23*K))*K - Ko; 86 | vec3 oz23 = floor(p23*K2)*Kz - Kzo; 87 | 88 | vec3 ox31 = fract(p31*K) - Ko; 89 | vec3 oy31 = mod7(floor(p31*K))*K - Ko; 90 | vec3 oz31 = floor(p31*K2)*Kz - Kzo; 91 | 92 | vec3 ox32 = fract(p32*K) - Ko; 93 | vec3 oy32 = mod7(floor(p32*K))*K - Ko; 94 | vec3 oz32 = floor(p32*K2)*Kz - Kzo; 95 | 96 | vec3 ox33 = fract(p33*K) - Ko; 97 | vec3 oy33 = mod7(floor(p33*K))*K - Ko; 98 | vec3 oz33 = floor(p33*K2)*Kz - Kzo; 99 | 100 | vec3 dx11 = Pfx + jitter*ox11; 101 | vec3 dy11 = Pfy.x + jitter*oy11; 102 | vec3 dz11 = Pfz.x + jitter*oz11; 103 | 104 | vec3 dx12 = Pfx + jitter*ox12; 105 | vec3 dy12 = Pfy.x + jitter*oy12; 106 | vec3 dz12 = Pfz.y + jitter*oz12; 107 | 108 | vec3 dx13 = Pfx + jitter*ox13; 109 | vec3 dy13 = Pfy.x + jitter*oy13; 110 | vec3 dz13 = Pfz.z + jitter*oz13; 111 | 112 | vec3 dx21 = Pfx + jitter*ox21; 113 | vec3 dy21 = Pfy.y + jitter*oy21; 114 | vec3 dz21 = Pfz.x + jitter*oz21; 115 | 116 | vec3 dx22 = Pfx + jitter*ox22; 117 | vec3 dy22 = Pfy.y + jitter*oy22; 118 | vec3 dz22 = Pfz.y + jitter*oz22; 119 | 120 | vec3 dx23 = Pfx + jitter*ox23; 121 | vec3 dy23 = Pfy.y + jitter*oy23; 122 | vec3 dz23 = Pfz.z + jitter*oz23; 123 | 124 | vec3 dx31 = Pfx + jitter*ox31; 125 | vec3 dy31 = Pfy.z + jitter*oy31; 126 | vec3 dz31 = Pfz.x + jitter*oz31; 127 | 128 | vec3 dx32 = Pfx + jitter*ox32; 129 | vec3 dy32 = Pfy.z + jitter*oy32; 130 | vec3 dz32 = Pfz.y + jitter*oz32; 131 | 132 | vec3 dx33 = Pfx + jitter*ox33; 133 | vec3 dy33 = Pfy.z + jitter*oy33; 134 | vec3 dz33 = Pfz.z + jitter*oz33; 135 | 136 | vec3 d11 = dx11 * dx11 + dy11 * dy11 + dz11 * dz11; 137 | vec3 d12 = dx12 * dx12 + dy12 * dy12 + dz12 * dz12; 138 | vec3 d13 = dx13 * dx13 + dy13 * dy13 + dz13 * dz13; 139 | vec3 d21 = dx21 * dx21 + dy21 * dy21 + dz21 * dz21; 140 | vec3 d22 = dx22 * dx22 + dy22 * dy22 + dz22 * dz22; 141 | vec3 d23 = dx23 * dx23 + dy23 * dy23 + dz23 * dz23; 142 | vec3 d31 = dx31 * dx31 + dy31 * dy31 + dz31 * dz31; 143 | vec3 d32 = dx32 * dx32 + dy32 * dy32 + dz32 * dz32; 144 | vec3 d33 = dx33 * dx33 + dy33 * dy33 + dz33 * dz33; 145 | 146 | // Sort out the two smallest distances (F1, F2) 147 | #if 0 148 | // Cheat and sort out only F1 149 | vec3 d1 = min(min(d11,d12), d13); 150 | vec3 d2 = min(min(d21,d22), d23); 151 | vec3 d3 = min(min(d31,d32), d33); 152 | vec3 d = min(min(d1,d2), d3); 153 | d.x = min(min(d.x,d.y),d.z); 154 | return vec2(sqrt(d.x)); // F1 duplicated, no F2 computed 155 | #else 156 | // Do it right and sort out both F1 and F2 157 | vec3 d1a = min(d11, d12); 158 | d12 = max(d11, d12); 159 | d11 = min(d1a, d13); // Smallest now not in d12 or d13 160 | d13 = max(d1a, d13); 161 | d12 = min(d12, d13); // 2nd smallest now not in d13 162 | vec3 d2a = min(d21, d22); 163 | d22 = max(d21, d22); 164 | d21 = min(d2a, d23); // Smallest now not in d22 or d23 165 | d23 = max(d2a, d23); 166 | d22 = min(d22, d23); // 2nd smallest now not in d23 167 | vec3 d3a = min(d31, d32); 168 | d32 = max(d31, d32); 169 | d31 = min(d3a, d33); // Smallest now not in d32 or d33 170 | d33 = max(d3a, d33); 171 | d32 = min(d32, d33); // 2nd smallest now not in d33 172 | vec3 da = min(d11, d21); 173 | d21 = max(d11, d21); 174 | d11 = min(da, d31); // Smallest now in d11 175 | d31 = max(da, d31); // 2nd smallest now not in d31 176 | d11.xy = (d11.x < d11.y) ? d11.xy : d11.yx; 177 | d11.xz = (d11.x < d11.z) ? d11.xz : d11.zx; // d11.x now smallest 178 | d12 = min(d12, d21); // 2nd smallest now not in d21 179 | d12 = min(d12, d22); // nor in d22 180 | d12 = min(d12, d31); // nor in d31 181 | d12 = min(d12, d32); // nor in d32 182 | d11.yz = min(d11.yz,d12.xy); // nor in d12.yz 183 | d11.y = min(d11.y,d12.z); // Only two more to go 184 | d11.y = min(d11.y,d11.z); // Done! (Phew!) 185 | return sqrt(d11.xy); // F1, F2 186 | #endif 187 | } 188 | -------------------------------------------------------------------------------- /src/classicnoise2D.glsl: -------------------------------------------------------------------------------- 1 | // 2 | // GLSL textureless classic 2D noise "cnoise", 3 | // with an RSL-style periodic variant "pnoise". 4 | // Author: Stefan Gustavson (stefan.gustavson@gmail.com) 5 | // Version: 2024-11-07 6 | // 7 | // Many thanks to Ian McEwan of Ashima Arts for the 8 | // ideas for permutation and gradient selection. 9 | // 10 | // Copyright (c) 2011 Stefan Gustavson. All rights reserved. 11 | // Distributed under the MIT license. See LICENSE file. 12 | // https://github.com/stegu/webgl-noise 13 | // 14 | 15 | vec4 mod289(vec4 x) 16 | { 17 | return x - floor(x * (1.0 / 289.0)) * 289.0; 18 | } 19 | 20 | vec4 permute(vec4 x) 21 | { 22 | return mod289(((x*34.0)+10.0)*x); 23 | } 24 | 25 | vec4 taylorInvSqrt(vec4 r) 26 | { 27 | return 1.79284291400159 - 0.85373472095314 * r; 28 | } 29 | 30 | vec2 fade(vec2 t) { 31 | return t*t*t*(t*(t*6.0-15.0)+10.0); 32 | } 33 | 34 | // Classic Perlin noise 35 | float cnoise(vec2 P) 36 | { 37 | vec4 Pi = floor(P.xyxy) + vec4(0.0, 0.0, 1.0, 1.0); 38 | vec4 Pf = fract(P.xyxy) - vec4(0.0, 0.0, 1.0, 1.0); 39 | Pi = mod289(Pi); // To avoid truncation effects in permutation 40 | vec4 ix = Pi.xzxz; 41 | vec4 iy = Pi.yyww; 42 | vec4 fx = Pf.xzxz; 43 | vec4 fy = Pf.yyww; 44 | 45 | vec4 i = permute(permute(ix) + iy); 46 | 47 | vec4 gx = fract(i * (1.0 / 41.0)) * 2.0 - 1.0 ; 48 | vec4 gy = abs(gx) - 0.5 ; 49 | vec4 tx = floor(gx + 0.5); 50 | gx = gx - tx; 51 | 52 | vec2 g00 = vec2(gx.x,gy.x); 53 | vec2 g10 = vec2(gx.y,gy.y); 54 | vec2 g01 = vec2(gx.z,gy.z); 55 | vec2 g11 = vec2(gx.w,gy.w); 56 | 57 | vec4 norm = taylorInvSqrt(vec4(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11))); 58 | 59 | float n00 = norm.x * dot(g00, vec2(fx.x, fy.x)); 60 | float n01 = norm.y * dot(g01, vec2(fx.z, fy.z)); 61 | float n10 = norm.z * dot(g10, vec2(fx.y, fy.y)); 62 | float n11 = norm.w * dot(g11, vec2(fx.w, fy.w)); 63 | 64 | vec2 fade_xy = fade(Pf.xy); 65 | vec2 n_x = mix(vec2(n00, n01), vec2(n10, n11), fade_xy.x); 66 | float n_xy = mix(n_x.x, n_x.y, fade_xy.y); 67 | return 2.3 * n_xy; 68 | } 69 | 70 | // Classic Perlin noise, periodic variant 71 | float pnoise(vec2 P, vec2 rep) 72 | { 73 | vec4 Pi = floor(P.xyxy) + vec4(0.0, 0.0, 1.0, 1.0); 74 | vec4 Pf = fract(P.xyxy) - vec4(0.0, 0.0, 1.0, 1.0); 75 | Pi = mod(Pi, rep.xyxy); // To create noise with explicit period 76 | Pi = mod289(Pi); // To avoid truncation effects in permutation 77 | vec4 ix = Pi.xzxz; 78 | vec4 iy = Pi.yyww; 79 | vec4 fx = Pf.xzxz; 80 | vec4 fy = Pf.yyww; 81 | 82 | vec4 i = permute(permute(ix) + iy); 83 | 84 | vec4 gx = fract(i * (1.0 / 41.0)) * 2.0 - 1.0 ; 85 | vec4 gy = abs(gx) - 0.5 ; 86 | vec4 tx = floor(gx + 0.5); 87 | gx = gx - tx; 88 | 89 | vec2 g00 = vec2(gx.x,gy.x); 90 | vec2 g10 = vec2(gx.y,gy.y); 91 | vec2 g01 = vec2(gx.z,gy.z); 92 | vec2 g11 = vec2(gx.w,gy.w); 93 | 94 | vec4 norm = taylorInvSqrt(vec4(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11))); 95 | 96 | float n00 = norm.x * dot(g00, vec2(fx.x, fy.x)); 97 | float n01 = norm.y * dot(g01, vec2(fx.z, fy.z)); 98 | float n10 = norm.z * dot(g10, vec2(fx.y, fy.y)); 99 | float n11 = norm.w * dot(g11, vec2(fx.w, fy.w)); 100 | 101 | vec2 fade_xy = fade(Pf.xy); 102 | vec2 n_x = mix(vec2(n00, n01), vec2(n10, n11), fade_xy.x); 103 | float n_xy = mix(n_x.x, n_x.y, fade_xy.y); 104 | return 2.3 * n_xy; 105 | } 106 | -------------------------------------------------------------------------------- /src/classicnoise3D.glsl: -------------------------------------------------------------------------------- 1 | // 2 | // GLSL textureless classic 3D noise "cnoise", 3 | // with an RSL-style periodic variant "pnoise". 4 | // Author: Stefan Gustavson (stefan.gustavson@gmail.com) 5 | // Version: 2024-11-07 6 | // 7 | // Many thanks to Ian McEwan of Ashima Arts for the 8 | // ideas for permutation and gradient selection. 9 | // 10 | // Copyright (c) 2011 Stefan Gustavson. All rights reserved. 11 | // Distributed under the MIT license. See LICENSE file. 12 | // https://github.com/stegu/webgl-noise 13 | // 14 | 15 | vec3 mod289(vec3 x) 16 | { 17 | return x - floor(x * (1.0 / 289.0)) * 289.0; 18 | } 19 | 20 | vec4 mod289(vec4 x) 21 | { 22 | return x - floor(x * (1.0 / 289.0)) * 289.0; 23 | } 24 | 25 | vec4 permute(vec4 x) 26 | { 27 | return mod289(((x*34.0)+10.0)*x); 28 | } 29 | 30 | vec4 taylorInvSqrt(vec4 r) 31 | { 32 | return 1.79284291400159 - 0.85373472095314 * r; 33 | } 34 | 35 | vec3 fade(vec3 t) { 36 | return t*t*t*(t*(t*6.0-15.0)+10.0); 37 | } 38 | 39 | // Classic Perlin noise 40 | float cnoise(vec3 P) 41 | { 42 | vec3 Pi0 = floor(P); // Integer part for indexing 43 | vec3 Pi1 = Pi0 + vec3(1.0); // Integer part + 1 44 | Pi0 = mod289(Pi0); 45 | Pi1 = mod289(Pi1); 46 | vec3 Pf0 = fract(P); // Fractional part for interpolation 47 | vec3 Pf1 = Pf0 - vec3(1.0); // Fractional part - 1.0 48 | vec4 ix = vec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x); 49 | vec4 iy = vec4(Pi0.yy, Pi1.yy); 50 | vec4 iz0 = Pi0.zzzz; 51 | vec4 iz1 = Pi1.zzzz; 52 | 53 | vec4 ixy = permute(permute(ix) + iy); 54 | vec4 ixy0 = permute(ixy + iz0); 55 | vec4 ixy1 = permute(ixy + iz1); 56 | 57 | vec4 gx0 = ixy0 * (1.0 / 7.0); 58 | vec4 gy0 = fract(floor(gx0) * (1.0 / 7.0)) - 0.5; 59 | gx0 = fract(gx0); 60 | vec4 gz0 = vec4(0.5) - abs(gx0) - abs(gy0); 61 | vec4 sz0 = step(gz0, vec4(0.0)); 62 | gx0 -= sz0 * (step(0.0, gx0) - 0.5); 63 | gy0 -= sz0 * (step(0.0, gy0) - 0.5); 64 | 65 | vec4 gx1 = ixy1 * (1.0 / 7.0); 66 | vec4 gy1 = fract(floor(gx1) * (1.0 / 7.0)) - 0.5; 67 | gx1 = fract(gx1); 68 | vec4 gz1 = vec4(0.5) - abs(gx1) - abs(gy1); 69 | vec4 sz1 = step(gz1, vec4(0.0)); 70 | gx1 -= sz1 * (step(0.0, gx1) - 0.5); 71 | gy1 -= sz1 * (step(0.0, gy1) - 0.5); 72 | 73 | vec3 g000 = vec3(gx0.x,gy0.x,gz0.x); 74 | vec3 g100 = vec3(gx0.y,gy0.y,gz0.y); 75 | vec3 g010 = vec3(gx0.z,gy0.z,gz0.z); 76 | vec3 g110 = vec3(gx0.w,gy0.w,gz0.w); 77 | vec3 g001 = vec3(gx1.x,gy1.x,gz1.x); 78 | vec3 g101 = vec3(gx1.y,gy1.y,gz1.y); 79 | vec3 g011 = vec3(gx1.z,gy1.z,gz1.z); 80 | vec3 g111 = vec3(gx1.w,gy1.w,gz1.w); 81 | 82 | vec4 norm0 = taylorInvSqrt(vec4(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110))); 83 | vec4 norm1 = taylorInvSqrt(vec4(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111))); 84 | 85 | float n000 = norm0.x * dot(g000, Pf0); 86 | float n010 = norm0.y * dot(g010, vec3(Pf0.x, Pf1.y, Pf0.z)); 87 | float n100 = norm0.z * dot(g100, vec3(Pf1.x, Pf0.yz)); 88 | float n110 = norm0.w * dot(g110, vec3(Pf1.xy, Pf0.z)); 89 | float n001 = norm1.x * dot(g001, vec3(Pf0.xy, Pf1.z)); 90 | float n011 = norm1.y * dot(g011, vec3(Pf0.x, Pf1.yz)); 91 | float n101 = norm1.z * dot(g101, vec3(Pf1.x, Pf0.y, Pf1.z)); 92 | float n111 = norm1.w * dot(g111, Pf1); 93 | 94 | vec3 fade_xyz = fade(Pf0); 95 | vec4 n_z = mix(vec4(n000, n100, n010, n110), vec4(n001, n101, n011, n111), fade_xyz.z); 96 | vec2 n_yz = mix(n_z.xy, n_z.zw, fade_xyz.y); 97 | float n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x); 98 | return 2.2 * n_xyz; 99 | } 100 | 101 | // Classic Perlin noise, periodic variant 102 | float pnoise(vec3 P, vec3 rep) 103 | { 104 | vec3 Pi0 = mod(floor(P), rep); // Integer part, modulo period 105 | vec3 Pi1 = mod(Pi0 + vec3(1.0), rep); // Integer part + 1, mod period 106 | Pi0 = mod289(Pi0); 107 | Pi1 = mod289(Pi1); 108 | vec3 Pf0 = fract(P); // Fractional part for interpolation 109 | vec3 Pf1 = Pf0 - vec3(1.0); // Fractional part - 1.0 110 | vec4 ix = vec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x); 111 | vec4 iy = vec4(Pi0.yy, Pi1.yy); 112 | vec4 iz0 = Pi0.zzzz; 113 | vec4 iz1 = Pi1.zzzz; 114 | 115 | vec4 ixy = permute(permute(ix) + iy); 116 | vec4 ixy0 = permute(ixy + iz0); 117 | vec4 ixy1 = permute(ixy + iz1); 118 | 119 | vec4 gx0 = ixy0 * (1.0 / 7.0); 120 | vec4 gy0 = fract(floor(gx0) * (1.0 / 7.0)) - 0.5; 121 | gx0 = fract(gx0); 122 | vec4 gz0 = vec4(0.5) - abs(gx0) - abs(gy0); 123 | vec4 sz0 = step(gz0, vec4(0.0)); 124 | gx0 -= sz0 * (step(0.0, gx0) - 0.5); 125 | gy0 -= sz0 * (step(0.0, gy0) - 0.5); 126 | 127 | vec4 gx1 = ixy1 * (1.0 / 7.0); 128 | vec4 gy1 = fract(floor(gx1) * (1.0 / 7.0)) - 0.5; 129 | gx1 = fract(gx1); 130 | vec4 gz1 = vec4(0.5) - abs(gx1) - abs(gy1); 131 | vec4 sz1 = step(gz1, vec4(0.0)); 132 | gx1 -= sz1 * (step(0.0, gx1) - 0.5); 133 | gy1 -= sz1 * (step(0.0, gy1) - 0.5); 134 | 135 | vec3 g000 = vec3(gx0.x,gy0.x,gz0.x); 136 | vec3 g100 = vec3(gx0.y,gy0.y,gz0.y); 137 | vec3 g010 = vec3(gx0.z,gy0.z,gz0.z); 138 | vec3 g110 = vec3(gx0.w,gy0.w,gz0.w); 139 | vec3 g001 = vec3(gx1.x,gy1.x,gz1.x); 140 | vec3 g101 = vec3(gx1.y,gy1.y,gz1.y); 141 | vec3 g011 = vec3(gx1.z,gy1.z,gz1.z); 142 | vec3 g111 = vec3(gx1.w,gy1.w,gz1.w); 143 | 144 | vec4 norm0 = taylorInvSqrt(vec4(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110))); 145 | vec4 norm1 = taylorInvSqrt(vec4(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111))); 146 | 147 | float n000 = norm0.x * dot(g000, Pf0); 148 | float n010 = norm0.y * dot(g010, vec3(Pf0.x, Pf1.y, Pf0.z)); 149 | float n100 = norm0.z * dot(g100, vec3(Pf1.x, Pf0.yz)); 150 | float n110 = norm0.w * dot(g110, vec3(Pf1.xy, Pf0.z)); 151 | float n001 = norm1.x * dot(g001, vec3(Pf0.xy, Pf1.z)); 152 | float n011 = norm1.y * dot(g011, vec3(Pf0.x, Pf1.yz)); 153 | float n101 = norm1.z * dot(g101, vec3(Pf1.x, Pf0.y, Pf1.z)); 154 | float n111 = norm1.w * dot(g111, Pf1); 155 | 156 | vec3 fade_xyz = fade(Pf0); 157 | vec4 n_z = mix(vec4(n000, n100, n010, n110), vec4(n001, n101, n011, n111), fade_xyz.z); 158 | vec2 n_yz = mix(n_z.xy, n_z.zw, fade_xyz.y); 159 | float n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x); 160 | return 2.2 * n_xyz; 161 | } 162 | -------------------------------------------------------------------------------- /src/classicnoise4D.glsl: -------------------------------------------------------------------------------- 1 | // 2 | // GLSL textureless classic 4D noise "cnoise", 3 | // with an RSL-style periodic variant "pnoise". 4 | // Author: Stefan Gustavson (stefan.gustavson@gmail.com) 5 | // Version: 20241-11-07 6 | // 7 | // Many thanks to Ian McEwan of Ashima Arts for the 8 | // ideas for permutation and gradient selection. 9 | // 10 | // Copyright (c) 2011 Stefan Gustavson. All rights reserved. 11 | // Distributed under the MIT license. See LICENSE file. 12 | // https://github.com/stegu/webgl-noise 13 | // 14 | 15 | vec4 mod289(vec4 x) 16 | { 17 | return x - floor(x * (1.0 / 289.0)) * 289.0; 18 | } 19 | 20 | vec4 permute(vec4 x) 21 | { 22 | return mod289(((x*34.0)+10.0)*x); 23 | } 24 | 25 | vec4 taylorInvSqrt(vec4 r) 26 | { 27 | return 1.79284291400159 - 0.85373472095314 * r; 28 | } 29 | 30 | vec4 fade(vec4 t) { 31 | return t*t*t*(t*(t*6.0-15.0)+10.0); 32 | } 33 | 34 | // Classic Perlin noise 35 | float cnoise(vec4 P) 36 | { 37 | vec4 Pi0 = floor(P); // Integer part for indexing 38 | vec4 Pi1 = Pi0 + 1.0; // Integer part + 1 39 | Pi0 = mod289(Pi0); 40 | Pi1 = mod289(Pi1); 41 | vec4 Pf0 = fract(P); // Fractional part for interpolation 42 | vec4 Pf1 = Pf0 - 1.0; // Fractional part - 1.0 43 | vec4 ix = vec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x); 44 | vec4 iy = vec4(Pi0.yy, Pi1.yy); 45 | vec4 iz0 = vec4(Pi0.zzzz); 46 | vec4 iz1 = vec4(Pi1.zzzz); 47 | vec4 iw0 = vec4(Pi0.wwww); 48 | vec4 iw1 = vec4(Pi1.wwww); 49 | 50 | vec4 ixy = permute(permute(ix) + iy); 51 | vec4 ixy0 = permute(ixy + iz0); 52 | vec4 ixy1 = permute(ixy + iz1); 53 | vec4 ixy00 = permute(ixy0 + iw0); 54 | vec4 ixy01 = permute(ixy0 + iw1); 55 | vec4 ixy10 = permute(ixy1 + iw0); 56 | vec4 ixy11 = permute(ixy1 + iw1); 57 | 58 | vec4 gx00 = ixy00 * (1.0 / 7.0); 59 | vec4 gy00 = floor(gx00) * (1.0 / 7.0); 60 | vec4 gz00 = floor(gy00) * (1.0 / 6.0); 61 | gx00 = fract(gx00) - 0.5; 62 | gy00 = fract(gy00) - 0.5; 63 | gz00 = fract(gz00) - 0.5; 64 | vec4 gw00 = vec4(0.75) - abs(gx00) - abs(gy00) - abs(gz00); 65 | vec4 sw00 = step(gw00, vec4(0.0)); 66 | gx00 -= sw00 * (step(0.0, gx00) - 0.5); 67 | gy00 -= sw00 * (step(0.0, gy00) - 0.5); 68 | 69 | vec4 gx01 = ixy01 * (1.0 / 7.0); 70 | vec4 gy01 = floor(gx01) * (1.0 / 7.0); 71 | vec4 gz01 = floor(gy01) * (1.0 / 6.0); 72 | gx01 = fract(gx01) - 0.5; 73 | gy01 = fract(gy01) - 0.5; 74 | gz01 = fract(gz01) - 0.5; 75 | vec4 gw01 = vec4(0.75) - abs(gx01) - abs(gy01) - abs(gz01); 76 | vec4 sw01 = step(gw01, vec4(0.0)); 77 | gx01 -= sw01 * (step(0.0, gx01) - 0.5); 78 | gy01 -= sw01 * (step(0.0, gy01) - 0.5); 79 | 80 | vec4 gx10 = ixy10 * (1.0 / 7.0); 81 | vec4 gy10 = floor(gx10) * (1.0 / 7.0); 82 | vec4 gz10 = floor(gy10) * (1.0 / 6.0); 83 | gx10 = fract(gx10) - 0.5; 84 | gy10 = fract(gy10) - 0.5; 85 | gz10 = fract(gz10) - 0.5; 86 | vec4 gw10 = vec4(0.75) - abs(gx10) - abs(gy10) - abs(gz10); 87 | vec4 sw10 = step(gw10, vec4(0.0)); 88 | gx10 -= sw10 * (step(0.0, gx10) - 0.5); 89 | gy10 -= sw10 * (step(0.0, gy10) - 0.5); 90 | 91 | vec4 gx11 = ixy11 * (1.0 / 7.0); 92 | vec4 gy11 = floor(gx11) * (1.0 / 7.0); 93 | vec4 gz11 = floor(gy11) * (1.0 / 6.0); 94 | gx11 = fract(gx11) - 0.5; 95 | gy11 = fract(gy11) - 0.5; 96 | gz11 = fract(gz11) - 0.5; 97 | vec4 gw11 = vec4(0.75) - abs(gx11) - abs(gy11) - abs(gz11); 98 | vec4 sw11 = step(gw11, vec4(0.0)); 99 | gx11 -= sw11 * (step(0.0, gx11) - 0.5); 100 | gy11 -= sw11 * (step(0.0, gy11) - 0.5); 101 | 102 | vec4 g0000 = vec4(gx00.x,gy00.x,gz00.x,gw00.x); 103 | vec4 g1000 = vec4(gx00.y,gy00.y,gz00.y,gw00.y); 104 | vec4 g0100 = vec4(gx00.z,gy00.z,gz00.z,gw00.z); 105 | vec4 g1100 = vec4(gx00.w,gy00.w,gz00.w,gw00.w); 106 | vec4 g0010 = vec4(gx10.x,gy10.x,gz10.x,gw10.x); 107 | vec4 g1010 = vec4(gx10.y,gy10.y,gz10.y,gw10.y); 108 | vec4 g0110 = vec4(gx10.z,gy10.z,gz10.z,gw10.z); 109 | vec4 g1110 = vec4(gx10.w,gy10.w,gz10.w,gw10.w); 110 | vec4 g0001 = vec4(gx01.x,gy01.x,gz01.x,gw01.x); 111 | vec4 g1001 = vec4(gx01.y,gy01.y,gz01.y,gw01.y); 112 | vec4 g0101 = vec4(gx01.z,gy01.z,gz01.z,gw01.z); 113 | vec4 g1101 = vec4(gx01.w,gy01.w,gz01.w,gw01.w); 114 | vec4 g0011 = vec4(gx11.x,gy11.x,gz11.x,gw11.x); 115 | vec4 g1011 = vec4(gx11.y,gy11.y,gz11.y,gw11.y); 116 | vec4 g0111 = vec4(gx11.z,gy11.z,gz11.z,gw11.z); 117 | vec4 g1111 = vec4(gx11.w,gy11.w,gz11.w,gw11.w); 118 | 119 | vec4 norm00 = taylorInvSqrt(vec4(dot(g0000, g0000), dot(g0100, g0100), dot(g1000, g1000), dot(g1100, g1100))); 120 | vec4 norm01 = taylorInvSqrt(vec4(dot(g0001, g0001), dot(g0101, g0101), dot(g1001, g1001), dot(g1101, g1101))); 121 | vec4 norm10 = taylorInvSqrt(vec4(dot(g0010, g0010), dot(g0110, g0110), dot(g1010, g1010), dot(g1110, g1110))); 122 | vec4 norm11 = taylorInvSqrt(vec4(dot(g0011, g0011), dot(g0111, g0111), dot(g1011, g1011), dot(g1111, g1111))); 123 | 124 | float n0000 = norm00.x * dot(g0000, Pf0); 125 | float n0100 = norm00.y * dot(g0100, vec4(Pf0.x, Pf1.y, Pf0.zw)); 126 | float n1000 = norm00.z * dot(g1000, vec4(Pf1.x, Pf0.yzw)); 127 | float n1100 = norm00.w * dot(g1100, vec4(Pf1.xy, Pf0.zw)); 128 | float n0010 = norm10.x * dot(g0010, vec4(Pf0.xy, Pf1.z, Pf0.w)); 129 | float n0110 = norm10.y * dot(g0110, vec4(Pf0.x, Pf1.yz, Pf0.w)); 130 | float n1010 = norm10.z * dot(g1010, vec4(Pf1.x, Pf0.y, Pf1.z, Pf0.w)); 131 | float n1110 = norm10.w * dot(g1110, vec4(Pf1.xyz, Pf0.w)); 132 | float n0001 = norm01.x * dot(g0001, vec4(Pf0.xyz, Pf1.w)); 133 | float n0101 = norm01.y * dot(g0101, vec4(Pf0.x, Pf1.y, Pf0.z, Pf1.w)); 134 | float n1001 = norm01.z * dot(g1001, vec4(Pf1.x, Pf0.yz, Pf1.w)); 135 | float n1101 = norm01.w * dot(g1101, vec4(Pf1.xy, Pf0.z, Pf1.w)); 136 | float n0011 = norm11.x * dot(g0011, vec4(Pf0.xy, Pf1.zw)); 137 | float n0111 = norm11.y * dot(g0111, vec4(Pf0.x, Pf1.yzw)); 138 | float n1011 = norm11.z * dot(g1011, vec4(Pf1.x, Pf0.y, Pf1.zw)); 139 | float n1111 = norm11.w * dot(g1111, Pf1); 140 | 141 | vec4 fade_xyzw = fade(Pf0); 142 | vec4 n_0w = mix(vec4(n0000, n1000, n0100, n1100), vec4(n0001, n1001, n0101, n1101), fade_xyzw.w); 143 | vec4 n_1w = mix(vec4(n0010, n1010, n0110, n1110), vec4(n0011, n1011, n0111, n1111), fade_xyzw.w); 144 | vec4 n_zw = mix(n_0w, n_1w, fade_xyzw.z); 145 | vec2 n_yzw = mix(n_zw.xy, n_zw.zw, fade_xyzw.y); 146 | float n_xyzw = mix(n_yzw.x, n_yzw.y, fade_xyzw.x); 147 | return 2.2 * n_xyzw; 148 | } 149 | 150 | // Classic Perlin noise, periodic version 151 | float pnoise(vec4 P, vec4 rep) 152 | { 153 | vec4 Pi0 = mod(floor(P), rep); // Integer part modulo rep 154 | vec4 Pi1 = mod(Pi0 + 1.0, rep); // Integer part + 1 mod rep 155 | Pi0 = mod289(Pi0); 156 | Pi1 = mod289(Pi1); 157 | vec4 Pf0 = fract(P); // Fractional part for interpolation 158 | vec4 Pf1 = Pf0 - 1.0; // Fractional part - 1.0 159 | vec4 ix = vec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x); 160 | vec4 iy = vec4(Pi0.yy, Pi1.yy); 161 | vec4 iz0 = vec4(Pi0.zzzz); 162 | vec4 iz1 = vec4(Pi1.zzzz); 163 | vec4 iw0 = vec4(Pi0.wwww); 164 | vec4 iw1 = vec4(Pi1.wwww); 165 | 166 | vec4 ixy = permute(permute(ix) + iy); 167 | vec4 ixy0 = permute(ixy + iz0); 168 | vec4 ixy1 = permute(ixy + iz1); 169 | vec4 ixy00 = permute(ixy0 + iw0); 170 | vec4 ixy01 = permute(ixy0 + iw1); 171 | vec4 ixy10 = permute(ixy1 + iw0); 172 | vec4 ixy11 = permute(ixy1 + iw1); 173 | 174 | vec4 gx00 = ixy00 * (1.0 / 7.0); 175 | vec4 gy00 = floor(gx00) * (1.0 / 7.0); 176 | vec4 gz00 = floor(gy00) * (1.0 / 6.0); 177 | gx00 = fract(gx00) - 0.5; 178 | gy00 = fract(gy00) - 0.5; 179 | gz00 = fract(gz00) - 0.5; 180 | vec4 gw00 = vec4(0.75) - abs(gx00) - abs(gy00) - abs(gz00); 181 | vec4 sw00 = step(gw00, vec4(0.0)); 182 | gx00 -= sw00 * (step(0.0, gx00) - 0.5); 183 | gy00 -= sw00 * (step(0.0, gy00) - 0.5); 184 | 185 | vec4 gx01 = ixy01 * (1.0 / 7.0); 186 | vec4 gy01 = floor(gx01) * (1.0 / 7.0); 187 | vec4 gz01 = floor(gy01) * (1.0 / 6.0); 188 | gx01 = fract(gx01) - 0.5; 189 | gy01 = fract(gy01) - 0.5; 190 | gz01 = fract(gz01) - 0.5; 191 | vec4 gw01 = vec4(0.75) - abs(gx01) - abs(gy01) - abs(gz01); 192 | vec4 sw01 = step(gw01, vec4(0.0)); 193 | gx01 -= sw01 * (step(0.0, gx01) - 0.5); 194 | gy01 -= sw01 * (step(0.0, gy01) - 0.5); 195 | 196 | vec4 gx10 = ixy10 * (1.0 / 7.0); 197 | vec4 gy10 = floor(gx10) * (1.0 / 7.0); 198 | vec4 gz10 = floor(gy10) * (1.0 / 6.0); 199 | gx10 = fract(gx10) - 0.5; 200 | gy10 = fract(gy10) - 0.5; 201 | gz10 = fract(gz10) - 0.5; 202 | vec4 gw10 = vec4(0.75) - abs(gx10) - abs(gy10) - abs(gz10); 203 | vec4 sw10 = step(gw10, vec4(0.0)); 204 | gx10 -= sw10 * (step(0.0, gx10) - 0.5); 205 | gy10 -= sw10 * (step(0.0, gy10) - 0.5); 206 | 207 | vec4 gx11 = ixy11 * (1.0 / 7.0); 208 | vec4 gy11 = floor(gx11) * (1.0 / 7.0); 209 | vec4 gz11 = floor(gy11) * (1.0 / 6.0); 210 | gx11 = fract(gx11) - 0.5; 211 | gy11 = fract(gy11) - 0.5; 212 | gz11 = fract(gz11) - 0.5; 213 | vec4 gw11 = vec4(0.75) - abs(gx11) - abs(gy11) - abs(gz11); 214 | vec4 sw11 = step(gw11, vec4(0.0)); 215 | gx11 -= sw11 * (step(0.0, gx11) - 0.5); 216 | gy11 -= sw11 * (step(0.0, gy11) - 0.5); 217 | 218 | vec4 g0000 = vec4(gx00.x,gy00.x,gz00.x,gw00.x); 219 | vec4 g1000 = vec4(gx00.y,gy00.y,gz00.y,gw00.y); 220 | vec4 g0100 = vec4(gx00.z,gy00.z,gz00.z,gw00.z); 221 | vec4 g1100 = vec4(gx00.w,gy00.w,gz00.w,gw00.w); 222 | vec4 g0010 = vec4(gx10.x,gy10.x,gz10.x,gw10.x); 223 | vec4 g1010 = vec4(gx10.y,gy10.y,gz10.y,gw10.y); 224 | vec4 g0110 = vec4(gx10.z,gy10.z,gz10.z,gw10.z); 225 | vec4 g1110 = vec4(gx10.w,gy10.w,gz10.w,gw10.w); 226 | vec4 g0001 = vec4(gx01.x,gy01.x,gz01.x,gw01.x); 227 | vec4 g1001 = vec4(gx01.y,gy01.y,gz01.y,gw01.y); 228 | vec4 g0101 = vec4(gx01.z,gy01.z,gz01.z,gw01.z); 229 | vec4 g1101 = vec4(gx01.w,gy01.w,gz01.w,gw01.w); 230 | vec4 g0011 = vec4(gx11.x,gy11.x,gz11.x,gw11.x); 231 | vec4 g1011 = vec4(gx11.y,gy11.y,gz11.y,gw11.y); 232 | vec4 g0111 = vec4(gx11.z,gy11.z,gz11.z,gw11.z); 233 | vec4 g1111 = vec4(gx11.w,gy11.w,gz11.w,gw11.w); 234 | 235 | vec4 norm00 = taylorInvSqrt(vec4(dot(g0000, g0000), dot(g0100, g0100), dot(g1000, g1000), dot(g1100, g1100))); 236 | vec4 norm01 = taylorInvSqrt(vec4(dot(g0001, g0001), dot(g0101, g0101), dot(g1001, g1001), dot(g1101, g1101))); 237 | vec4 norm10 = taylorInvSqrt(vec4(dot(g0010, g0010), dot(g0110, g0110), dot(g1010, g1010), dot(g1110, g1110))); 238 | vec4 norm11 = taylorInvSqrt(vec4(dot(g0011, g0011), dot(g0111, g0111), dot(g1011, g1011), dot(g1111, g1111))); 239 | 240 | float n0000 = norm00.x * dot(g0000, Pf0); 241 | float n0100 = norm00.y * dot(g0100, vec4(Pf0.x, Pf1.y, Pf0.zw)); 242 | float n1000 = norm00.z * dot(g1000, vec4(Pf1.x, Pf0.yzw)); 243 | float n1100 = norm00.w * dot(g1100, vec4(Pf1.xy, Pf0.zw)); 244 | float n0010 = norm10.x * dot(g0010, vec4(Pf0.xy, Pf1.z, Pf0.w)); 245 | float n0110 = norm10.y * dot(g0110, vec4(Pf0.x, Pf1.yz, Pf0.w)); 246 | float n1010 = norm10.z * dot(g1010, vec4(Pf1.x, Pf0.y, Pf1.z, Pf0.w)); 247 | float n1110 = norm10.w * dot(g1110, vec4(Pf1.xyz, Pf0.w)); 248 | float n0001 = norm01.x * dot(g0001, vec4(Pf0.xyz, Pf1.w)); 249 | float n0101 = norm01.y * dot(g0101, vec4(Pf0.x, Pf1.y, Pf0.z, Pf1.w)); 250 | float n1001 = norm01.z * dot(g1001, vec4(Pf1.x, Pf0.yz, Pf1.w)); 251 | float n1101 = norm01.w * dot(g1101, vec4(Pf1.xy, Pf0.z, Pf1.w)); 252 | float n0011 = norm11.x * dot(g0011, vec4(Pf0.xy, Pf1.zw)); 253 | float n0111 = norm11.y * dot(g0111, vec4(Pf0.x, Pf1.yzw)); 254 | float n1011 = norm11.z * dot(g1011, vec4(Pf1.x, Pf0.y, Pf1.zw)); 255 | float n1111 = norm11.w * dot(g1111, Pf1); 256 | 257 | vec4 fade_xyzw = fade(Pf0); 258 | vec4 n_0w = mix(vec4(n0000, n1000, n0100, n1100), vec4(n0001, n1001, n0101, n1101), fade_xyzw.w); 259 | vec4 n_1w = mix(vec4(n0010, n1010, n0110, n1110), vec4(n0011, n1011, n0111, n1111), fade_xyzw.w); 260 | vec4 n_zw = mix(n_0w, n_1w, fade_xyzw.z); 261 | vec2 n_yzw = mix(n_zw.xy, n_zw.zw, fade_xyzw.y); 262 | float n_xyzw = mix(n_yzw.x, n_yzw.y, fade_xyzw.x); 263 | return 2.2 * n_xyzw; 264 | } 265 | -------------------------------------------------------------------------------- /src/noise2D.glsl: -------------------------------------------------------------------------------- 1 | // 2 | // Description : Array and textureless GLSL 2D simplex noise function. 3 | // Author : Ian McEwan, Ashima Arts. 4 | // Maintainer : stegu 5 | // Lastmod : 20110822 (ijm) 6 | // License : Copyright (C) 2011 Ashima Arts. All rights reserved. 7 | // Distributed under the MIT License. See LICENSE file. 8 | // https://github.com/ashima/webgl-noise 9 | // https://github.com/stegu/webgl-noise 10 | // 11 | 12 | vec3 mod289(vec3 x) { 13 | return x - floor(x * (1.0 / 289.0)) * 289.0; 14 | } 15 | 16 | vec2 mod289(vec2 x) { 17 | return x - floor(x * (1.0 / 289.0)) * 289.0; 18 | } 19 | 20 | vec3 permute(vec3 x) { 21 | return mod289(((x*34.0)+10.0)*x); 22 | } 23 | 24 | float snoise(vec2 v) 25 | { 26 | const vec4 C = vec4(0.211324865405187, // (3.0-sqrt(3.0))/6.0 27 | 0.366025403784439, // 0.5*(sqrt(3.0)-1.0) 28 | -0.577350269189626, // -1.0 + 2.0 * C.x 29 | 0.024390243902439); // 1.0 / 41.0 30 | // First corner 31 | vec2 i = floor(v + dot(v, C.yy) ); 32 | vec2 x0 = v - i + dot(i, C.xx); 33 | 34 | // Other corners 35 | vec2 i1; 36 | //i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0 37 | //i1.y = 1.0 - i1.x; 38 | i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0); 39 | // x0 = x0 - 0.0 + 0.0 * C.xx ; 40 | // x1 = x0 - i1 + 1.0 * C.xx ; 41 | // x2 = x0 - 1.0 + 2.0 * C.xx ; 42 | vec4 x12 = x0.xyxy + C.xxzz; 43 | x12.xy -= i1; 44 | 45 | // Permutations 46 | i = mod289(i); // Avoid truncation effects in permutation 47 | vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 )) 48 | + i.x + vec3(0.0, i1.x, 1.0 )); 49 | 50 | vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0); 51 | m = m*m ; 52 | m = m*m ; 53 | 54 | // Gradients: 41 points uniformly over a line, mapped onto a diamond. 55 | // The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287) 56 | 57 | vec3 x = 2.0 * fract(p * C.www) - 1.0; 58 | vec3 h = abs(x) - 0.5; 59 | vec3 ox = floor(x + 0.5); 60 | vec3 a0 = x - ox; 61 | 62 | // Normalise gradients implicitly by scaling m 63 | // Approximation of: m *= inversesqrt( a0*a0 + h*h ); 64 | m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h ); 65 | 66 | // Compute final noise value at P 67 | vec3 g; 68 | g.x = a0.x * x0.x + h.x * x0.y; 69 | g.yz = a0.yz * x12.xz + h.yz * x12.yw; 70 | return 130.0 * dot(m, g); 71 | } 72 | -------------------------------------------------------------------------------- /src/noise3D.glsl: -------------------------------------------------------------------------------- 1 | // 2 | // Description : Array and textureless GLSL 2D/3D/4D simplex 3 | // noise functions. 4 | // Author : Ian McEwan, Ashima Arts. 5 | // Maintainer : stegu 6 | // Lastmod : 20201014 (stegu) 7 | // License : Copyright (C) 2011 Ashima Arts. All rights reserved. 8 | // Distributed under the MIT License. See LICENSE file. 9 | // https://github.com/ashima/webgl-noise 10 | // https://github.com/stegu/webgl-noise 11 | // 12 | 13 | vec3 mod289(vec3 x) { 14 | return x - floor(x * (1.0 / 289.0)) * 289.0; 15 | } 16 | 17 | vec4 mod289(vec4 x) { 18 | return x - floor(x * (1.0 / 289.0)) * 289.0; 19 | } 20 | 21 | vec4 permute(vec4 x) { 22 | return mod289(((x*34.0)+10.0)*x); 23 | } 24 | 25 | vec4 taylorInvSqrt(vec4 r) 26 | { 27 | return 1.79284291400159 - 0.85373472095314 * r; 28 | } 29 | 30 | float snoise(vec3 v) 31 | { 32 | const vec2 C = vec2(1.0/6.0, 1.0/3.0) ; 33 | const vec4 D = vec4(0.0, 0.5, 1.0, 2.0); 34 | 35 | // First corner 36 | vec3 i = floor(v + dot(v, C.yyy) ); 37 | vec3 x0 = v - i + dot(i, C.xxx) ; 38 | 39 | // Other corners 40 | vec3 g = step(x0.yzx, x0.xyz); 41 | vec3 l = 1.0 - g; 42 | vec3 i1 = min( g.xyz, l.zxy ); 43 | vec3 i2 = max( g.xyz, l.zxy ); 44 | 45 | // x0 = x0 - 0.0 + 0.0 * C.xxx; 46 | // x1 = x0 - i1 + 1.0 * C.xxx; 47 | // x2 = x0 - i2 + 2.0 * C.xxx; 48 | // x3 = x0 - 1.0 + 3.0 * C.xxx; 49 | vec3 x1 = x0 - i1 + C.xxx; 50 | vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y 51 | vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y 52 | 53 | // Permutations 54 | i = mod289(i); 55 | vec4 p = permute( permute( permute( 56 | i.z + vec4(0.0, i1.z, i2.z, 1.0 )) 57 | + i.y + vec4(0.0, i1.y, i2.y, 1.0 )) 58 | + i.x + vec4(0.0, i1.x, i2.x, 1.0 )); 59 | 60 | // Gradients: 7x7 points over a square, mapped onto an octahedron. 61 | // The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294) 62 | float n_ = 0.142857142857; // 1.0/7.0 63 | vec3 ns = n_ * D.wyz - D.xzx; 64 | 65 | vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7) 66 | 67 | vec4 x_ = floor(j * ns.z); 68 | vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N) 69 | 70 | vec4 x = x_ *ns.x + ns.yyyy; 71 | vec4 y = y_ *ns.x + ns.yyyy; 72 | vec4 h = 1.0 - abs(x) - abs(y); 73 | 74 | vec4 b0 = vec4( x.xy, y.xy ); 75 | vec4 b1 = vec4( x.zw, y.zw ); 76 | 77 | //vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0; 78 | //vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0; 79 | vec4 s0 = floor(b0)*2.0 + 1.0; 80 | vec4 s1 = floor(b1)*2.0 + 1.0; 81 | vec4 sh = -step(h, vec4(0.0)); 82 | 83 | vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ; 84 | vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ; 85 | 86 | vec3 p0 = vec3(a0.xy,h.x); 87 | vec3 p1 = vec3(a0.zw,h.y); 88 | vec3 p2 = vec3(a1.xy,h.z); 89 | vec3 p3 = vec3(a1.zw,h.w); 90 | 91 | //Normalise gradients 92 | vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3))); 93 | p0 *= norm.x; 94 | p1 *= norm.y; 95 | p2 *= norm.z; 96 | p3 *= norm.w; 97 | 98 | // Mix final noise value 99 | vec4 m = max(0.5 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0); 100 | m = m * m; 101 | return 105.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1), 102 | dot(p2,x2), dot(p3,x3) ) ); 103 | } 104 | -------------------------------------------------------------------------------- /src/noise3Dgrad.glsl: -------------------------------------------------------------------------------- 1 | // 2 | // Description : Array and textureless GLSL 2D/3D/4D simplex 3 | // noise functions. 4 | // Author : Ian McEwan, Ashima Arts. 5 | // Maintainer : stegu 6 | // Lastmod : 20201014 (stegu) 7 | // License : Copyright (C) 2011 Ashima Arts. All rights reserved. 8 | // Distributed under the MIT License. See LICENSE file. 9 | // https://github.com/ashima/webgl-noise 10 | // https://github.com/stegu/webgl-noise 11 | // 12 | 13 | vec3 mod289(vec3 x) { 14 | return x - floor(x * (1.0 / 289.0)) * 289.0; 15 | } 16 | 17 | vec4 mod289(vec4 x) { 18 | return x - floor(x * (1.0 / 289.0)) * 289.0; 19 | } 20 | 21 | vec4 permute(vec4 x) { 22 | return mod289(((x*34.0)+10.0)*x); 23 | } 24 | 25 | vec4 taylorInvSqrt(vec4 r) 26 | { 27 | return 1.79284291400159 - 0.85373472095314 * r; 28 | } 29 | 30 | float snoise(vec3 v, out vec3 gradient) 31 | { 32 | const vec2 C = vec2(1.0/6.0, 1.0/3.0) ; 33 | const vec4 D = vec4(0.0, 0.5, 1.0, 2.0); 34 | 35 | // First corner 36 | vec3 i = floor(v + dot(v, C.yyy) ); 37 | vec3 x0 = v - i + dot(i, C.xxx) ; 38 | 39 | // Other corners 40 | vec3 g = step(x0.yzx, x0.xyz); 41 | vec3 l = 1.0 - g; 42 | vec3 i1 = min( g.xyz, l.zxy ); 43 | vec3 i2 = max( g.xyz, l.zxy ); 44 | 45 | // x0 = x0 - 0.0 + 0.0 * C.xxx; 46 | // x1 = x0 - i1 + 1.0 * C.xxx; 47 | // x2 = x0 - i2 + 2.0 * C.xxx; 48 | // x3 = x0 - 1.0 + 3.0 * C.xxx; 49 | vec3 x1 = x0 - i1 + C.xxx; 50 | vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y 51 | vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y 52 | 53 | // Permutations 54 | i = mod289(i); 55 | vec4 p = permute( permute( permute( 56 | i.z + vec4(0.0, i1.z, i2.z, 1.0 )) 57 | + i.y + vec4(0.0, i1.y, i2.y, 1.0 )) 58 | + i.x + vec4(0.0, i1.x, i2.x, 1.0 )); 59 | 60 | // Gradients: 7x7 points over a square, mapped onto an octahedron. 61 | // The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294) 62 | float n_ = 0.142857142857; // 1.0/7.0 63 | vec3 ns = n_ * D.wyz - D.xzx; 64 | 65 | vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7) 66 | 67 | vec4 x_ = floor(j * ns.z); 68 | vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N) 69 | 70 | vec4 x = x_ *ns.x + ns.yyyy; 71 | vec4 y = y_ *ns.x + ns.yyyy; 72 | vec4 h = 1.0 - abs(x) - abs(y); 73 | 74 | vec4 b0 = vec4( x.xy, y.xy ); 75 | vec4 b1 = vec4( x.zw, y.zw ); 76 | 77 | //vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0; 78 | //vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0; 79 | vec4 s0 = floor(b0)*2.0 + 1.0; 80 | vec4 s1 = floor(b1)*2.0 + 1.0; 81 | vec4 sh = -step(h, vec4(0.0)); 82 | 83 | vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ; 84 | vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ; 85 | 86 | vec3 p0 = vec3(a0.xy,h.x); 87 | vec3 p1 = vec3(a0.zw,h.y); 88 | vec3 p2 = vec3(a1.xy,h.z); 89 | vec3 p3 = vec3(a1.zw,h.w); 90 | 91 | //Normalise gradients 92 | vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3))); 93 | p0 *= norm.x; 94 | p1 *= norm.y; 95 | p2 *= norm.z; 96 | p3 *= norm.w; 97 | 98 | // Mix final noise value 99 | vec4 m = max(0.5 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0); 100 | vec4 m2 = m * m; 101 | vec4 m4 = m2 * m2; 102 | vec4 pdotx = vec4(dot(p0,x0), dot(p1,x1), dot(p2,x2), dot(p3,x3)); 103 | 104 | // Determine noise gradient 105 | vec4 temp = m2 * m * pdotx; 106 | gradient = -8.0 * (temp.x * x0 + temp.y * x1 + temp.z * x2 + temp.w * x3); 107 | gradient += m4.x * p0 + m4.y * p1 + m4.z * p2 + m4.w * p3; 108 | gradient *= 105.0; 109 | 110 | return 105.0 * dot(m4, pdotx); 111 | } 112 | -------------------------------------------------------------------------------- /src/noise4D.glsl: -------------------------------------------------------------------------------- 1 | // 2 | // Description : Array and textureless GLSL 2D/3D/4D simplex 3 | // noise functions. 4 | // Author : Ian McEwan, Ashima Arts. 5 | // Maintainer : stegu 6 | // Lastmod : 20110822 (ijm) 7 | // License : Copyright (C) 2011 Ashima Arts. All rights reserved. 8 | // Distributed under the MIT License. See LICENSE file. 9 | // https://github.com/ashima/webgl-noise 10 | // https://github.com/stegu/webgl-noise 11 | // 12 | 13 | vec4 mod289(vec4 x) { 14 | return x - floor(x * (1.0 / 289.0)) * 289.0; } 15 | 16 | float mod289(float x) { 17 | return x - floor(x * (1.0 / 289.0)) * 289.0; } 18 | 19 | vec4 permute(vec4 x) { 20 | return mod289(((x*34.0)+10.0)*x); 21 | } 22 | 23 | float permute(float x) { 24 | return mod289(((x*34.0)+10.0)*x); 25 | } 26 | 27 | vec4 taylorInvSqrt(vec4 r) 28 | { 29 | return 1.79284291400159 - 0.85373472095314 * r; 30 | } 31 | 32 | float taylorInvSqrt(float r) 33 | { 34 | return 1.79284291400159 - 0.85373472095314 * r; 35 | } 36 | 37 | vec4 grad4(float j, vec4 ip) 38 | { 39 | const vec4 ones = vec4(1.0, 1.0, 1.0, -1.0); 40 | vec4 p,s; 41 | 42 | p.xyz = floor( fract (vec3(j) * ip.xyz) * 7.0) * ip.z - 1.0; 43 | p.w = 1.5 - dot(abs(p.xyz), ones.xyz); 44 | s = vec4(lessThan(p, vec4(0.0))); 45 | p.xyz = p.xyz + (s.xyz*2.0 - 1.0) * s.www; 46 | 47 | return p; 48 | } 49 | 50 | // (sqrt(5) - 1)/4 = F4, used once below 51 | #define F4 0.309016994374947451 52 | 53 | float snoise(vec4 v) 54 | { 55 | const vec4 C = vec4( 0.138196601125011, // (5 - sqrt(5))/20 G4 56 | 0.276393202250021, // 2 * G4 57 | 0.414589803375032, // 3 * G4 58 | -0.447213595499958); // -1 + 4 * G4 59 | 60 | // First corner 61 | vec4 i = floor(v + dot(v, vec4(F4)) ); 62 | vec4 x0 = v - i + dot(i, C.xxxx); 63 | 64 | // Other corners 65 | 66 | // Rank sorting originally contributed by Bill Licea-Kane, AMD (formerly ATI) 67 | vec4 i0; 68 | vec3 isX = step( x0.yzw, x0.xxx ); 69 | vec3 isYZ = step( x0.zww, x0.yyz ); 70 | // i0.x = dot( isX, vec3( 1.0 ) ); 71 | i0.x = isX.x + isX.y + isX.z; 72 | i0.yzw = 1.0 - isX; 73 | // i0.y += dot( isYZ.xy, vec2( 1.0 ) ); 74 | i0.y += isYZ.x + isYZ.y; 75 | i0.zw += 1.0 - isYZ.xy; 76 | i0.z += isYZ.z; 77 | i0.w += 1.0 - isYZ.z; 78 | 79 | // i0 now contains the unique values 0,1,2,3 in each channel 80 | vec4 i3 = clamp( i0, 0.0, 1.0 ); 81 | vec4 i2 = clamp( i0-1.0, 0.0, 1.0 ); 82 | vec4 i1 = clamp( i0-2.0, 0.0, 1.0 ); 83 | 84 | // x0 = x0 - 0.0 + 0.0 * C.xxxx 85 | // x1 = x0 - i1 + 1.0 * C.xxxx 86 | // x2 = x0 - i2 + 2.0 * C.xxxx 87 | // x3 = x0 - i3 + 3.0 * C.xxxx 88 | // x4 = x0 - 1.0 + 4.0 * C.xxxx 89 | vec4 x1 = x0 - i1 + C.xxxx; 90 | vec4 x2 = x0 - i2 + C.yyyy; 91 | vec4 x3 = x0 - i3 + C.zzzz; 92 | vec4 x4 = x0 + C.wwww; 93 | 94 | // Permutations 95 | i = mod289(i); 96 | float j0 = permute( permute( permute( permute(i.w) + i.z) + i.y) + i.x); 97 | vec4 j1 = permute( permute( permute( permute ( 98 | i.w + vec4(i1.w, i2.w, i3.w, 1.0 )) 99 | + i.z + vec4(i1.z, i2.z, i3.z, 1.0 )) 100 | + i.y + vec4(i1.y, i2.y, i3.y, 1.0 )) 101 | + i.x + vec4(i1.x, i2.x, i3.x, 1.0 )); 102 | 103 | // Gradients: 7x7x6 points over a cube, mapped onto a 4-cross polytope 104 | // 7*7*6 = 294, which is close to the ring size 17*17 = 289. 105 | vec4 ip = vec4(1.0/294.0, 1.0/49.0, 1.0/7.0, 0.0) ; 106 | 107 | vec4 p0 = grad4(j0, ip); 108 | vec4 p1 = grad4(j1.x, ip); 109 | vec4 p2 = grad4(j1.y, ip); 110 | vec4 p3 = grad4(j1.z, ip); 111 | vec4 p4 = grad4(j1.w, ip); 112 | 113 | // Normalise gradients 114 | vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3))); 115 | p0 *= norm.x; 116 | p1 *= norm.y; 117 | p2 *= norm.z; 118 | p3 *= norm.w; 119 | p4 *= taylorInvSqrt(dot(p4,p4)); 120 | 121 | // Mix contributions from the five corners 122 | vec3 m0 = max(0.57 - vec3(dot(x0,x0), dot(x1,x1), dot(x2,x2)), 0.0); 123 | vec2 m1 = max(0.57 - vec2(dot(x3,x3), dot(x4,x4) ), 0.0); 124 | m0 = m0 * m0; 125 | m1 = m1 * m1; 126 | return 60.1 * ( dot(m0*m0, vec3( dot( p0, x0 ), dot( p1, x1 ), dot( p2, x2 ))) 127 | + dot(m1*m1, vec2( dot( p3, x3 ), dot( p4, x4 ) ) ) ) ; 128 | 129 | } 130 | -------------------------------------------------------------------------------- /src/psrdnoise2D.glsl: -------------------------------------------------------------------------------- 1 | // 2 | // vec3 psrdnoise(vec2 pos, vec2 per, float rot) 3 | // vec3 psdnoise(vec2 pos, vec2 per) 4 | // float psrnoise(vec2 pos, vec2 per, float rot) 5 | // float psnoise(vec2 pos, vec2 per) 6 | // vec3 srdnoise(vec2 pos, float rot) 7 | // vec3 sdnoise(vec2 pos) 8 | // float srnoise(vec2 pos, float rot) 9 | // float snoise(vec2 pos) 10 | // 11 | // Periodic (tiling) 2-D simplex noise (hexagonal lattice gradient noise) 12 | // with rotating gradients and analytic derivatives. 13 | // Variants also without the derivative (no "d" in the name), without 14 | // the tiling property (no "p" in the name) and without the rotating 15 | // gradients (no "r" in the name). 16 | // 17 | // This is (yet) another variation on simplex noise. It's similar to the 18 | // version presented by Ken Perlin, but the grid is axis-aligned and 19 | // slightly stretched in the y direction to permit rectangular tiling. 20 | // 21 | // The noise can be made to tile seamlessly to any integer period in x and 22 | // any even integer period in y. Odd periods may be specified for y, but 23 | // then the actual tiling period will be twice that number. 24 | // 25 | // The rotating gradients give the appearance of a swirling motion, and can 26 | // serve a similar purpose for animation as motion along z in 3-D noise. 27 | // The rotating gradients in conjunction with the analytic derivatives 28 | // can make "flow noise" effects as presented by Perlin and Neyret. 29 | // 30 | // vec3 {p}s{r}dnoise(vec2 pos {, vec2 per} {, float rot}) 31 | // "pos" is the input (x,y) coordinate 32 | // "per" is the x and y period, where per.x is a positive integer 33 | // and per.y is a positive even integer 34 | // "rot" is the angle to rotate the gradients (any float value, 35 | // where 0.0 is no rotation and 1.0 is one full turn) 36 | // The first component of the 3-element return vector is the noise value. 37 | // The second and third components are the x and y partial derivatives. 38 | // 39 | // float {p}s{r}noise(vec2 pos {, vec2 per} {, float rot}) 40 | // "pos" is the input (x,y) coordinate 41 | // "per" is the x and y period, where per.x is a positive integer 42 | // and per.y is a positive even integer 43 | // "rot" is the angle to rotate the gradients (any float value, 44 | // where 0.0 is no rotation and 1.0 is one full turn) 45 | // The return value is the noise value. 46 | // Partial derivatives are not computed, making these functions faster. 47 | // 48 | // Author: Stefan Gustavson (stefan.gustavson@gmail.com) 49 | // Version 2016-05-10. 50 | // 51 | // Many thanks to Ian McEwan of Ashima Arts for the 52 | // idea of using a permutation polynomial. 53 | // 54 | // Copyright (c) 2016 Stefan Gustavson. All rights reserved. 55 | // Distributed under the MIT license. See LICENSE file. 56 | // https://github.com/stegu/webgl-noise 57 | // 58 | 59 | // 60 | // TODO: One-pixel wide artefacts used to occur due to precision issues with 61 | // the gradient indexing. This is specific to this variant of noise, because 62 | // one axis of the simplex grid is perfectly aligned with the input x axis. 63 | // The errors were rare, and they are now very unlikely to ever be visible 64 | // after a quick fix was introduced: a small offset is added to the y coordinate. 65 | // A proper fix would involve using round() instead of floor() in selected 66 | // places, but the quick fix works fine. 67 | // (If you run into problems with this, please let me know.) 68 | // 69 | 70 | // Modulo 289, optimizes to code without divisions 71 | vec3 mod289(vec3 x) { 72 | return x - floor(x * (1.0 / 289.0)) * 289.0; 73 | } 74 | 75 | float mod289(float x) { 76 | return x - floor(x * (1.0 / 289.0)) * 289.0; 77 | } 78 | 79 | // Permutation polynomial (ring size 289 = 17*17) 80 | vec3 permute(vec3 x) { 81 | return mod289(((x*34.0)+10.0)*x); 82 | } 83 | 84 | float permute(float x) { 85 | return mod289(((x*34.0)+1.0)*x); 86 | } 87 | 88 | // Hashed 2-D gradients with an extra rotation. 89 | // (The constant 0.0243902439 is 1/41) 90 | vec2 rgrad2(vec2 p, float rot) { 91 | #if 0 92 | // Map from a line to a diamond such that a shift maps to a rotation. 93 | float u = permute(permute(p.x) + p.y) * 0.0243902439 + rot; // Rotate by shift 94 | u = 4.0 * fract(u) - 2.0; 95 | // (This vector could be normalized, exactly or approximately.) 96 | return vec2(abs(u)-1.0, abs(abs(u+1.0)-2.0)-1.0); 97 | #else 98 | // For more isotropic gradients, sin/cos can be used instead. 99 | float u = permute(permute(p.x) + p.y) * 0.0243902439 + rot; // Rotate by shift 100 | u = fract(u) * 6.28318530718; // 2*pi 101 | return vec2(cos(u), sin(u)); 102 | #endif 103 | } 104 | 105 | // 106 | // 2-D tiling simplex noise with rotating gradients and analytical derivative. 107 | // The first component of the 3-element return vector is the noise value, 108 | // and the second and third components are the x and y partial derivatives. 109 | // 110 | vec3 psrdnoise(vec2 pos, vec2 per, float rot) { 111 | // Hack: offset y slightly to hide some rare artifacts 112 | pos.y += 0.01; 113 | // Skew to hexagonal grid 114 | vec2 uv = vec2(pos.x + pos.y*0.5, pos.y); 115 | 116 | vec2 i0 = floor(uv); 117 | vec2 f0 = fract(uv); 118 | // Traversal order 119 | vec2 i1 = (f0.x > f0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0); 120 | 121 | // Unskewed grid points in (x,y) space 122 | vec2 p0 = vec2(i0.x - i0.y * 0.5, i0.y); 123 | vec2 p1 = vec2(p0.x + i1.x - i1.y * 0.5, p0.y + i1.y); 124 | vec2 p2 = vec2(p0.x + 0.5, p0.y + 1.0); 125 | 126 | // Integer grid point indices in (u,v) space 127 | i1 = i0 + i1; 128 | vec2 i2 = i0 + vec2(1.0, 1.0); 129 | 130 | // Vectors in unskewed (x,y) coordinates from 131 | // each of the simplex corners to the evaluation point 132 | vec2 d0 = pos - p0; 133 | vec2 d1 = pos - p1; 134 | vec2 d2 = pos - p2; 135 | 136 | // Wrap i0, i1 and i2 to the desired period before gradient hashing: 137 | // wrap points in (x,y), map to (u,v) 138 | vec3 xw = mod(vec3(p0.x, p1.x, p2.x), per.x); 139 | vec3 yw = mod(vec3(p0.y, p1.y, p2.y), per.y); 140 | vec3 iuw = xw + 0.5 * yw; 141 | vec3 ivw = yw; 142 | 143 | // Create gradients from indices 144 | vec2 g0 = rgrad2(vec2(iuw.x, ivw.x), rot); 145 | vec2 g1 = rgrad2(vec2(iuw.y, ivw.y), rot); 146 | vec2 g2 = rgrad2(vec2(iuw.z, ivw.z), rot); 147 | 148 | // Gradients dot vectors to corresponding corners 149 | // (The derivatives of this are simply the gradients) 150 | vec3 w = vec3(dot(g0, d0), dot(g1, d1), dot(g2, d2)); 151 | 152 | // Radial weights from corners 153 | // 0.8 is the square of 2/sqrt(5), the distance from 154 | // a grid point to the nearest simplex boundary 155 | vec3 t = 0.8 - vec3(dot(d0, d0), dot(d1, d1), dot(d2, d2)); 156 | 157 | // Partial derivatives for analytical gradient computation 158 | vec3 dtdx = -2.0 * vec3(d0.x, d1.x, d2.x); 159 | vec3 dtdy = -2.0 * vec3(d0.y, d1.y, d2.y); 160 | 161 | // Set influence of each surflet to zero outside radius sqrt(0.8) 162 | if (t.x < 0.0) { 163 | dtdx.x = 0.0; 164 | dtdy.x = 0.0; 165 | t.x = 0.0; 166 | } 167 | if (t.y < 0.0) { 168 | dtdx.y = 0.0; 169 | dtdy.y = 0.0; 170 | t.y = 0.0; 171 | } 172 | if (t.z < 0.0) { 173 | dtdx.z = 0.0; 174 | dtdy.z = 0.0; 175 | t.z = 0.0; 176 | } 177 | 178 | // Fourth power of t (and third power for derivative) 179 | vec3 t2 = t * t; 180 | vec3 t4 = t2 * t2; 181 | vec3 t3 = t2 * t; 182 | 183 | // Final noise value is: 184 | // sum of ((radial weights) times (gradient dot vector from corner)) 185 | float n = dot(t4, w); 186 | 187 | // Final analytical derivative (gradient of a sum of scalar products) 188 | vec2 dt0 = vec2(dtdx.x, dtdy.x) * 4.0 * t3.x; 189 | vec2 dn0 = t4.x * g0 + dt0 * w.x; 190 | vec2 dt1 = vec2(dtdx.y, dtdy.y) * 4.0 * t3.y; 191 | vec2 dn1 = t4.y * g1 + dt1 * w.y; 192 | vec2 dt2 = vec2(dtdx.z, dtdy.z) * 4.0 * t3.z; 193 | vec2 dn2 = t4.z * g2 + dt2 * w.z; 194 | 195 | return 11.0*vec3(n, dn0 + dn1 + dn2); 196 | } 197 | 198 | // 199 | // 2-D tiling simplex noise with fixed gradients 200 | // and analytical derivative. 201 | // This function is implemented as a wrapper to "psrdnoise", 202 | // at the minimal cost of three extra additions. 203 | // 204 | vec3 psdnoise(vec2 pos, vec2 per) { 205 | return psrdnoise(pos, per, 0.0); 206 | } 207 | 208 | // 209 | // 2-D tiling simplex noise with rotating gradients, 210 | // but without the analytical derivative. 211 | // 212 | float psrnoise(vec2 pos, vec2 per, float rot) { 213 | // Offset y slightly to hide some rare artifacts 214 | pos.y += 0.001; 215 | // Skew to hexagonal grid 216 | vec2 uv = vec2(pos.x + pos.y*0.5, pos.y); 217 | 218 | vec2 i0 = floor(uv); 219 | vec2 f0 = fract(uv); 220 | // Traversal order 221 | vec2 i1 = (f0.x > f0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0); 222 | 223 | // Unskewed grid points in (x,y) space 224 | vec2 p0 = vec2(i0.x - i0.y * 0.5, i0.y); 225 | vec2 p1 = vec2(p0.x + i1.x - i1.y * 0.5, p0.y + i1.y); 226 | vec2 p2 = vec2(p0.x + 0.5, p0.y + 1.0); 227 | 228 | // Integer grid point indices in (u,v) space 229 | i1 = i0 + i1; 230 | vec2 i2 = i0 + vec2(1.0, 1.0); 231 | 232 | // Vectors in unskewed (x,y) coordinates from 233 | // each of the simplex corners to the evaluation point 234 | vec2 d0 = pos - p0; 235 | vec2 d1 = pos - p1; 236 | vec2 d2 = pos - p2; 237 | 238 | // Wrap i0, i1 and i2 to the desired period before gradient hashing: 239 | // wrap points in (x,y), map to (u,v) 240 | vec3 xw = mod(vec3(p0.x, p1.x, p2.x), per.x); 241 | vec3 yw = mod(vec3(p0.y, p1.y, p2.y), per.y); 242 | vec3 iuw = xw + 0.5 * yw; 243 | vec3 ivw = yw; 244 | 245 | // Create gradients from indices 246 | vec2 g0 = rgrad2(vec2(iuw.x, ivw.x), rot); 247 | vec2 g1 = rgrad2(vec2(iuw.y, ivw.y), rot); 248 | vec2 g2 = rgrad2(vec2(iuw.z, ivw.z), rot); 249 | 250 | // Gradients dot vectors to corresponding corners 251 | // (The derivatives of this are simply the gradients) 252 | vec3 w = vec3(dot(g0, d0), dot(g1, d1), dot(g2, d2)); 253 | 254 | // Radial weights from corners 255 | // 0.8 is the square of 2/sqrt(5), the distance from 256 | // a grid point to the nearest simplex boundary 257 | vec3 t = 0.8 - vec3(dot(d0, d0), dot(d1, d1), dot(d2, d2)); 258 | 259 | // Set influence of each surflet to zero outside radius sqrt(0.8) 260 | t = max(t, 0.0); 261 | 262 | // Fourth power of t 263 | vec3 t2 = t * t; 264 | vec3 t4 = t2 * t2; 265 | 266 | // Final noise value is: 267 | // sum of ((radial weights) times (gradient dot vector from corner)) 268 | float n = dot(t4, w); 269 | 270 | // Rescale to cover the range [-1,1] reasonably well 271 | return 11.0*n; 272 | } 273 | 274 | // 275 | // 2-D tiling simplex noise with fixed gradients, 276 | // without the analytical derivative. 277 | // This function is implemented as a wrapper to "psrnoise", 278 | // at the minimal cost of three extra additions. 279 | // 280 | float psnoise(vec2 pos, vec2 per) { 281 | return psrnoise(pos, per, 0.0); 282 | } 283 | 284 | // 285 | // 2-D non-tiling simplex noise with rotating gradients and analytical derivative. 286 | // The first component of the 3-element return vector is the noise value, 287 | // and the second and third components are the x and y partial derivatives. 288 | // 289 | vec3 srdnoise(vec2 pos, float rot) { 290 | // Offset y slightly to hide some rare artifacts 291 | pos.y += 0.001; 292 | // Skew to hexagonal grid 293 | vec2 uv = vec2(pos.x + pos.y*0.5, pos.y); 294 | 295 | vec2 i0 = floor(uv); 296 | vec2 f0 = fract(uv); 297 | // Traversal order 298 | vec2 i1 = (f0.x > f0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0); 299 | 300 | // Unskewed grid points in (x,y) space 301 | vec2 p0 = vec2(i0.x - i0.y * 0.5, i0.y); 302 | vec2 p1 = vec2(p0.x + i1.x - i1.y * 0.5, p0.y + i1.y); 303 | vec2 p2 = vec2(p0.x + 0.5, p0.y + 1.0); 304 | 305 | // Integer grid point indices in (u,v) space 306 | i1 = i0 + i1; 307 | vec2 i2 = i0 + vec2(1.0, 1.0); 308 | 309 | // Vectors in unskewed (x,y) coordinates from 310 | // each of the simplex corners to the evaluation point 311 | vec2 d0 = pos - p0; 312 | vec2 d1 = pos - p1; 313 | vec2 d2 = pos - p2; 314 | 315 | vec3 x = vec3(p0.x, p1.x, p2.x); 316 | vec3 y = vec3(p0.y, p1.y, p2.y); 317 | vec3 iuw = x + 0.5 * y; 318 | vec3 ivw = y; 319 | 320 | // Avoid precision issues in permutation 321 | iuw = mod289(iuw); 322 | ivw = mod289(ivw); 323 | 324 | // Create gradients from indices 325 | vec2 g0 = rgrad2(vec2(iuw.x, ivw.x), rot); 326 | vec2 g1 = rgrad2(vec2(iuw.y, ivw.y), rot); 327 | vec2 g2 = rgrad2(vec2(iuw.z, ivw.z), rot); 328 | 329 | // Gradients dot vectors to corresponding corners 330 | // (The derivatives of this are simply the gradients) 331 | vec3 w = vec3(dot(g0, d0), dot(g1, d1), dot(g2, d2)); 332 | 333 | // Radial weights from corners 334 | // 0.8 is the square of 2/sqrt(5), the distance from 335 | // a grid point to the nearest simplex boundary 336 | vec3 t = 0.8 - vec3(dot(d0, d0), dot(d1, d1), dot(d2, d2)); 337 | 338 | // Partial derivatives for analytical gradient computation 339 | vec3 dtdx = -2.0 * vec3(d0.x, d1.x, d2.x); 340 | vec3 dtdy = -2.0 * vec3(d0.y, d1.y, d2.y); 341 | 342 | // Set influence of each surflet to zero outside radius sqrt(0.8) 343 | if (t.x < 0.0) { 344 | dtdx.x = 0.0; 345 | dtdy.x = 0.0; 346 | t.x = 0.0; 347 | } 348 | if (t.y < 0.0) { 349 | dtdx.y = 0.0; 350 | dtdy.y = 0.0; 351 | t.y = 0.0; 352 | } 353 | if (t.z < 0.0) { 354 | dtdx.z = 0.0; 355 | dtdy.z = 0.0; 356 | t.z = 0.0; 357 | } 358 | 359 | // Fourth power of t (and third power for derivative) 360 | vec3 t2 = t * t; 361 | vec3 t4 = t2 * t2; 362 | vec3 t3 = t2 * t; 363 | 364 | // Final noise value is: 365 | // sum of ((radial weights) times (gradient dot vector from corner)) 366 | float n = dot(t4, w); 367 | 368 | // Final analytical derivative (gradient of a sum of scalar products) 369 | vec2 dt0 = vec2(dtdx.x, dtdy.x) * 4.0 * t3.x; 370 | vec2 dn0 = t4.x * g0 + dt0 * w.x; 371 | vec2 dt1 = vec2(dtdx.y, dtdy.y) * 4.0 * t3.y; 372 | vec2 dn1 = t4.y * g1 + dt1 * w.y; 373 | vec2 dt2 = vec2(dtdx.z, dtdy.z) * 4.0 * t3.z; 374 | vec2 dn2 = t4.z * g2 + dt2 * w.z; 375 | 376 | return 11.0*vec3(n, dn0 + dn1 + dn2); 377 | } 378 | 379 | // 380 | // 2-D non-tiling simplex noise with fixed gradients and analytical derivative. 381 | // This function is implemented as a wrapper to "srdnoise", 382 | // at the minimal cost of three extra additions. 383 | // 384 | vec3 sdnoise(vec2 pos) { 385 | return srdnoise(pos, 0.0); 386 | } 387 | 388 | // 389 | // 2-D non-tiling simplex noise with rotating gradients, 390 | // without the analytical derivative. 391 | // 392 | float srnoise(vec2 pos, float rot) { 393 | // Offset y slightly to hide some rare artifacts 394 | pos.y += 0.001; 395 | // Skew to hexagonal grid 396 | vec2 uv = vec2(pos.x + pos.y*0.5, pos.y); 397 | 398 | vec2 i0 = floor(uv); 399 | vec2 f0 = fract(uv); 400 | // Traversal order 401 | vec2 i1 = (f0.x > f0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0); 402 | 403 | // Unskewed grid points in (x,y) space 404 | vec2 p0 = vec2(i0.x - i0.y * 0.5, i0.y); 405 | vec2 p1 = vec2(p0.x + i1.x - i1.y * 0.5, p0.y + i1.y); 406 | vec2 p2 = vec2(p0.x + 0.5, p0.y + 1.0); 407 | 408 | // Integer grid point indices in (u,v) space 409 | i1 = i0 + i1; 410 | vec2 i2 = i0 + vec2(1.0, 1.0); 411 | 412 | // Vectors in unskewed (x,y) coordinates from 413 | // each of the simplex corners to the evaluation point 414 | vec2 d0 = pos - p0; 415 | vec2 d1 = pos - p1; 416 | vec2 d2 = pos - p2; 417 | 418 | // Wrap i0, i1 and i2 to the desired period before gradient hashing: 419 | // wrap points in (x,y), map to (u,v) 420 | vec3 x = vec3(p0.x, p1.x, p2.x); 421 | vec3 y = vec3(p0.y, p1.y, p2.y); 422 | vec3 iuw = x + 0.5 * y; 423 | vec3 ivw = y; 424 | 425 | // Avoid precision issues in permutation 426 | iuw = mod289(iuw); 427 | ivw = mod289(ivw); 428 | 429 | // Create gradients from indices 430 | vec2 g0 = rgrad2(vec2(iuw.x, ivw.x), rot); 431 | vec2 g1 = rgrad2(vec2(iuw.y, ivw.y), rot); 432 | vec2 g2 = rgrad2(vec2(iuw.z, ivw.z), rot); 433 | 434 | // Gradients dot vectors to corresponding corners 435 | // (The derivatives of this are simply the gradients) 436 | vec3 w = vec3(dot(g0, d0), dot(g1, d1), dot(g2, d2)); 437 | 438 | // Radial weights from corners 439 | // 0.8 is the square of 2/sqrt(5), the distance from 440 | // a grid point to the nearest simplex boundary 441 | vec3 t = 0.8 - vec3(dot(d0, d0), dot(d1, d1), dot(d2, d2)); 442 | 443 | // Set influence of each surflet to zero outside radius sqrt(0.8) 444 | t = max(t, 0.0); 445 | 446 | // Fourth power of t 447 | vec3 t2 = t * t; 448 | vec3 t4 = t2 * t2; 449 | 450 | // Final noise value is: 451 | // sum of ((radial weights) times (gradient dot vector from corner)) 452 | float n = dot(t4, w); 453 | 454 | // Rescale to cover the range [-1,1] reasonably well 455 | return 11.0*n; 456 | } 457 | 458 | // 459 | // 2-D non-tiling simplex noise with fixed gradients, 460 | // without the analytical derivative. 461 | // This function is implemented as a wrapper to "srnoise", 462 | // at the minimal cost of three extra additions. 463 | // Note: if this kind of noise is all you want, there are faster 464 | // GLSL implementations of non-tiling simplex noise out there. 465 | // This one is included mainly for completeness and compatibility 466 | // with the other functions in the file. 467 | // 468 | float snoise(vec2 pos) { 469 | return srnoise(pos, 0.0); 470 | } 471 | -------------------------------------------------------------------------------- /webdemo/cellular.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | GLSL noise library: cellular noise variants 6 | 7 | 8 | 9 | 10 | 11 |

12 | stegu/webgl-noise is 13 | a repository of GLSL shaders implementing Simplex, Perlin, and Worley noise. 14 |

15 | 16 | 21 | 22 |
23 | 24 |
25 | 26 |

27 | The library includes cellular (Worley) noise. The F1 channel is the distance to the closest feature point and F2 is the distance to the second closest feature point. There is an implementation that uses 3x3 areas and a faster variant that uses 2x2 area. The faster variant is very similar for the F1 channel, with only a few artifacts: 28 |

29 | 30 | 31 | 32 | 33 |

34 | The faster variant has many artifacts in the F2 channel: 35 |

36 | 37 | 38 | 39 | 40 |

41 | There's also a 3D version, where the slower variant uses 3x3x3 and the faster variant uses 2x2x2: 42 |

43 | 44 | 45 | 46 | 47 |

48 | The faster variant has many artifacts in the F2 channel: 49 |

50 | 51 | 52 | 53 | 54 |
55 | 56 |
57 |
58 |

Click on an image to generate a shadertoy-compatible shader:

59 | 60 |
61 |
62 | 63 |
64 | 65 | 66 | 67 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /webdemo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | GLSL noise library: Simplex and Perlin noise 6 | 7 | 8 | 9 | 10 | 11 |

12 | stegu/webgl-noise is 13 | a repository of GLSL shaders implementing Simplex, Perlin, and Worley noise. 14 |

15 | 16 | 21 | 22 |
23 | 24 |
25 | 26 |

27 | Compare 2D Simplex noise with 2D Perlin noise: 28 |

29 | 30 | 31 | 32 | 33 |

34 | 3D Simplex and Perlin noise on a sphere: 35 |

36 | 37 | 38 | 39 | 40 |

41 | The obvious visual differences between Simplex noise (left) and Perlin noise (right) disappear when many octaves are added using fractal Brownian motion (fBm). These are 2D slices through 3D noise: 42 |

43 | 44 | 45 | 46 | 47 |

48 | These are 3D slices through 4D noise: 49 |

50 | 51 | 52 | 53 | 54 |
55 | 56 |
57 |
58 |

Click on an image to generate a shadertoy-compatible shader:

59 | 60 |
61 |
62 | 63 |
64 | 65 | 66 | 67 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /webdemo/noisedemo.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Web demos for GLSL procedural noise. The shaders are loaded over 3 | * the network from the glsl files in this repository and displayed with 4 | * various effects added. 5 | * 6 | * This code is in the public domain. 7 | */ 8 | 9 | 'use strict'; 10 | 11 | // The shader will be assembled from 12 | // * a noise source file (e.g. noise3D.glsl) 13 | // * a glue function "color" that takes only a vec and returns a float 14 | // * an effect (one of EFFECTS) that assign to a float 'n' 15 | // * a shadertoy-compatible wrapper 16 | 17 | const EFFECTS = { 18 | '2d': { 19 | plain: ` 20 | float n = color(xyz.xy * 4.0); 21 | `, 22 | 23 | fbm: ` 24 | vec2 step = vec2(1.3, 1.7); 25 | float n = color(xyz.xy); 26 | n += 0.5 * color(xyz.xy * 2.0 - step); 27 | n += 0.25 * color(xyz.xy * 4.0 - 2.0 * step); 28 | n += 0.125 * color(xyz.xy * 8.0 - 3.0 * step); 29 | n += 0.0625 * color(xyz.xy * 16.0 - 4.0 * step); 30 | n += 0.03125 * color(xyz.xy * 32.0 - 5.0 * step); 31 | `, 32 | }, 33 | 34 | '3d': { 35 | plain: ` 36 | float n = color(xyz * 4.0); 37 | `, 38 | 39 | fbm: ` 40 | vec3 step = vec3(1.3, 1.7, 2.1); 41 | float n = color(xyz); 42 | n += 0.5 * color(xyz * 2.0 - step); 43 | n += 0.25 * color(xyz * 4.0 - 2.0 * step); 44 | n += 0.125 * color(xyz * 8.0 - 3.0 * step); 45 | n += 0.0625 * color(xyz * 16.0 - 4.0 * step); 46 | n += 0.03125 * color(xyz * 32.0 - 5.0 * step); 47 | `, 48 | }, 49 | }; 50 | 51 | 52 | /** 53 | * Create and compile a GL shader. 54 | * @param {WebGLRenderingContext} gl - webgl context 55 | * @param {GLEnum} type - gl.VERTEX_SHADER | gl.FRAGMENT_SHADER 56 | * @param {string} glsl 57 | * @returns {} shader 58 | */ 59 | function createGlShader(gl, type, glsl) { 60 | let shader = gl.createShader(type); 61 | gl.shaderSource(shader, glsl); 62 | gl.compileShader(shader); 63 | if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { 64 | console.log(gl.getShaderInfoLog(shader)); 65 | gl.deleteShader(shader); 66 | return; 67 | } 68 | return shader; 69 | } 70 | 71 | /** 72 | * Construct a shadertoy-compatible shader program 73 | * @param {"2d" | "3d"} shape - whether to use xy or xyz 74 | * @param {string} sourceFile - url with the fragment shader to load 75 | * @param {string} glueFrag - a glsl expression to generate a color 76 | */ 77 | async function createFragShader(shape, sourceFile, glueFrag, effect) { 78 | let noiseFrag = await fetch(`../src/${sourceFile}`); 79 | noiseFrag = await noiseFrag.text(); 80 | noiseFrag = noiseFrag.replace('#version 120', '', noiseFrag); 81 | 82 | let reshapeFrag; 83 | if (shape === '3d') { 84 | reshapeFrag = ` 85 | float z_squared = 1.0 - length(p.xy); 86 | if (z_squared < 0.0) { fragColor = vec4(0, 0, 0, 1); return; } 87 | vec3 xyz = vec3(p, -sqrt(z_squared)); 88 | ${EFFECTS[shape][effect]} 89 | fragColor.xyz = mix(0.0, 0.5 + 0.5 * n, smoothstep(0.0, 0.003, z_squared)) * vec3(1, 1, 1); 90 | `; 91 | } else { 92 | reshapeFrag = ` 93 | vec3 xyz = vec3(p, 0); 94 | ${EFFECTS[shape][effect]} 95 | fragColor.xyz = vec3(0.5 + 0.5 * vec3(n, n, n)); 96 | `; 97 | } 98 | 99 | return `${noiseFrag} 100 | // demo code: 101 | float color(${shape === '3d'? 'vec3 xyz' : 'vec2 xy'}) { return ${glueFrag}; } 102 | void mainImage(out vec4 fragColor, in vec2 fragCoord) { 103 | vec2 p = (fragCoord.xy/iResolution.y) * 2.0 - 1.0; 104 | ${reshapeFrag} 105 | }`; 106 | 107 | } 108 | 109 | /** 110 | * Draw a webgl diagram 111 | * @param {string} selector - a css selector for the target canvas 112 | * @param {"2d" | "3d"} shape - whether to use xy or xyz 113 | * @param {string} sourceFile - url with the fragment shader to load 114 | * @param {string} glueFrag - a glsl expression to generate a color 115 | * @param {"plain" | "fbm"} effect - one octave or many 116 | * @param {boolean} animate - whether to redraw every frame 117 | */ 118 | async function Diagram(selector, shape, sourceFile, glueFrag, effect, animate) { 119 | let shadertoyFrag = await createFragShader(shape, sourceFile, glueFrag, effect); 120 | let frag = ` 121 | precision highp float; // medium sufficient on desktop, high needed on mobile 122 | uniform float iTime; 123 | uniform vec2 iResolution; 124 | uniform vec2 per; 125 | 126 | ${shadertoyFrag} 127 | 128 | void main() { 129 | mainImage(gl_FragColor, gl_FragCoord.xy); 130 | gl_FragColor.a = 1.0; 131 | }`; 132 | 133 | let vert = ` 134 | precision highp float; 135 | attribute vec2 a_position; 136 | void main () { 137 | gl_Position = vec4(a_position, 0, 1); 138 | }`; 139 | 140 | const canvas = document.querySelector(selector); 141 | const gl = /** @type{WebGLRenderingContext} */ (canvas.getContext('webgl')); 142 | let canvasSize = {w: canvas.clientWidth, h: canvas.clientHeight}; 143 | canvas.width = gl.viewportWidth = canvasSize.w | 0; 144 | canvas.height = gl.viewportHeight = canvasSize.h | 0; 145 | 146 | let vertShader = createGlShader(gl, gl.VERTEX_SHADER, vert); 147 | let fragShader = createGlShader(gl, gl.FRAGMENT_SHADER, frag); 148 | let program = gl.createProgram(); 149 | gl.attachShader(program, vertShader); 150 | gl.attachShader(program, fragShader); 151 | gl.linkProgram(program); 152 | if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { 153 | console.log(gl.getProgramInfoLog(program)); 154 | gl.deleteProgram(program); 155 | return; 156 | } 157 | 158 | let locations = { 159 | a_position: gl.getAttribLocation(program, 'a_position'), 160 | iTime: gl.getUniformLocation(program, 'iTime'), 161 | iResolution: gl.getUniformLocation(program, 'iResolution'), 162 | per: gl.getUniformLocation(program, 'per'), 163 | }; 164 | 165 | let positionBuffer = gl.createBuffer(); 166 | gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); 167 | gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-4, -4, +4, -4, 0, +4]), gl.STATIC_DRAW); 168 | 169 | const startTime = Date.now(); 170 | let sliders = {}; 171 | let changed = true; 172 | 173 | function draw() { 174 | if (animate || changed) { 175 | changed = false; 176 | 177 | gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight); 178 | gl.clearColor(1, 0, 1, 1); 179 | gl.clear(gl.COLOR_BUFFER_BIT); 180 | 181 | gl.useProgram(program); 182 | 183 | gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); 184 | gl.vertexAttribPointer(locations.a_position, 2, gl.FLOAT, false, 0, 0); 185 | gl.enableVertexAttribArray(locations.a_position); 186 | 187 | gl.uniform1f(locations.iTime, (Date.now() - startTime) * 1e-3); 188 | gl.uniform2f(locations.iResolution, gl.viewportWidth, gl.viewportHeight); 189 | gl.uniform2f(locations.per, 190 | sliders?.per_x?.valueAsNumber ?? 1.0, 191 | sliders?.per_y?.valueAsNumber ?? 1.0); 192 | 193 | gl.drawArrays(gl.TRIANGLES, 0, 3); 194 | } 195 | requestAnimationFrame(draw); 196 | } 197 | 198 | // Set up event listeners on sliders to trigger redraw 199 | for (let slider of document.querySelectorAll("input[type=range]")) { 200 | sliders[slider.getAttribute("id")] = slider; 201 | slider.addEventListener('input', () => { changed = true; }); 202 | } 203 | 204 | // Click on the diagram to see a shadertoy version 205 | canvas.addEventListener('click', () => { 206 | document.querySelector("textarea").value = shadertoyFrag; 207 | }); 208 | 209 | // Redraw loop will run forever 210 | draw(); 211 | } 212 | -------------------------------------------------------------------------------- /webdemo/periodic.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | GLSL noise library demo: periodic and rotation variants 6 | 7 | 8 | 9 | 10 | 11 |

12 | stegu/webgl-noise is 13 | a repository of GLSL shaders implementing Simplex, Perlin, and Worley noise. 14 |

15 | 16 | 21 | 22 |
23 | 24 |
25 | 26 |

27 | The library includes a variant of Simplex Noise that supports rotation within each hexagonal area. Watching the animation shows how Simplex Noise results in hexagons divided into a dark and light half: 28 |

29 | 30 | 31 | 32 | 33 |

34 | The library includes periodic Simplex (2D) and periodic Perlin noise (2D, 3D, 4D). 35 |
36 | per.x= 37 | per.y= 38 |

39 | 40 | 41 | 42 | 43 |

44 | Some of the shaders also include variants that calculate analytic derivatives. 45 |

46 | 47 |
48 | 49 |
50 |
51 |

Click on an image to generate a shadertoy-compatible shader:

52 | 53 |
54 |
55 | 56 |
57 | 58 | 59 | 60 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /webdemo/style.css: -------------------------------------------------------------------------------- 1 | * { box-sizing: border-box; } 2 | 3 | canvas { max-width: 49%; cursor: hand; } 4 | 5 | .side-by-side { display: grid; grid-template-columns: 6fr 4fr; grid-gap: 1em; justify-items: top; } 6 | @media (max-width: 60em) { .side-by-side { grid-template-columns: 1fr; } } 7 | 8 | .source { position: relative; } 9 | .source > div { position: sticky; top: 0; } 10 | .source > div > textarea { width: 100%; height: 95vh; overflow-x: auto; } 11 | --------------------------------------------------------------------------------