I used the sample 2d noise from the book of shaders to mix into my existing shader, and applied sin and cos functions to add movement to its position. As for scaling the canvas, I kept it low at 4 times. Combined with the existing time dependent shaping functions I had used previously, they formed soft organic looking shapes that slowly evolved and morphed and moved. Together with the back and forth motion, I think it really captures the feeling of a living organism – almost as if it’s breathing. You can view a live example here ```#ifdef GL_ES
precision mediump float;
#endif

#define PI 3.14159265359
#define TWO_PI 6.28318530718
uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;

// random and noise code from https://thebookofshaders.com/11/
float random(vec2 co){
return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
}

float noise (in vec2 st) {
vec2 i = floor(st);
vec2 f = fract(st);

// Four corners in 2D of a tile
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));

// Smooth Interpolation

// Cubic Hermine Curve.  Same as SmoothStep()
vec2 u = f*f*(3.0-2.0*f);
// u = smoothstep(0.,1.,f);

// Mix 4 coorners percentages
return mix(a, b, u.x) +
(c - a)* u.y * (1.0 - u.x) +
(d - b) * u.x * u.y;
}

float plot(vec2 st, float pct){
return  smoothstep( pct-0.1, pct, st.y) -
smoothstep( pct, pct+0.5, st.y);
}

//  Function from Iñigo Quiles
vec3 hsb2rgb( in vec3 c ){
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);
}

vec3 rgb2hsb( in vec3 c ){
vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
vec4 p = mix(vec4(c.bg, K.wz),
vec4(c.gb, K.xy),
step(c.b, c.g));
vec4 q = mix(vec4(p.xyw, c.r),
vec4(c.r, p.yzx),
step(p.x, c.r));
float d = q.x - min(q.w, q.y);
float e = 1.0e-10;
return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)),
d / (q.x + e),
q.x);
}

void main() {
vec2 st = gl_FragCoord.xy/u_resolution;

// time dependent shaping equations
float y = sin(PI*st.x+u_time/40.)/0.8 + cos(PI*st.y+ u_time/40.)/2.;
float yz = sin(PI*st.x+u_time/30.)/1. + cos(PI*st.y+ u_time/10.)/0.8;

// various colours to mix
vec3 color = vec3(y);
vec3 colorA = vec3(0.545,0.169,0.000);
vec3 colorB = vec3(0.565,0.435,0.121);
vec3 colorC = vec3(0.126,0.490,0.171);
vec3 colorD = vec3(0.362,0.237,0.820);
float pct = plot(st,y);

// Use polar coordinates instead of cartesian
vec2 toCenter = vec2(0.5)-st;
float angle = atan(toCenter.y,toCenter.x);
// circle equation
float z = radius * 10.*sin(u_time/2.+ atan(st.y, st.x));

// scale the canvas for noise
vec2 pos = vec2(st*4.);

// move the noise values back and forth
float n = noise(pos + sin(u_time) + cos(u_time));

// now mix it all
color = mix(colorA, colorB, y);
color = mix(color, colorC, n);
color = mix(color, colorD, yz);
vec3 hsbtemp = rgb2hsb(color);
color = hsb2rgb(vec3(hsbtemp, hsbtemp*0.5, hsbtemp*0.5));

gl_FragColor = vec4(color,1.0);
}
```

I’ve been trying to get a sense of how scaling the canvas changes the overall noise effect. As the canvas is scaled larger, many familiar noise textures seem to emerge (pixelation, white noise, stripes like on a tuning VHS). I think it’s interesting that artificially adding noise in these ways provides windows into understanding noise found in the imperfect conversions between mediums (ex analog to digital).  ## Week 2 HW

My favourite shader made this week was this neat ripple effect created using techniques learned in the patterns video, shaping functions video, as well as my own explorations into the sin function. I first began by modifying the code from the grid example, and created a series of if else statements targeting each column individually.

In each of these conditions, I drew circles with the size being based off a sin function using u_time, which created an effect where the circle grew and shrunk over time.

