Skip to content

Commit b1fa600

Browse files
committed
Integrate 3D noise after strands refactor
1 parent 7160ad9 commit b1fa600

File tree

3 files changed

+98
-80
lines changed

3 files changed

+98
-80
lines changed

src/strands/strands_api.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { StrandsConditional } from './strands_conditionals'
1515
import * as CFG from './ir_cfg'
1616
import * as FES from './strands_FES'
1717
import { getNodeDataFromID } from './ir_dag'
18-
import noiseGLSL from '../webgl/shaders/functions/noiseGLSL.glsl';
18+
import noiseGLSL from '../webgl/shaders/functions/noise3DGLSL.glsl';
1919

2020
//////////////////////////////////////////////
2121
// User nodes
@@ -125,15 +125,17 @@ export function initGlobalStrandsAPI(p5, fn, strandsContext) {
125125
strandsContext.fragmentDeclarations.add(noiseGLSL);
126126
// Handle noise(x, y) as noise(vec2)
127127
let nodeArgs;
128-
if (args.length === 2) {
129-
nodeArgs = [fn.vec2(args[0], args[1])];
128+
if (args.length === 3) {
129+
nodeArgs = [fn.vec3(args[0], args[1], args[2])];
130+
} else if (args.length === 2) {
131+
nodeArgs = [fn.vec3(args[0], args[1], 0)];
130132
} else {
131133
nodeArgs = args;
132134
}
133135

134136
const { id, dimension } = build.functionCallNode(strandsContext, 'noise', nodeArgs, {
135137
overloads: [{
136-
params: [DataType.float2],
138+
params: [DataType.float3],
137139
returnType: DataType.float1,
138140
}]
139141
});
Lines changed: 92 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,108 @@
1-
// Based on https://thebookofshaders.com/13/ and https://github.com/patriciogonzalezvivo/lygia
1+
// Based on https://github.com/stegu/webgl-noise/blob/22434e04d7753f7e949e8d724ab3da2864c17a0f/src/noise3D.glsl
22
// MIT licensed, adapted for p5.strands
33

4-
vec3 random3(vec3 p) {
5-
return fract(sin(vec3(
6-
dot(p, vec3(127.1, 311.7, 74.7)),
7-
dot(p, vec3(269.5, 183.3, 246.1)),
8-
dot(p, vec3(113.5, 271.9, 124.6))
9-
)) * 43758.5453123);
4+
vec3 mod289(vec3 x) {
5+
return x - floor(x * (1.0 / 289.0)) * 289.0;
106
}
117

12-
float baseNoise(vec3 p) {
13-
vec3 i = floor(p);
14-
vec3 f = fract(p);
15-
16-
// Compute corner vectors
17-
vec3 a = random3(i);
18-
vec3 b = random3(i + vec3(1, 0, 0));
19-
vec3 c = random3(i + vec3(0, 1, 0));
20-
vec3 d = random3(i + vec3(1, 1, 0));
21-
vec3 e = random3(i + vec3(0, 0, 1));
22-
vec3 f1 = random3(i + vec3(1, 0, 1));
23-
vec3 g = random3(i + vec3(0, 1, 1));
24-
vec3 h = random3(i + vec3(1, 1, 1));
25-
26-
vec3 u = f * f * (3.0 - 2.0 * f);
27-
28-
return mix(
29-
mix(
30-
mix(dot(a, f - vec3(0, 0, 0)), dot(b, f - vec3(1, 0, 0)), u.x),
31-
mix(dot(c, f - vec3(0, 1, 0)), dot(d, f - vec3(1, 1, 0)), u.x), u.y
32-
),
33-
mix(
34-
mix(dot(e, f - vec3(0, 0, 1)), dot(f1, f - vec3(1, 0, 1)), u.x),
35-
mix(dot(g, f - vec3(0, 1, 1)), dot(h, f - vec3(1, 1, 1)), u.x), u.y
36-
),
37-
u.z
38-
);
8+
vec4 mod289(vec4 x) {
9+
return x - floor(x * (1.0 / 289.0)) * 289.0;
3910
}
4011

41-
float noise(vec3 p) {
12+
vec4 permute(vec4 x) {
13+
return mod289(((x*34.0)+10.0)*x);
14+
}
15+
16+
vec4 taylorInvSqrt(vec4 r)
17+
{
18+
return 1.79284291400159 - 0.85373472095314 * r;
19+
}
20+
21+
float baseNoise(vec3 v)
22+
{
23+
const vec2 C = vec2(1.0/6.0, 1.0/3.0) ;
24+
const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);
25+
26+
// First corner
27+
vec3 i = floor(v + dot(v, C.yyy) );
28+
vec3 x0 = v - i + dot(i, C.xxx) ;
29+
30+
// Other corners
31+
vec3 g = step(x0.yzx, x0.xyz);
32+
vec3 l = 1.0 - g;
33+
vec3 i1 = min( g.xyz, l.zxy );
34+
vec3 i2 = max( g.xyz, l.zxy );
35+
36+
// x0 = x0 - 0.0 + 0.0 * C.xxx;
37+
// x1 = x0 - i1 + 1.0 * C.xxx;
38+
// x2 = x0 - i2 + 2.0 * C.xxx;
39+
// x3 = x0 - 1.0 + 3.0 * C.xxx;
40+
vec3 x1 = x0 - i1 + C.xxx;
41+
vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y
42+
vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y
43+
44+
// Permutations
45+
i = mod289(i);
46+
vec4 p = permute( permute( permute(
47+
i.z + vec4(0.0, i1.z, i2.z, 1.0 ))
48+
+ i.y + vec4(0.0, i1.y, i2.y, 1.0 ))
49+
+ i.x + vec4(0.0, i1.x, i2.x, 1.0 ));
50+
51+
// Gradients: 7x7 points over a square, mapped onto an octahedron.
52+
// The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)
53+
float n_ = 0.142857142857; // 1.0/7.0
54+
vec3 ns = n_ * D.wyz - D.xzx;
55+
56+
vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7)
57+
58+
vec4 x_ = floor(j * ns.z);
59+
vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N)
60+
61+
vec4 x = x_ *ns.x + ns.yyyy;
62+
vec4 y = y_ *ns.x + ns.yyyy;
63+
vec4 h = 1.0 - abs(x) - abs(y);
64+
65+
vec4 b0 = vec4( x.xy, y.xy );
66+
vec4 b1 = vec4( x.zw, y.zw );
67+
68+
//vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0;
69+
//vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0;
70+
vec4 s0 = floor(b0)*2.0 + 1.0;
71+
vec4 s1 = floor(b1)*2.0 + 1.0;
72+
vec4 sh = -step(h, vec4(0.0));
73+
74+
vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ;
75+
vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ;
76+
77+
vec3 p0 = vec3(a0.xy,h.x);
78+
vec3 p1 = vec3(a0.zw,h.y);
79+
vec3 p2 = vec3(a1.xy,h.z);
80+
vec3 p3 = vec3(a1.zw,h.w);
81+
82+
//Normalise gradients
83+
vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));
84+
p0 *= norm.x;
85+
p1 *= norm.y;
86+
p2 *= norm.z;
87+
p3 *= norm.w;
88+
89+
// Mix final noise value
90+
vec4 m = max(0.5 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);
91+
m = m * m;
92+
return 105.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1),
93+
dot(p2,x2), dot(p3,x3) ) );
94+
}
95+
96+
float noise(vec3 st) {
4297
float result = 0.0;
4398
float amplitude = 1.0;
4499
float frequency = 1.0;
45100

46101
for (int i = 0; i < 4; i++) {
47-
result += amplitude * baseNoise(p * frequency);
102+
result += amplitude * baseNoise(st * frequency);
48103
frequency *= 2.0;
49104
amplitude *= 0.5;
50105
}
106+
51107
return result;
52108
}

src/webgl/shaders/functions/noiseGLSL.glsl

Lines changed: 0 additions & 40 deletions
This file was deleted.

0 commit comments

Comments
 (0)