The Code Therapy

Simplex Noise with RGB->HSV

This is a 3D simplex noise field. I map the float return to to the hue, brightness, and saturation. The hue is mapped directly, the saturation, and brightness are mapped using square and square root.

Created by justbobby on Fri, 03 Mar 2023 16:19:59 GMT.


#version 300 es
precision highp float;

uniform vec2 resolution;
uniform float time;

out vec4 fragColor;

const float amount = 1.0;
const float saturation = 0.8;
const vec2 vignetteSize = vec2(0.25, 0.25);
const float vignetteRoundness = 0.12;
const float vignetteMix = 1.0;
const float vignetteSmoothness = 0.42;
const float W = 1.2;
const float T = 7.5;

const float PI = acos(-1.0);
const float TAU = PI * 2.0;
const float SQRT3 = sqrt(3.0);
const float TAN30 = SQRT3 / 3.0;
const float HALFPI = PI / 2.0;

uniform float fft;
uniform float fftLow;

uniform float fftNormalized;
vec3 rand3(vec3 n) {
  return fract(sin(vec3(dot(n, vec3(12.9898, 78.233, 43.9821)), dot(n, vec3(21.5671, 51.6727, 63.7263)), dot(n, vec3(98.2345, 87.6543, 76.5432)))) * 43758.5453);
}
vec3 permute(vec3 x) { return mod(((x*34.0)+1.0)*x, 289.0); }

float snoise(vec2 v){
  const vec4 C = vec4(0.211324865405187, 0.366025403784439,
           -0.577350269189626, 0.024390243902439);
  vec2 i  = floor(v + dot(v, C.yy) );
  vec2 x0 = v -   i + dot(i, C.xx);
  vec2 i1;
  i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);
  vec4 x12 = x0.xyxy + C.xxzz;
  x12.xy -= i1;
  i = mod(i, 289.0);
  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 ;
  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;
  m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h );
  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 worleyNoise(vec3 p, float jitter) {
  vec3 pi = floor(p);
  vec3 pf = fract(p);
  float d = 1.0;
  for (int i = -1; i <= 1; i++) {
    for (int j = -1; j <= 1; j++) {
      for (int k = -1; k <= 1; k++) {
        vec3 g = vec3(float(i), float(j), float(k));
        vec3 o = rand3(pi + g);
        vec3 r = g + o - pf;
        d = min(d, dot(r, r));
      }
    }
  }
  return pow(d, 0.25);
}
vec3 hueRotate(vec3 c, float angle) {
  vec3 rot = vec3(TAN30, sin(vec2(radians(angle)) + vec2(0.0, HALFPI)));
  return mix(rot.xxx * dot(rot.xxx, c), c, rot.z) + (cross(rot.xxx, c) * rot.y);
}

vec4 permute(vec4 x){return mod(((x*34.0)+1.0)*x, 289.0);}
vec4 taylorInvSqrt(vec4 r){return 1.79284291400159 - 0.85373472095314 * r;}

float snoise(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 * C 
  vec3 x1 = x0 - i1 + 1.0 * C.xxx;
  vec3 x2 = x0 - i2 + 2.0 * C.xxx;
  vec3 x3 = x0 - 1. + 3.0 * C.xxx;

// Permutations
  i = mod(i, 289.0 ); 
  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
// ( N*N points uniformly over a square, mapped onto an octahedron.)
  float n_ = 1.0/7.0; // N=7
  vec3  ns = n_ * D.wyz - D.xzx;

  vec4 j = p - 49.0 * floor(p * ns.z *ns.z);  //  mod(p,N*N)

  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 = 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) ) );
}

vec3 hsvToRgb(vec3 hsv) {
  float h = hsv.x;
  float s = hsv.y;
  float v = hsv.z;
  
  float c = v * s;
  float hprime = mod(h / 60.0, 6.0);
  float x = c * (1.0 - abs(mod(hprime, 2.0) - 1.0));
  float m = v - c;
  
  vec3 rgb = vec3(0.0);
  if (0.0 <= hprime && hprime < 1.0) {
    rgb = vec3(c, x, 0.0);
  } else if (1.0 <= hprime && hprime < 2.0) {
    rgb = vec3(x, c, 0.0);
  } else if (2.0 <= hprime && hprime < 3.0) {
    rgb = vec3(0.0, c, x);
  } else if (3.0 <= hprime && hprime < 4.0) {
    rgb = vec3(0.0, x, c);
  } else if (4.0 <= hprime && hprime < 5.0) {
    rgb = vec3(x, 0.0, c);
  } else if (5.0 <= hprime && hprime < 6.0) {
    rgb = vec3(c, 0.0, x);
  }
  
  return rgb + vec3(m);
}

vec3 brightnessToHue(float brightness) {
  float hue = brightness * 360.0;
  return hsvToRgb(vec3(hue, 1.0, 1.0));
}

float filmicReinhardCurve(float x) {
  float q = (T * T + 1.0) * x * x;
  return q / (q + x + T * T);
}

vec3 filmicReinhard(vec3 c) {
  float w = filmicReinhardCurve(W);
  return vec3(
    filmicReinhardCurve(c.r),
    filmicReinhardCurve(c.g),
    filmicReinhardCurve(c.b)
  ) / w;
}

vec3 hsb2rgb( in vec3 c ){
    c.x = mod(c.x * 2.5, 1.0);
	c.y = mod(c.y *2.5,1.0);
  
    vec3 rgb = clamp(abs(mod(c.x*6.0+vec3(0.0,4.0,2.0),
                             6.0)-3.0)-1.0,
                     0.0,
                     1.0 );
    rgb = rgb*rgb*(3.0-2.0*rgb);
    return c.z * mix(vec3(1.0), rgb, c.y);
}



void main() {
  
  float bExp;
  
  
  vec2 uv = gl_FragCoord.xy / resolution.xy;
  float noiseFactor = snoise(vec3(uv.x/1.0,uv.y/1.0,time/10.0));
  if (fft == 0.0 ) {
    bExp = .4;
  } else {
    bExp = fft - pow(fftLow,1.0)+.2;
  }
  vec3 color = hsb2rgb(vec3(noiseFactor,mod(noiseFactor*10.0,30.0)/30.0,1.-pow(noiseFactor,bExp)));
  color.r = clamp(color.r,.5,1.0);
  vec3 reinhard = filmicReinhard(color);
  color = reinhard;
  // color = hueRotate(color,sin(time/10.0*3.14)*360.0);
  
  fragColor = vec4(color, 1.0);
}