I modified the speed of the effect by multiplying  u_time, effectively changing the period of the function, which resulted in a shorter cycle and animation. This can be seen below in my experiments in graphtoy, the orange wave is sin(x) while the shorter yellow wave is sin(x*2). In order to offset the animation of each circle to create the ripple effect, I added a varying horizontal shift to each function, so that the cycles would occur quickly in succession. Once again, this was verified using graphtoy.

Overall, making this shader refreshed a lot of what I learned about sin functions and their modifiers, and it was especially interesting using sin functions with u_time to create an animated shader.

```#ifdef GL_ES
precision mediump float;
#endif

uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;

vec2 createGrid( in vec2 st, in vec2 grid, out vec2 indices ){

// multiply by the number of cells
// [0,1] range => [0,10] (for example)
st *= grid;

// get the cell indices
// for example, in a grid of 10x10:
// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
indices = floor(st);

// use fract to get the fractional amount of st
// 9.5 => 0.5
// shows the xy coordinate in each cell
st = fract(st);

return st;
}

float drawCircle (vec2 st, vec2 pos, float size){
float result = distance (st, pos);
result=1.-step(size,result);

return result;
}

void main() {

vec2 st = gl_FragCoord.xy/u_resolution.xy;
st.x *= u_resolution.x/u_resolution.y;

// good practice to take a copy of the original st
// before you change it
vec2 st0 = st;

vec2 indices;

// This divides the result of the sin function, changing the final size of the circle
float size = 4.;

// This changes the period of the sin function, changing the speed at which the circles animate
float speed = 5.;

// Create grid for circles
st = createGrid( st, vec2(5., 5.), indices);

// Set bg colour
vec3 color = vec3(0.995,0.764,0.451);
// Change the colour and sin function of each column
if(indices.x == 0.){
float r = drawCircle(st, vec2(0.5), sin(u_time*speed)/size);
color = mix( color, vec3(0.683,0.289,1.000), r);
}else if(indices.x == 1.){
float r = drawCircle(st, vec2(0.5), sin(u_time*speed+1.)/size);
color = mix( color, vec3(1.000,0.243,0.831), r);
}
else if(indices.x == 2.){
float r = drawCircle(st, vec2(0.5), sin(u_time*speed+2.)/size);
color = mix( color, vec3(1.000,0.118,0.380), r);
}
else if(indices.x == 3.){
float r = drawCircle(st, vec2(0.5), sin(u_time*speed+3.)/size);
color = mix( color, vec3(1.000,0.188,0.236), r);
}
else if(indices.x == 4.){
float r = drawCircle(st, vec2(0.5), sin(u_time*speed+4.)/size);
color = mix( color, vec3(1.000,0.237,0.122), r);
}

gl_FragColor = vec4(color,1.0);
}

```

## Week 1 HW

For week 1’s homework, I experimented with shaping functions as well as u_time to create a neat moving gradient effect. I was pretty interested in using the sin function in conjunction with u_time to create a repeating pattern of colours. I first began by generating a moving pattern using the sin function, and editing the numbers to see what effects I could achieve.

After some experimentation, I took the shader one step further by not only changing the G value over time with sin, but also the B value. This created 2 patterns that moved out of sync with each other. Funnily enough this reminded me of looking out the window of a train, and seeing how scenery closer to you would speed by faster than scenery farther away.

```
#ifdef GL_ES
precision mediump float;
#endif

uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;

#define TWO_PI 6.283185307

void main() {
vec2 st = gl_FragCoord.xy/u_resolution.xy;
st.x *= u_resolution.x/u_resolution.y;

float amt = st.x;
float amt2 = st.x;

amt = sin( u_time * 2. + st.x * TWO_PI * 1.7 ) * 0.5 + 0.620;
amt2 = sin( u_time * 15. + st.x * TWO_PI * 1.5 ) * 0.700 + 0.6;

// combine amt together
vec3 color = vec3( 0.9, amt, amt2);

gl_FragColor = vec4(color,1.0);
}

```

