const fragmentShader = `
precision highp float;
uniform vec3 color1;
uniform vec3 color2;
uniform vec3 color3;
uniform vec3 color4;
uniform float colorSize;
uniform float colorSpacing;
uniform float colorRotation;
uniform float colorSpread;
uniform float displacement;
uniform float zoom;
uniform float spacing;
uniform float seed;
uniform vec2 viewportSize;
uniform vec2 colorOffset;
uniform vec2 transformPosition;
uniform float noiseSize;
uniform float noiseIntensity;
in vec2 vPosition;
vec3 gradientDerivativesNoise3DHash(vec3 p)
{
//p = 50.0 * fract(p * 0.3183099 + vec2(0.71, 0.113));
//return -1.0 + 2.0 * fract(p.x * p.y * (p.x + p.y));
p = fract(p * vec3(.1031, .1030, .0973));
p += dot(p, p.yxz + 33.33);
return fract((p.xxy + p.yxx) * p.zyx);
}
#Reverse engineering a shader from a site
5 messages · Page 1 of 1 (latest)
// return value noise (in x) and its derivatives (in yzw)
vec4 gradientDerivativesNoise3D(in vec3 x)
{
// grid
vec3 p = floor(x);
vec3 w = fract(x);
#if 1
// quintic interpolant
vec3 u = w * w * w * (w * (w * 6.0 - 15.0) + 10.0);
vec3 du = 30.0 * w * w * (w * (w - 2.0) + 1.0);
#else
// cubic interpolant
vec3 u = w * w * (3.0 - 2.0 * w);
vec3 du = 6.0 * w * (1.0 - w);
#endif
// gradients
vec3 ga = gradientDerivativesNoise3DHash(p + vec3(0.0, 0.0, 0.0));
vec3 gb = gradientDerivativesNoise3DHash(p + vec3(1.0, 0.0, 0.0));
vec3 gc = gradientDerivativesNoise3DHash(p + vec3(0.0, 1.0, 0.0));
vec3 gd = gradientDerivativesNoise3DHash(p + vec3(1.0, 1.0, 0.0));
vec3 ge = gradientDerivativesNoise3DHash(p + vec3(0.0, 0.0, 1.0));
vec3 gf = gradientDerivativesNoise3DHash(p + vec3(1.0, 0.0, 1.0));
vec3 gg = gradientDerivativesNoise3DHash(p + vec3(0.0, 1.0, 1.0));
vec3 gh = gradientDerivativesNoise3DHash(p + vec3(1.0, 1.0, 1.0));
// projections
float va = dot(ga, w - vec3(0.0, 0.0, 0.0));
float vb = dot(gb, w - vec3(1.0, 0.0, 0.0));
float vc = dot(gc, w - vec3(0.0, 1.0, 0.0));
float vd = dot(gd, w - vec3(1.0, 1.0, 0.0));
float ve = dot(ge, w - vec3(0.0, 0.0, 1.0));
float vf = dot(gf, w - vec3(1.0, 0.0, 1.0));
float vg = dot(gg, w - vec3(0.0, 1.0, 1.0));
float vh = dot(gh, w - vec3(1.0, 1.0, 1.0));
// interpolations
return vec4(va + u.x * (vb - va) + u.y * (vc - va) + u.z * (ve - va) + u.x * u.y * (va - vb - vc + vd) + u.y * u.z * (va - vc - ve + vg) + u.z * u.x * (va - vb - ve + vf) + (-va + vb + vc - vd + ve - vf - vg + vh) * u.x * u.y * u.z, // value
ga + u.x * (gb - ga) + u.y * (gc - ga) + u.z * (ge - ga) + u.x * u.y * (ga - gb - gc + gd) + u.y * u.z * (ga - gc - ge + gg) + u.z * u.x * (ga - gb - ge + gf) + (-ga + gb + gc - gd + ge - gf - gg + gh) * u.x * u.y * u.z + // derivatives
du * (vec3(vb, vc, ve) - va + u.yzx * vec3(va - vb - vc + vd, va - vc - ve + vg, va - vb - ve + vf) + u.zxy * vec3(va - vb - ve + vf, va - vb - vc + vd, va - vc - ve + vg) + u.yzx * u.zxy * (-va + vb + vc - vd + ve - vf - vg + vh)));
}
float hash(vec2 p) {
p = 50.0 * fract(p * 0.3183099 + vec2(0.71, 0.113));
return -1.0 + 2.0 * fract(p.x * p.y * (p.x + p.y));
}
float computeNoise(in vec2 p) {
vec2 i = floor(p);
vec2 f = fract(p);
vec2 u = f * f * (3.0 - 2.0 * f);
return mix(mix(hash(i + vec2(0.0, 0.0)),
hash(i + vec2(1.0, 0.0)), u.x),
mix(hash(i + vec2(0.0, 1.0)),
hash(i + vec2(1.0, 1.0)), u.x), u.y);
}
vec2 rotate(vec2 v, float a) {
float s = sin(a);
float c = cos(a);
mat2 m = mat2(c, -s, s, c);
return m * v;
}
void main() {
vec2 position = vPosition;
position.x *= min(1.0, viewportSize.x / viewportSize.y);
position.y *= min(1.0, viewportSize.y / viewportSize.x);
position /= zoom;
position += transformPosition;
vec2 noiseLocalPosition = position * 0.5 + 0.5;
vec3 displacementNoise = gradientDerivativesNoise3D(vec3(noiseLocalPosition, seed)).xyz;
float noise = computeNoise(vPosition * viewportSize / noiseSize);
position += displacementNoise.xz * displacement;
vec2 offsetedPosition = position;
offsetedPosition -= colorOffset;
offsetedPosition = mod(offsetedPosition - spacing, vec2(spacing * 2.0)) - spacing;
offsetedPosition = rotate(offsetedPosition, -colorRotation);
offsetedPosition /= vec2(colorSize, colorSize);
offsetedPosition *= vec2(1.0 / colorSpread, 1.0);
vec3 color = vec3(0.0);
color = mix(color1, color, smoothstep(0.0, 1.0, distance(offsetedPosition, vec2(0.0, colorSpacing * 1.5))));
color = mix(color2, color, smoothstep(0.0, 1.0, distance(offsetedPosition, vec2(0.0, colorSpacing * 0.5))));
color = mix(color3, color, smoothstep(0.0, 1.0, distance(offsetedPosition, vec2(0.0, -colorSpacing * 0.5))));
color = mix(color4, color, smoothstep(0.0, 1.0, distance(offsetedPosition, vec2(0.0, -colorSpacing * 1.5))));
color += noise * noiseIntensity;
color = clamp(color, 0.0, 1.0);
gl_FragColor = vec4(color, 1.0);
//gl_FragColor = vec4(0.6, 0.5, 0.5, 1.0);
}
If I output the uncommented //gl_FragColor = vec4(0.6, 0.5, 0.5, 1.0) , it displays a flat colour just fine
The uniforms I'm using for the fragmentShader are as follows:
this.gradientEffect = {
uniforms: {
"color1": { value: new THREE.Vector3(0.604,0.302,0.2) },
"color2": { value: new THREE.Vector3(0.996,0.663,0.) },
"color3": { value: new THREE.Vector3(0.996,0.663,0.) },
"color4": { value: new THREE.Vector3(0.608,0.788,0.608) },
"colorSize": { value: 0.0 },
"colorSpread": { value: 4.52},
"colorSpacing": { value: 0.52 },
"colorRotation": { value: -0.381592653589793 },
"colorOffset": { value: new THREE.Vector2(-0.7741174697875977,-0.20644775390624992) },
"displacement": { value: 0.1 },
"seed": { value: -0.9 },
"position": { value: new THREE.Vector2(-0.2816110610961914,-0.43914794921875) },
"zoom": { value: 0.72 },
"spacing": { value: 4.27 },
"noiseIntensity": {value: .04 },
"noiseSize": {value: .5 },
"viewportSize": {value: new THREE.Vector2(window.innerWidth, window.innerHeight)},
"transformPosition": {value: new THREE.Vector2(0.125, 0.059)}
},
vertexShader: vertexShader,
fragmentShader: fragmentShader
}
Some of these values are retrieved from the site itself: https://monopo.london/ , I've just hardcoded them there, although I'm not sure what transformPosition does yet exactly
If you check the element inspector the values are shown there