Feat : add local reference to fbm.glsl

This commit is contained in:
2024-06-30 14:50:58 +02:00
parent 6cc91d58ce
commit 1fbe9a57ee
2 changed files with 627 additions and 3 deletions
+7 -3
View File
@@ -1,4 +1,7 @@
function getFile(url) {
if(url == "https://lygia.xyz/generative/fbm.glsl"){
url = "/fbm.glsl"
}
let httpRequest = new XMLHttpRequest();
httpRequest.open("GET", url, false);
httpRequest.send();
@@ -8,6 +11,8 @@ function getFile(url) {
return "";
}
const lygiaURL = "https://lygia.xyz"
function resolveLygia(lines) {
if ( !Array.isArray(lines) ) {
lines = lines.split(/\r?\n/);
@@ -18,14 +23,13 @@ function resolveLygia(lines) {
const line_trim = line.trim();
if (line_trim.startsWith('#include \"lygia') ) {
let include_url = line_trim.substring(15);
include_url = "https://lygia.xyz" + include_url.replace(/\"|\;|\s/g,'');
include_url = lygiaURL + include_url.replace(/\"|\;|\s/g,'');
src += getFile(include_url) + '\n';
}
else {
src += line + '\n';
}
});
return src;
}
@@ -39,7 +43,7 @@ async function resolveLygiaAsync(lines) {
const line_trim = line.trim();
if (line_trim.startsWith('#include "lygia')) {
let include_url = line_trim.substring(15);
include_url = "https://lygia.xyz" + include_url.replace(/\"|\;|\s/g, "");
include_url = lygiaURL + include_url.replace(/\"|\;|\s/g, "");
return fetch(include_url).then((res) => res.text());
}
else
+620
View File
@@ -0,0 +1,620 @@
/*
contributors: [Stefan Gustavson, Ian McEwan]
description: modulus of 289
use: <float|vec2|vec3|vec4> mod289(<float|vec2|vec3|vec4> x)
*/
#ifndef FNC_MOD289
#define FNC_MOD289
float mod289(const in float x) { return x - floor(x * (1. / 289.)) * 289.; }
vec2 mod289(const in vec2 x) { return x - floor(x * (1. / 289.)) * 289.; }
vec3 mod289(const in vec3 x) { return x - floor(x * (1. / 289.)) * 289.; }
vec4 mod289(const in vec4 x) { return x - floor(x * (1. / 289.)) * 289.; }
#endif
/*
contributors: [Stefan Gustavson, Ian McEwan]
description: permute
use: <float|vec2|vec3|vec4> permute(<float|vec2|vec3|vec4> x)
examples:
- https://raw.githubusercontent.com/patriciogonzalezvivo/lygia_examples/main/math_functions.frag
*/
#ifndef FNC_PERMUTE
#define FNC_PERMUTE
float permute(const in float v) { return mod289(((v * 34.0) + 1.0) * v); }
vec2 permute(const in vec2 v) { return mod289(((v * 34.0) + 1.0) * v); }
vec3 permute(const in vec3 v) { return mod289(((v * 34.0) + 1.0) * v); }
vec4 permute(const in vec4 v) { return mod289(((v * 34.0) + 1.0) * v); }
#endif
/*
contributors: [Stefan Gustavson, Ian McEwan]
description: Fast, accurate inverse square root.
use: <float|vec2|vec3|vec4> taylorInvSqrt(<float|vec2|vec3|vec4> x)
*/
#ifndef FNC_TAYLORINVSQRT
#define FNC_TAYLORINVSQRT
float taylorInvSqrt(in float r) { return 1.79284291400159 - 0.85373472095314 * r; }
vec2 taylorInvSqrt(in vec2 r) { return 1.79284291400159 - 0.85373472095314 * r; }
vec3 taylorInvSqrt(in vec3 r) { return 1.79284291400159 - 0.85373472095314 * r; }
vec4 taylorInvSqrt(in vec4 r) { return 1.79284291400159 - 0.85373472095314 * r; }
#endif
/*
contributors: [Stefan Gustavson, Ian McEwan]
description: grad4, used for snoise(vec4 v)
use: grad4(<float> j, <vec4> ip)
*/
#ifndef FNC_GRAD4
#define FNC_GRAD4
vec4 grad4(float j, vec4 ip) {
const vec4 ones = vec4(1.0, 1.0, 1.0, -1.0);
vec4 p,s;
p.xyz = floor( fract (vec3(j) * ip.xyz) * 7.0) * ip.z - 1.0;
p.w = 1.5 - dot(abs(p.xyz), ones.xyz);
s = vec4(lessThan(p, vec4(0.0)));
p.xyz = p.xyz + (s.xyz*2.0 - 1.0) * s.www;
return p;
}
#endif
/*
contributors: [Stefan Gustavson, Ian McEwan]
description: Simplex Noise https://github.com/stegu/webgl-noise
use: snoise(<vec2|vec3|vec4> pos)
license: |
Copyright 2021-2023 by Stefan Gustavson and Ian McEwan.
Published under the terms of the MIT license:
https://opensource.org/license/mit/
examples:
- /shaders/generative_snoise.frag
*/
#ifndef FNC_SNOISE
#define FNC_SNOISE
float snoise(in vec2 v) {
const vec4 C = vec4(0.211324865405187, // (3.0-sqrt(3.0))/6.0
0.366025403784439, // 0.5*(sqrt(3.0)-1.0)
-0.577350269189626, // -1.0 + 2.0 * C.x
0.024390243902439); // 1.0 / 41.0
// First corner
vec2 i = floor(v + dot(v, C.yy) );
vec2 x0 = v - i + dot(i, C.xx);
// Other corners
vec2 i1;
//i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0
//i1.y = 1.0 - i1.x;
i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);
// x0 = x0 - 0.0 + 0.0 * C.xx ;
// x1 = x0 - i1 + 1.0 * C.xx ;
// x2 = x0 - 1.0 + 2.0 * C.xx ;
vec4 x12 = x0.xyxy + C.xxzz;
x12.xy -= i1;
// Permutations
i = mod289(i); // Avoid truncation effects in permutation
vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 ))
+ i.x + vec3(0.0, i1.x, 1.0 ));
vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0);
m = m*m ;
m = m*m ;
// Gradients: 41 points uniformly over a line, mapped onto a diamond.
// The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287)
vec3 x = 2.0 * fract(p * C.www) - 1.0;
vec3 h = abs(x) - 0.5;
vec3 ox = floor(x + 0.5);
vec3 a0 = x - ox;
// Normalise gradients implicitly by scaling m
// Approximation of: m *= inversesqrt( a0*a0 + h*h );
m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h );
// Compute final noise value at P
vec3 g;
g.x = a0.x * x0.x + h.x * x0.y;
g.yz = a0.yz * x12.xz + h.yz * x12.yw;
return 130.0 * dot(m, g);
}
float snoise(in vec3 v) {
const vec2 C = vec2(1.0/6.0, 1.0/3.0) ;
const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);
// First corner
vec3 i = floor(v + dot(v, C.yyy) );
vec3 x0 = v - i + dot(i, C.xxx) ;
// Other corners
vec3 g = step(x0.yzx, x0.xyz);
vec3 l = 1.0 - g;
vec3 i1 = min( g.xyz, l.zxy );
vec3 i2 = max( g.xyz, l.zxy );
// x0 = x0 - 0.0 + 0.0 * C.xxx;
// x1 = x0 - i1 + 1.0 * C.xxx;
// x2 = x0 - i2 + 2.0 * C.xxx;
// x3 = x0 - 1.0 + 3.0 * C.xxx;
vec3 x1 = x0 - i1 + C.xxx;
vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y
vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y
// Permutations
i = mod289(i);
vec4 p = permute( permute( permute(
i.z + vec4(0.0, i1.z, i2.z, 1.0 ))
+ i.y + vec4(0.0, i1.y, i2.y, 1.0 ))
+ i.x + vec4(0.0, i1.x, i2.x, 1.0 ));
// Gradients: 7x7 points over a square, mapped onto an octahedron.
// The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)
float n_ = 0.142857142857; // 1.0/7.0
vec3 ns = n_ * D.wyz - D.xzx;
vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7)
vec4 x_ = floor(j * ns.z);
vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N)
vec4 x = x_ *ns.x + ns.yyyy;
vec4 y = y_ *ns.x + ns.yyyy;
vec4 h = 1.0 - abs(x) - abs(y);
vec4 b0 = vec4( x.xy, y.xy );
vec4 b1 = vec4( x.zw, y.zw );
//vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0;
//vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0;
vec4 s0 = floor(b0)*2.0 + 1.0;
vec4 s1 = floor(b1)*2.0 + 1.0;
vec4 sh = -step(h, vec4(0.0));
vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ;
vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ;
vec3 p0 = vec3(a0.xy,h.x);
vec3 p1 = vec3(a0.zw,h.y);
vec3 p2 = vec3(a1.xy,h.z);
vec3 p3 = vec3(a1.zw,h.w);
//Normalise gradients
vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));
p0 *= norm.x;
p1 *= norm.y;
p2 *= norm.z;
p3 *= norm.w;
// Mix final noise value
vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);
m = m * m;
return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1),
dot(p2,x2), dot(p3,x3) ) );
}
float snoise(in vec4 v) {
const vec4 C = vec4( 0.138196601125011, // (5 - sqrt(5))/20 G4
0.276393202250021, // 2 * G4
0.414589803375032, // 3 * G4
-0.447213595499958); // -1 + 4 * G4
// First corner
vec4 i = floor(v + dot(v, vec4(.309016994374947451)) ); // (sqrt(5) - 1)/4
vec4 x0 = v - i + dot(i, C.xxxx);
// Other corners
// Rank sorting originally contributed by Bill Licea-Kane, AMD (formerly ATI)
vec4 i0;
vec3 isX = step( x0.yzw, x0.xxx );
vec3 isYZ = step( x0.zww, x0.yyz );
// i0.x = dot( isX, vec3( 1.0 ) );
i0.x = isX.x + isX.y + isX.z;
i0.yzw = 1.0 - isX;
// i0.y += dot( isYZ.xy, vec2( 1.0 ) );
i0.y += isYZ.x + isYZ.y;
i0.zw += 1.0 - isYZ.xy;
i0.z += isYZ.z;
i0.w += 1.0 - isYZ.z;
// i0 now contains the unique values 0,1,2,3 in each channel
vec4 i3 = clamp( i0, 0.0, 1.0 );
vec4 i2 = clamp( i0-1.0, 0.0, 1.0 );
vec4 i1 = clamp( i0-2.0, 0.0, 1.0 );
// x0 = x0 - 0.0 + 0.0 * C.xxxx
// x1 = x0 - i1 + 1.0 * C.xxxx
// x2 = x0 - i2 + 2.0 * C.xxxx
// x3 = x0 - i3 + 3.0 * C.xxxx
// x4 = x0 - 1.0 + 4.0 * C.xxxx
vec4 x1 = x0 - i1 + C.xxxx;
vec4 x2 = x0 - i2 + C.yyyy;
vec4 x3 = x0 - i3 + C.zzzz;
vec4 x4 = x0 + C.wwww;
// Permutations
i = mod289(i);
float j0 = permute( permute( permute( permute(i.w) + i.z) + i.y) + i.x);
vec4 j1 = permute( permute( permute( permute (
i.w + vec4(i1.w, i2.w, i3.w, 1.0 ))
+ i.z + vec4(i1.z, i2.z, i3.z, 1.0 ))
+ i.y + vec4(i1.y, i2.y, i3.y, 1.0 ))
+ i.x + vec4(i1.x, i2.x, i3.x, 1.0 ));
// Gradients: 7x7x6 points over a cube, mapped onto a 4-cross polytope
// 7*7*6 = 294, which is close to the ring size 17*17 = 289.
vec4 ip = vec4(1.0/294.0, 1.0/49.0, 1.0/7.0, 0.0) ;
vec4 p0 = grad4(j0, ip);
vec4 p1 = grad4(j1.x, ip);
vec4 p2 = grad4(j1.y, ip);
vec4 p3 = grad4(j1.z, ip);
vec4 p4 = grad4(j1.w, ip);
// Normalise gradients
vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));
p0 *= norm.x;
p1 *= norm.y;
p2 *= norm.z;
p3 *= norm.w;
p4 *= taylorInvSqrt(dot(p4,p4));
// Mix contributions from the five corners
vec3 m0 = max(0.6 - vec3(dot(x0,x0), dot(x1,x1), dot(x2,x2)), 0.0);
vec2 m1 = max(0.6 - vec2(dot(x3,x3), dot(x4,x4) ), 0.0);
m0 = m0 * m0;
m1 = m1 * m1;
return 49.0 * ( dot(m0*m0, vec3( dot( p0, x0 ), dot( p1, x1 ), dot( p2, x2 )))
+ dot(m1*m1, vec2( dot( p3, x3 ), dot( p4, x4 ) ) ) ) ;
}
vec2 snoise2( vec2 x ){
float s = snoise(vec2( x ));
float s1 = snoise(vec2( x.y - 19.1, x.x + 47.2 ));
return vec2( s , s1 );
}
vec3 snoise3( vec3 x ){
float s = snoise(vec3( x ));
float s1 = snoise(vec3( x.y - 19.1 , x.z + 33.4 , x.x + 47.2 ));
float s2 = snoise(vec3( x.z + 74.2 , x.x - 124.5 , x.y + 99.4 ));
return vec3( s , s1 , s2 );
}
vec3 snoise3( vec4 x ){
float s = snoise(vec4( x ));
float s1 = snoise(vec4( x.y - 19.1 , x.z + 33.4 , x.x + 47.2, x.w ));
float s2 = snoise(vec4( x.z + 74.2 , x.x - 124.5 , x.y + 99.4, x.w ));
return vec3( s , s1 , s2 );
}
#endif
/*
contributors: ["Patricio Gonzalez Vivo", "David Hoskins", "Inigo Quilez"]
description: Pass a value and get some random normalize value between 0 and 1
use: float random[2|3](<float|vec2|vec3> value)
options:
- RANDOM_HIGHER_RANGE: for working with a range over 0 and 1
- RANDOM_SINLESS: Use sin-less random, which tolerates bigger values before producing pattern. From https://www.shadertoy.com/view/4djSRW
- RANDOM_SCALE: by default this scale if for number with a big range. For producing good random between 0 and 1 use bigger range
examples:
- /shaders/generative_random.frag
license:
- MIT License (MIT) Copyright 2014, David Hoskins
*/
#ifndef RANDOM_SCALE
#ifdef RANDOM_HIGHER_RANGE
#define RANDOM_SCALE vec4(.1031, .1030, .0973, .1099)
#else
#define RANDOM_SCALE vec4(443.897, 441.423, .0973, .1099)
#endif
#endif
#ifndef FNC_RANDOM
#define FNC_RANDOM
float random(in float x) {
#ifdef RANDOM_SINLESS
x = fract(x * RANDOM_SCALE.x);
x *= x + 33.33;
x *= x + x;
return fract(x);
#else
return fract(sin(x) * 43758.5453);
#endif
}
float random(in vec2 st) {
#ifdef RANDOM_SINLESS
vec3 p3 = fract(vec3(st.xyx) * RANDOM_SCALE.xyz);
p3 += dot(p3, p3.yzx + 33.33);
return fract((p3.x + p3.y) * p3.z);
#else
return fract(sin(dot(st.xy, vec2(12.9898, 78.233))) * 43758.5453);
#endif
}
float random(in vec3 pos) {
#ifdef RANDOM_SINLESS
pos = fract(pos * RANDOM_SCALE.xyz);
pos += dot(pos, pos.zyx + 31.32);
return fract((pos.x + pos.y) * pos.z);
#else
return fract(sin(dot(pos.xyz, vec3(70.9898, 78.233, 32.4355))) * 43758.5453123);
#endif
}
float random(in vec4 pos) {
#ifdef RANDOM_SINLESS
pos = fract(pos * RANDOM_SCALE);
pos += dot(pos, pos.wzxy + 33.33);
return fract((pos.x + pos.y) * (pos.z + pos.w));
#else
float dot_product = dot(pos, vec4(12.9898,78.233,45.164,94.673));
return fract(sin(dot_product) * 43758.5453);
#endif
}
vec2 random2(float p) {
vec3 p3 = fract(vec3(p) * RANDOM_SCALE.xyz);
p3 += dot(p3, p3.yzx + 19.19);
return fract((p3.xx + p3.yz) * p3.zy);
}
vec2 random2(vec2 p) {
vec3 p3 = fract(p.xyx * RANDOM_SCALE.xyz);
p3 += dot(p3, p3.yzx + 19.19);
return fract((p3.xx + p3.yz) * p3.zy);
}
vec2 random2(vec3 p3) {
p3 = fract(p3 * RANDOM_SCALE.xyz);
p3 += dot(p3, p3.yzx + 19.19);
return fract((p3.xx + p3.yz) * p3.zy);
}
vec3 random3(float p) {
vec3 p3 = fract(vec3(p) * RANDOM_SCALE.xyz);
p3 += dot(p3, p3.yzx + 19.19);
return fract((p3.xxy + p3.yzz) * p3.zyx);
}
vec3 random3(vec2 p) {
vec3 p3 = fract(vec3(p.xyx) * RANDOM_SCALE.xyz);
p3 += dot(p3, p3.yxz + 19.19);
return fract((p3.xxy + p3.yzz) * p3.zyx);
}
vec3 random3(vec3 p) {
p = fract(p * RANDOM_SCALE.xyz);
p += dot(p, p.yxz + 19.19);
return fract((p.xxy + p.yzz) * p.zyx);
}
vec4 random4(float p) {
vec4 p4 = fract(p * RANDOM_SCALE);
p4 += dot(p4, p4.wzxy + 19.19);
return fract((p4.xxyz + p4.yzzw) * p4.zywx);
}
vec4 random4(vec2 p) {
vec4 p4 = fract(p.xyxy * RANDOM_SCALE);
p4 += dot(p4, p4.wzxy + 19.19);
return fract((p4.xxyz + p4.yzzw) * p4.zywx);
}
vec4 random4(vec3 p) {
vec4 p4 = fract(p.xyzx * RANDOM_SCALE);
p4 += dot(p4, p4.wzxy + 19.19);
return fract((p4.xxyz + p4.yzzw) * p4.zywx);
}
vec4 random4(vec4 p4) {
p4 = fract(p4 * RANDOM_SCALE);
p4 += dot(p4, p4.wzxy + 19.19);
return fract((p4.xxyz + p4.yzzw) * p4.zywx);
}
#endif
/*
contributors: Patricio Gonzalez Vivo
description: Signed Random
use: srandomX(<vec2|vec3> x)
license:
- Copyright (c) 2021 Patricio Gonzalez Vivo under Prosperity License - https://prosperitylicense.com/versions/3.0.0
- Copyright (c) 2021 Patricio Gonzalez Vivo under Patron License - https://lygia.xyz/license
*/
#ifndef FNC_SRANDOM
#define FNC_SRANDOM
float srandom(in float x) {
return -1. + 2. * fract(sin(x) * 43758.5453);
}
float srandom(in vec2 st) {
return -1. + 2. * fract(sin(dot(st.xy, vec2(12.9898, 78.233))) * 43758.5453);
}
float srandom(in vec3 pos) {
return -1. + 2. * fract(sin(dot(pos.xyz, vec3(70.9898, 78.233, 32.4355))) * 43758.5453123);
}
float srandom(in vec4 pos) {
float dot_product = dot(pos, vec4(12.9898,78.233,45.164,94.673));
return -1. + 2. * fract(sin(dot_product) * 43758.5453);
}
vec2 srandom2(in vec2 st) {
const vec2 k = vec2(.3183099, .3678794);
st = st * k + k.yx;
return -1. + 2. * fract(16. * k * fract(st.x * st.y * (st.x + st.y)));
}
vec3 srandom3(in vec3 p) {
p = vec3( dot(p, vec3(127.1, 311.7, 74.7)),
dot(p, vec3(269.5, 183.3, 246.1)),
dot(p, vec3(113.5, 271.9, 124.6)));
return -1. + 2. * fract(sin(p) * 43758.5453123);
}
vec2 srandom2(in vec2 p, const in float tileLength) {
p = mod(p, vec2(tileLength));
return srandom2(p);
}
vec3 srandom3(in vec3 p, const in float tileLength) {
p = mod(p, vec3(tileLength));
return srandom3(p);
}
#endif
/*
contributors: Inigo Quiles
description: cubic polynomial https://iquilezles.org/articles/smoothsteps/
use: <float|vec2|vec3|vec4> cubic(<float|vec2|vec3|vec4> value[, <float> in, <float> out]);
examples:
- https://raw.githubusercontent.com/patriciogonzalezvivo/lygia_examples/main/math_functions.frag
*/
#ifndef FNC_CUBIC
#define FNC_CUBIC
float cubic(const in float v) { return v*v*(3.0-2.0*v); }
vec2 cubic(const in vec2 v) { return v*v*(3.0-2.0*v); }
vec3 cubic(const in vec3 v) { return v*v*(3.0-2.0*v); }
vec4 cubic(const in vec4 v) { return v*v*(3.0-2.0*v); }
float cubic(const in float v, in float slope0, in float slope1) {
float a = slope0 + slope1 - 2.;
float b = -2. * slope0 - slope1 + 3.;
float c = slope0;
float v2 = v * v;
float v3 = v * v2;
return a * v3 + b * v2 + c * v;
}
vec2 cubic(const in vec2 v, in float slope0, in float slope1) {
float a = slope0 + slope1 - 2.;
float b = -2. * slope0 - slope1 + 3.;
float c = slope0;
vec2 v2 = v * v;
vec2 v3 = v * v2;
return a * v3 + b * v2 + c * v;
}
vec3 cubic(const in vec3 v, in float slope0, in float slope1) {
float a = slope0 + slope1 - 2.;
float b = -2. * slope0 - slope1 + 3.;
float c = slope0;
vec3 v2 = v * v;
vec3 v3 = v * v2;
return a * v3 + b * v2 + c * v;
}
vec4 cubic(const in vec4 v, in float slope0, in float slope1) {
float a = slope0 + slope1 - 2.;
float b = -2. * slope0 - slope1 + 3.;
float c = slope0;
vec4 v2 = v * v;
vec4 v3 = v * v2;
return a * v3 + b * v2 + c * v;
}
#endif
/*
contributors: Inigo Quiles
description: quintic polynomial https://iquilezles.org/articles/smoothsteps/
use: <float|vec2|vec3|vec4> quintic(<float|vec2|vec3|vec4> value);
examples:
- https://raw.githubusercontent.com/patriciogonzalezvivo/lygia_examples/main/math_functions.frag
*/
#ifndef FNC_QUINTIC
#define FNC_QUINTIC
float quintic(const in float v) { return v*v*v*(v*(v*6.0-15.0)+10.0); }
vec2 quintic(const in vec2 v) { return v*v*v*(v*(v*6.0-15.0)+10.0); }
vec3 quintic(const in vec3 v) { return v*v*v*(v*(v*6.0-15.0)+10.0); }
vec4 quintic(const in vec4 v) { return v*v*v*(v*(v*6.0-15.0)+10.0); }
#endif
/*
contributors: Patricio Gonzalez Vivo
description: Gradient Noise
use: gnoise(<float> x)
license:
- Copyright (c) 2021 Patricio Gonzalez Vivo under Prosperity License - https://prosperitylicense.com/versions/3.0.0
- Copyright (c) 2021 Patricio Gonzalez Vivo under Patron License - https://lygia.xyz/license
*/
#ifndef FNC_GNOISE
#define FNC_GNOISE
float gnoise(float x) {
float i = floor(x); // integer
float f = fract(x); // fraction
return mix(random(i), random(i + 1.0), smoothstep(0.,1.,f));
}
float gnoise(vec2 st) {
vec2 i = floor(st);
vec2 f = fract(st);
float a = random(i);
float b = random(i + vec2(1.0, 0.0));
float c = random(i + vec2(0.0, 1.0));
float d = random(i + vec2(1.0, 1.0));
vec2 u = cubic(f);
return mix( a, b, u.x) +
(c - a)* u.y * (1.0 - u.x) +
(d - b) * u.x * u.y;
}
float gnoise(vec3 p) {
vec3 i = floor(p);
vec3 f = fract(p);
vec3 u = quintic(f);
return -1.0 + 2.0 * mix( mix( mix( random(i + vec3(0.0,0.0,0.0)),
random(i + vec3(1.0,0.0,0.0)), u.x),
mix( random(i + vec3(0.0,1.0,0.0)),
random(i + vec3(1.0,1.0,0.0)), u.x), u.y),
mix( mix( random(i + vec3(0.0,0.0,1.0)),
random(i + vec3(1.0,0.0,1.0)), u.x),
mix( random(i + vec3(0.0,1.0,1.0)),
random(i + vec3(1.0,1.0,1.0)), u.x), u.y), u.z );
}
float gnoise(vec3 p, float tileLength) {
vec3 i = floor(p);
vec3 f = fract(p);
vec3 u = quintic(f);
return mix( mix( mix( dot( srandom3(i + vec3(0.0,0.0,0.0), tileLength), f - vec3(0.0,0.0,0.0)),
dot( srandom3(i + vec3(1.0,0.0,0.0), tileLength), f - vec3(1.0,0.0,0.0)), u.x),
mix( dot( srandom3(i + vec3(0.0,1.0,0.0), tileLength), f - vec3(0.0,1.0,0.0)),
dot( srandom3(i + vec3(1.0,1.0,0.0), tileLength), f - vec3(1.0,1.0,0.0)), u.x), u.y),
mix( mix( dot( srandom3(i + vec3(0.0,0.0,1.0), tileLength), f - vec3(0.0,0.0,1.0)),
dot( srandom3(i + vec3(1.0,0.0,1.0), tileLength), f - vec3(1.0,0.0,1.0)), u.x),
mix( dot( srandom3(i + vec3(0.0,1.0,1.0), tileLength), f - vec3(0.0,1.0,1.0)),
dot( srandom3(i + vec3(1.0,1.0,1.0), tileLength), f - vec3(1.0,1.0,1.0)), u.x), u.y), u.z );
}
vec3 gnoise3(vec3 x) {
return vec3(gnoise(x+vec3(123.456, 0.567, 0.37)),
gnoise(x+vec3(0.11, 47.43, 19.17)),
gnoise(x) );
}
#endif
/*
contributors: Patricio Gonzalez Vivo
description: Fractal Brownian Motion
use: fbm(<vec2> pos)
options:
FBM_OCTAVES: numbers of octaves. Default is 4.
FBM_NOISE_FNC(UV): noise function to use Default 'snoise(UV)' (simplex noise)
FBM_VALUE_INITIAL: initial value. Default is 0.
FBM_SCALE_SCALAR: scalar. Defualt is 2.
FBM_AMPLITUD_INITIAL: initial amplitud value. Default is 0.5
FBM_AMPLITUD_SCALAR: amplitud scalar. Default is 0.5
examples:
- /shaders/generative_fbm.frag
license:
- Copyright (c) 2021 Patricio Gonzalez Vivo under Prosperity License - https://prosperitylicense.com/versions/3.0.0
- Copyright (c) 2021 Patricio Gonzalez Vivo under Patron License - https://lygia.xyz/license
*/
#ifndef FBM_OCTAVES
#define FBM_OCTAVES 4
#endif
#ifndef FBM_NOISE_FNC
#define FBM_NOISE_FNC(UV) snoise(UV)
#endif
#ifndef FBM_NOISE2_FNC
#define FBM_NOISE2_FNC(UV) FBM_NOISE_FNC(UV)
#endif
#ifndef FBM_NOISE3_FNC
#define FBM_NOISE3_FNC(UV) FBM_NOISE_FNC(UV)
#endif
#ifndef FBM_NOISE_TILABLE_FNC
#define FBM_NOISE_TILABLE_FNC(UV, TILE) gnoise(UV, TILE)
#endif
#ifndef FBM_NOISE3_TILABLE_FNC
#define FBM_NOISE3_TILABLE_FNC(UV, TILE) FBM_NOISE_TILABLE_FNC(UV, TILE)
#endif
#ifndef FBM_NOISE_TYPE
#define FBM_NOISE_TYPE float
#endif
#ifndef FBM_VALUE_INITIAL
#define FBM_VALUE_INITIAL 0.0
#endif
#ifndef FBM_SCALE_SCALAR
#define FBM_SCALE_SCALAR 2.0
#endif
#ifndef FBM_AMPLITUD_INITIAL
#define FBM_AMPLITUD_INITIAL 0.5
#endif
#ifndef FBM_AMPLITUD_SCALAR
#define FBM_AMPLITUD_SCALAR 0.5
#endif
#ifndef FNC_FBM
#define FNC_FBM
FBM_NOISE_TYPE fbm(in vec2 st) {
// Initial values
FBM_NOISE_TYPE value = FBM_NOISE_TYPE(FBM_VALUE_INITIAL);
float amplitud = FBM_AMPLITUD_INITIAL;
// Loop of octaves
for (int i = 0; i < FBM_OCTAVES; i++) {
value += amplitud * FBM_NOISE2_FNC(st);
st *= FBM_SCALE_SCALAR;
amplitud *= FBM_AMPLITUD_SCALAR;
}
return value;
}
FBM_NOISE_TYPE fbm(in vec3 pos) {
// Initial values
FBM_NOISE_TYPE value = FBM_NOISE_TYPE(FBM_VALUE_INITIAL);
float amplitud = FBM_AMPLITUD_INITIAL;
// Loop of octaves
for (int i = 0; i < FBM_OCTAVES; i++) {
value += amplitud * FBM_NOISE3_FNC(pos);
pos *= FBM_SCALE_SCALAR;
amplitud *= FBM_AMPLITUD_SCALAR;
}
return value;
}
FBM_NOISE_TYPE fbm(vec3 p, float tileLength) {
const float persistence = 0.5;
const float lacunarity = 2.0;
float amplitude = 0.5;
FBM_NOISE_TYPE total = FBM_NOISE_TYPE(0.0);
float normalization = 0.0;
for (int i = 0; i < FBM_OCTAVES; ++i) {
float noiseValue = FBM_NOISE3_TILABLE_FNC(p, tileLength * lacunarity * 0.5) * 0.5 + 0.5;
total += noiseValue * amplitude;
normalization += amplitude;
amplitude *= persistence;
p = p * lacunarity;
}
return total / normalization;
}
#endif