For this excersize I took my grid from last week and implemented the noise effect. I also added a distorted circle to the grid that warps and moves. I thought the grid effect  looked interesting with its psychedelic colour scheme. ```
// Author: Emily Flood
// Title: Noise grid
/* Code used from "Patterns" from The Book of Shaders
> @patriciogv ( patriciogonzalezvivo.com ) - 2015
*/

#ifdef GL_ES
precision mediump float;
#endif

uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;

#define PI 3.14159265358979323846

//function to tile the image
vec2 tile(vec2 _st, float _zoom){
_st *= _zoom;
return fract(_st);
}

//function to draw a rectangle
float drawRect(vec2 st, vec2 pos, vec2 size){
float result = 1.0;

vec2 border = (1.0-size)/2.;

st = st - pos + vec2(0.5);

result = step(border.x,st.x);
result *= step(border.x,1.0-st.x);
result *= step(border.y,st.y);
result *= step(border.y,1.-st.y);

return result;
}

//function to draw a circle
float drawCircle(vec2 st, vec2 pos, float size){

float result = distance(st,pos);
result = 1.0-step(size,result);
return result;
}

float drawRectangle(vec2 st, vec2 pos, vec2 size){
float result = 1.0;

vec2 border = (1.0-size)/2.;

st = st - pos +vec2(0.5);

result = step( border.x, st.x);
result *= step( border.x, 1.-st.x);
result *= step( border.y, st.y);
result *= step( border.y, 1.-st.y);

return result;
}

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 il;
il = (x0.x > x0.y) ? vec2(1.0,0.0) : vec2(0.0, 1.0);
vec4 x12 = x0.xyxy + C.xxzz;
x12.xy -= il;
i = mod(i, 289.0);
vec3 p = permute( permute(i.y + vec3(0.0, il.y, 1.0))
+ i.x + vec3(0.0, il.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 random (vec2 st){
return fract(sin(dot(st.xy, vec2(12.9898,78.233)))*43758.5453123);
}

float map (float value, float min1, float max1, float min2, float max2){

return min2 + (value - min1) * (max2 - min2) / (max1 - min1);
}

void main() {
vec2 st = gl_FragCoord.xy/u_resolution.xy;
vec3 color = vec3(0.);

//tiling the image and animating it
st *= 5.;
st = mod(st,1.3);
st = tile(st,0.952);
st.x += sin(st.y *2. + u_time) * 0.1;
st.y -= cos(st.x *2. + u_time) * 0.1;
float size = 0.416;

//drawing out the rectangle and circle
float r1 = drawRect(st, vec2(0.5), vec2(0.5));

float c1 = drawCircle(st, vec2(0.5), size);

color = vec3(st,0.048);

//applying colour
color.r = snoise( st * 3. + vec2(100., -u_time*0.5)) * 0.5 + 0.5;
color.g = snoise( st * 3. + vec2(200., -u_time*0.4)) * 0.5 + 0.5;
color.b = snoise( st * 3. + vec2(300., -u_time*0.4)) * 0.5 + 0.5;

color.r = snoise( st * 2. + vec2(400., u_time)) * 0.5 + 0.5;
color.g = snoise( st * 2. + vec2(500., u_time)) * 0.5 + 0.5;
color.b = snoise( st * 2. + vec2(600., u_time)) * 0.5 + 0.5;

vec2 index = floor( st);

float cs = (snoise(st + vec2(0, u_time*0.2))*0.5 + 0.5) * 0.3 + 0.1;

float circ = drawCircle( st, vec2(0.5), cs);

vec3 circColor;
circColor.r = random( index + vec2(10.));
circColor.g = random( index + vec2(20.));
circColor.b = random( index + vec2(30.));

color = mix ( color, circColor, circ);

float cs2 = (snoise(st + vec2(0, u_time*0.2))*0.5 + 0.5) * 0.3 + 0.1;

float circ2 = drawCircle( st, vec2(0.5), cs2);

vec3 circColor2;
circColor2.r = random( index + vec2(10.));
circColor2.g = random( index + vec2(20.));
circColor2.b = random( index + vec2(30.));

color = mix ( color, circColor, circ);

float rectSize = random(index);

gl_FragColor = vec4(color,1.0);
}

```

My shader was pretty simple – I focused on playing with noise in both shape and colour. I really liked the bit of the demo where we applied the noise to the size of the circle, therefore creating a  blob, so I wanted to do that. I also used noise to warp my canvas and tiles for my pattern, which I thought created an interesting effect. I was going for an ‘oil’ spill aesthetic, where elements would move independently to create one cohesive image, but could still be seen in the result.  ```
// Author:
// Title:

#ifdef GL_ES
precision mediump float;
#endif

uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;

vec2 createGrid(in vec2 st, in vec2 grid, out vec2 indices){
st *= grid;
indices = floor(st);
st = fract(st);

return st;
}
float drawCircle(vec2 st, vec2 pos, float size){
float result = 1.0;
result = distance(st, pos);
result = 1.0- step(size, result);

return result;
}
float drawRectangle(vec2 st, vec2 pos, vec2 size ){

float result = 1.0;
vec2 border = (1.0-size)/2.0;
st = st - pos + vec2(0.5);

result = step(border.x, st.x);
result *= step(border.x, 1.0-st.x);
result *= step(border.y, st.y);
result *= step(border.y, 1.0-st.y);

return result;
}
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);
}
vec3 noiseGradient( vec2 st, float offset, vec2 frequency, float t){

// like random(), simplex noise takes a vec2 argument and returns a float
// because it is deterministic, we need to offset to get different
// values for r, g & b
// we add an additional offset in case we want to call the function mutliple times
// so we continue to generate unique numbers
// isn't modularity great?
// also, we add time to 'animate' the noise

vec3 color;
color.r = snoise( st * frequency + vec2(offset, t)) * 0.5 + 0.5;
color.g = snoise( st * frequency + vec2(200.+offset, t)) * 0.5 + 0.5;
color.b = snoise( st * frequency + vec2(300.+offset, t)) * 0.5 + 0.5;

return color;
}
float map(float value, float min1, float max1, float min2, float max2) {
return min2 + (value - min1) * (max2 - min2) / (max1 - min1);
}

void main() {
vec2 st = gl_FragCoord.xy/u_resolution.xy;
st.x *= u_resolution.x/u_resolution.y;

vec2 indices = floor(st);
float cs = (snoise(st*4. + vec2(u_time*0.01) )*0.540+0.868)*0.744+sin(u_time)*0.3;
st = createGrid(st, vec2(cs*20.), indices);
vec3 bgColor = noiseGradient(st, -0.280, vec2(0.540,0.780), u_time * 0.2);

vec3 color = bgColor;
//color.r = mod(indices.x, 2.);
//color.rgb += mod(indices.y, 2.);

if (mod(indices.x, 2.) == 0. && mod(indices.y, 2.) == 0.){
//lowerleft
float cs = (snoise(st + vec2(u_time*0.01) )*0.5+0.5)*0.744+0.1;
//color = vec3(1.000,0.786,0.038);
float c = drawCircle(st, vec2(cs*5., cs*10.), cs);
color = mix(color, vec3(0.870,0.201,0.076), c);
float c2 = drawCircle(st, vec2(0.5)*cos(u_time)+0.5, cs);
color = mix(color, vec3(0.040,0.342,0.870), c2);
}
else if (mod(indices.x, 2.) == 0.)
{
//color = vec3(1.000,0.786,0.038);
float cs = (snoise(st + vec2(u_time*0.01) )*0.492+0.5)*0.4+0.1;
float c = drawCircle(st, vec2(1)*fract(u_time)*2., cs);
color = mix(color, vec3(0.087,0.711,0.870), c);
float c2 = drawCircle(st, vec2(0.5)*sin(u_time)+0.5, cs);
color = mix(color, vec3(0.130,0.579,0.870), c2);

}
else if (mod(indices.x, 2.) != 0. && mod(indices.y, 2.) == 0.)
{
//upper left
// color = vec3(1.000,0.786,0.038);

float cs = (snoise(st + vec2(u_time*0.01) )*0.5+0.5)*0.4+0.1;
float c = drawCircle(st, vec2(1)*fract(u_time)*2., cs);
color = mix(color, vec3(0.087,0.711,0.870), c);
float c2 = drawCircle(st, vec2(0.5)*sin(u_time)+0.5, cs);
color = mix(color, vec3(0.018,0.160,0.870), c2);
}
else
{
// color = vec3(1.000,0.786,0.038);
float cs = (snoise(st + vec2(u_time*0.01) )*0.5+0.5)*0.4+0.1;

float c = drawCircle(st, vec2(1)*fract(u_time+0.5)*0.3, cs);

color = mix(color, vec3(0.087,0.711,0.870), c);
float c2 = drawCircle(st, vec2(0.5)*cos(u_time)+0.5, cs);
color = mix(color, vec3(0.111,0.534,0.870), c2);

//upper right
//color = vec3(0.675,0.664,0.411);
}
gl_FragColor = vec4(color,1.0);
}

``` I built this shader by adding on to the circle shapes I produced for week 2. It is hard to photograph because it animates with time (image is of one of it’s less flattering frames). The main changes were changing the colors of the circles to a gradient shared across all of them rather than coloring each independently, and incorporating the shifting noise into the code, as it can’t be added to vec3 shapes and colors using the mix() function.

```
// Author: Dawn Murphy

#ifdef GL_ES
precision mediump float;
#endif

uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;

//generate 2D random
float random (in vec2 st) {
return fract(sin(dot(st.xy,
vec2(12.9898,78.233)))
* abs(sin(u_time)));
}

// 2D Noise based on Morgan McGuire @morgan3d
float noise (in vec2 st) {
vec2 i = floor(st);
vec2 f = fract(st);

// Four corners in 2D of a tile
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));

// Smooth Interpolation

// Cubic Hermine Curve. Same as SmoothStep()
vec2 u = f*f*(3.0-2.0*f);
// u = smoothstep(0.,1.,f);

// Mix 4 coorners percentages
return mix(a, b, u.x) +
(c - a)* u.y * (1.0 - u.x) +
(d - b) * u.x * u.y;
}

//Generate circles
//define first circle
float circleF(in vec2 _st, in float _radius){
vec2 dist = _st-vec2(0.8);
dot(dist,dist)*10.0);
}

//define second circle
float circleS(in vec2 _st, in float _radius){
vec2 dist = _st-vec2(0.5);
dot(dist,dist)*10.0);
}

//define third circle
float circleT(in vec2 _st, in float _radius){
vec2 dist = _st-vec2(0.2);
dot(dist,dist)*10.0);
}

//define fourth circle
float circleFo(in vec2 _st, in float _radius){
vec2 dist = _st-vec2(0.2,0.8);
dot(dist,dist)*10.0);
}

//define fifth circle
float circleFi(in vec2 _st, in float _radius){
vec2 dist = _st-vec2(0.80,0.200);
dot(dist,dist)*10.0);
}

void main() {
vec2 st = gl_FragCoord.xy/u_resolution.xy;
vec3 color = vec3(0.0);
vec2 pos = vec2(st*(u_resolution/10.0));
vec3 pct = vec3(st.x);

// Use the noise function
float n = noise(pos);

vec3 pink = vec3(0.995,0.370,0.604);
vec3 blue = vec3(0.091,0.399,1.000);
vec3 gradcolor = mix(pink, blue, st.y);

//visualize the circles
vec3 colorF = vec3(circleF(st,0.9));
vec3 colorS = vec3(circleS(st,0.9));
colorS -= gradcolor; //turns the first circle pink by subtracting all the green
vec3 colorT = vec3(circleT(st,0.9));
vec3 colorFo = vec3(circleFo(st,0.9));
vec3 colorFi = vec3(circleFi(st,0.9));

//combine time

gl_FragColor = vec4( color, n); //draws
}

```  Iterating on this shader several times, it seemed fit to share the source of iteration. This is a grid set to be zoomed on this position, with alternating animations for red, blue and green using ‘u_time’ and and then altering the canvas with noise.

The code combine several functions and experimentation from other classes and shader sessions. I found this form of shaders fun and intriguing, it has brought together some of the learning.

```
// Author:joshua linton
// Title: wallway_02

#ifdef GL_ES
precision mediump float;
#endif

uniform vec2 u_resolution;
uniform float u_time;

float drawRectangle(vec2 st, vec2 size) {

float result = 1.0;

vec2 border = (1.0-size)/2.;

result = step( border.x, st.x);
result *= step( border.x, 1.0-st.x);
result *= step( border.y, st.y);
result *= step( border.y, 1.0-st.y);

return result;
}
//from Week 3 Shader Session Noise
//
vec3 permute(vec3 x) { return mod(((x*34.0)+1.0)*x, 289.0); }
float snoise(vec2 v){
const vec4 C = vec4(0.2113224865405187, 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.y * x12.xz + h.yz * x12.yw;
return 130.0 * dot(m, g);
}

vec2 createGrid( in vec2 st, in vec2 grid, out vec2 indices) {

st *= grid;
indices = floor(st);
st = fract(st);

return st;
}

float drawRectangle(vec2 st, vec2 pos, vec2 size) {

float result = 1.0;
vec2 border = (1.0-size)/2.;

st = st - pos + vec2(0.5);

result = step( border.x, st.x);
result *= step( border.x, 1.0-st.x);
result *= step( border.y, st.y);
result *= step( border.y, 1.0-st.y);

return result;
}

void main() {

vec2 st = gl_FragCoord.xy/u_resolution.xy;
st.x *= u_resolution.x/u_resolution.y;

vec3 color = vec3(u_time);

st *= 0.19;

vec2 indices;

st = createGrid( st, vec2 (20., 8.), indices);

//st.y += cos( st.x + u_time / cos(-st.y * 2.4) /1280.0) /.24;
st.x += snoise(st + vec2(0, u_time*0.04))*5.;
st.y += snoise(st + vec2(0, u_time*.64))*0.00002;
//st.x += cos( st.y + u_time * sin(st.x)) /5.;

//from Week 2 Shader Session Patterns
if( mod(indices.x, 5.) == 0.0 && mod(indices.y, 2.) == 0.){

st = createGrid(st, vec2(5.0), indices);

color = vec3(0.006,1.000,0.607);

float b = drawRectangle(st, vec2(0.5), vec2(0.5));

color = mix( color, vec3(0.2, 0.3, 0.9), b);

} else if( mod(indices.x, 2.) == 1.0 && mod(indices.y, 2.) == 0.0){

color = vec3(0.605,0.942,1.000);

} else if( mod(indices.x, 2.) == 1.0 && mod(indices.y, 2.) == 1.0){

st - createGrid(st, vec2(2.0), indices);

color = vec3(0.000,0.800,0.716);

float d = drawRectangle(st, vec2(0.5), vec2(0.5));

color = mix( color, vec3(0.051,1.000,0.541), d);

} else {

color = vec3(1.000,0.910,0.018);
}

//from a previous sketch playing around shapes and borders
float border = .1 + (tan( st.y * 4. + u_time * .64) *4. + 5.) * 0.1;
float borderAgain = + (cos( -st.y * 0.2 + u_time / 5.) *10. + 0.1) * 0.1;
float borderLast = .12 + (tan( st.y * 0.5 + u_time * .064) *4. + 5.) * .4;

vec2 size = vec2(0.590,0.790);

color.r = drawRectangle( st, size );
color.r -= drawRectangle( st, size - vec2(border));
color.b = drawRectangle( st, vec2(0.290,0.270) + vec2(borderLast));
//color.b -= drawRectangle( st, size);
color.g = drawRectangle( st, vec2(0.9,0.9) - vec2(borderLast));
color.g -= drawRectangle( st, size + borderAgain);

//color.g = drawRectangle( st, vec2(.7,.7));
color.b = drawRectangle( st, vec2(1.9,.32));

gl_FragColor = vec4(color,0.9);

}

```  I made a simple grid of squares that change colour randomly. I imported the shader into P5. The shader also has a layer of a different coloured grid that overlays on top occasionally.

code:

#ifdef GL_ES
precision mediump float;
#endif

uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;

float stipes = 24.072;

float random (vec2 st) {
return fract(sin(dot(st.xy,
vec2(-0.062,stipes + u_time * 0.064)))*
4.409);
}

void main() {
vec2 st = gl_FragCoord.xy/u_resolution.xy;

st *= 9.280; // Scale the coordinate system
vec2 ipos = floor(st*0.396 + abs(sin(u_time *0.396))); // get the integer coords
vec2 fpos = fract(st *-0.068 + abs(cos(u_time *-0.332))); // get the fractional coords
// Assign a random value based on the integer coord
vec3 color = vec3(random( ipos ), fpos);

gl_FragColor = vec4(color,1.0);
}

First, using the tips from last weeks coding session, I got my black and white circle grid to animate the way I wanted it to. See here: Click to play

I used the same animation of circles moving in a clockwise manner around a square. I added noise to the circles, which was affecting their shape and making for interesting patterns.

I then started to introduce color and play with different blending modes. Here are some animations taken throughout the exploration process (click to play them in a new window):

Then I tried exploring with creating a chromatic aberration by stacking three circles in an additive blending mode and then using smoothstep to really blur the edges. Here is that result:

I preferred the look of more distinct and separate blobs. So I went back a step and then changed the background to white and the blending to be subtractive blending mode. I also explored different shaping functions as opposed to using the staged animation of Up, Down, Left, Right. Here it is combining the tan() function with snoise() to some very pleasing results.

This is the final submission:

Bonus? I was able to get my shaders to render in the browser using a node.js package called GLSL-Canvas-JS. (https://www.npmjs.com/package/glsl-canvas-js). So you can view my circle grid OpArt inspired loop and the final blended RGB blobs using noise in full screen at these links:

Code:

```// Nicole Vella
// 2021

#ifdef GL_ES
precision mediump float;
#endif

uniform vec2 u_resolution;
uniform float u_time;

float map(float value,float min1,float max1,float min2,float max2){
return min2+(value-min1)*(max2-min2)/(max1-min1);
}

vec3 permute(vec3 x){return mod(((x*34.)+1.)*x,289.);}

float snoise(vec2 v){
const vec4 C=vec4(.211324865405187,.366025403784439,
-.577350269189626,.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.):vec2(0.,1.);
vec4 x12=x0.xyxy+C.xxzz;
x12.xy-=i1;
i=mod(i,289.);
vec3 p=permute(permute(i.y+vec3(0.,i1.y,1.))
+i.x+vec3(0.,i1.x,1.));
vec3 m=max(.5-vec3(dot(x0,x0),dot(x12.xy,x12.xy),
dot(x12.zw,x12.zw)),0.);
m=m*m;
m=m*m;
vec3 x=2.*fract(p*C.www)-1.;
vec3 h=abs(x)-.5;
vec3 ox=floor(x+.5);
vec3 a0=x-ox;
m*=1.79284291400159-.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.*dot(m,g);
}

float drawRectangle(vec2 st,vec2 pos,vec2 size){
float result=1.;
vec2 border=(1.-size)/2.200;
st=st-pos+vec2(.5);
result=step(border.x,st.x);
result*=step(border.x,1.-st.x);
result*=step(border.y,st.y);
result*=step(border.y,1.-st.y);

return result;
}

#define drawCircle(st,pos,size)smoothstep(0.,250./u_resolution.y,size-length(pos-st))

void main(){
vec2 st=gl_FragCoord.xy/u_resolution.xy;
st.x*=u_resolution.x/u_resolution.y;

float circSize=.5;
vec3 white=vec3(1.);
vec3 black=vec3(0.);
vec3 red=vec3(1.,0.,0.);
vec3 green=vec3(0.,1.,0.);
vec3 blue=vec3(0.,0.,1.);
vec3 canvas=vec3(0.);

float n=snoise(vec2(st.x-u_time*.1,0.))*.5+.5;

float rect=drawRectangle(st,vec2(0.),vec2(4.));

float circleC1=drawCircle(st,vec2(cos(u_time*.33)*n+n+.03,n),circSize);
float circleC2=drawCircle(st,vec2(cos(u_time*.44)*n+n+.02,n),circSize);
float circleC3=drawCircle(st,vec2(cos(u_time*.66)*n+n+.01,n),circSize);

canvas=mix(canvas,white,rect);

canvas*=mix(canvas,green,circleC3);
canvas/=mix(canvas,blue,circleC1);
canvas*=mix(canvas,red,circleC2);

gl_FragColor=vec4(canvas,1.);
}
```

## Week 3

I call this one spaghetti.  ```
// Author @patriciogv - 2015
// http://patriciogonzalezvivo.com

#ifdef GL_ES
precision mediump float;
#endif

uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;
#define PI 3.14159265358979323846
float random (in vec2 st) {
return fract(sin(dot(st.xy,
vec2(0.360,0.320)))
* 43758.5453123);
}

// Value noise by Inigo Quilez - iq/2013
float noise(vec2 st) {
vec2 i = floor(st);
vec2 f = fract(st)+sin(u_time*0.1);
vec2 u = f*f*(3.0-2.0*f);
return mix( mix( random( i + vec2(0.0,0.0) ),
random( i + vec2(1.0,0.0) ), u.x),
mix( random( i + vec2(0.0,1.0) ),
random( i + vec2(1.0,1.0) ), u.x), u.y);
}

mat2 rotate2d(float angle){
return mat2(cos(angle),-sin(angle),
sin(angle),cos(angle));
}
vec2 rotatePattern(vec2 _st, float _angle){
_st -= 0.5;
_st = mat2(cos(_angle),-sin(_angle),
sin(_angle),cos(_angle)) * _st;
_st += -0.596;
return _st;
}

vec2 tile(vec2 _st, float _zoom){
_st *= _zoom;
return fract(_st);
}
float lines(in vec2 pos, float b){
float scale = 1.600;
pos *= scale;
return smoothstep(0.0,
.5+b*.5,
abs((sin(pos.x*u_time/25.0)+b*abs(sin((u_time)))))*.5);
}
vec2 rotateTilePattern(vec2 _st){

// Scale the coordinate system by 2x2
_st *= 2.0;

// Give each cell an index number
// according to its position
float index = 0.0;
index += step(1., mod(_st.x,2.0));
index += step(1., mod(_st.y,2.0))*2.0;

// |
// 2 | 3
// |
//--------------
// |
// 0 | 1
// |

// Make each cell between 0.0 - 1.0
_st = fract(_st);

// Rotate each cell according to the index
if(index == 1.0){
// Rotate cell 1 by 90 degrees
_st = rotatePattern(_st,PI*0.25);
} else if(index == 2.0){
// Rotate cell 2 by -90 degrees
_st = rotatePattern(_st,PI*-.75);
} else if(index == 3.0){
// Rotate cell 3 by 180 degrees
_st = rotatePattern(_st,PI*.75);
}
else{
_st = rotatePattern(_st,PI*-.25);
}

return _st;
}

void main() {
vec2 st = gl_FragCoord.xy/u_resolution.xy;
st = tile(st,1.);
st = rotateTilePattern(st);
st.y *= u_resolution.y/u_resolution.x;

vec2 pos = st.yx*vec2(0.990,0.960);
vec3 color = vec3(0.0);
float pattern = pos.x;