## Assignment 2

For this assignment I wanted to try to make 3D figures using what we learned. I edited the code so that I can have diagonal lines, in doing that I made a trapezoid. I used 2 of the shapes to create each of the faces and overlayed another effect so that there is a red outline. I used a sin function to animate it and try to make it look like there is light circling the object but it did not seem to work.

```// Function for trapezoid
float rect(vec2 st, vec2 size, vec2 loc,float skew, float stretch, vec2 wh){

float result = 1.0;

vec2 border = (1.0-size)/2.000;

result = step( border.x, mix (st.x,st.y,skew)+-loc.x);
result *= step( border.x, wh.x-mix (st.x,st.y,(skew))+loc.x);
result *= step( border.y, mix (st.x,st.y,stretch)+-loc.y);
result *= step( border.y, wh.y-mix (st.x,st.y,stretch)+loc.y);

return result;
}
```
```void main() {

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

//Left cube face
//Variables
vec2 wH1= vec2(0.9,1.22); // Width and height varible to make the layers uniform
vec2 loc1= vec2 (-0.132,-0.204); //Location varible to make the layers uniform

//Colour mixing to get the right colour

vec3 colourA1 = vec3(0.554,1.000,0.673);
colourA1.r = rect(st, vec2 (0.472),loc1,0.,1.434, vec2(wH1));
colourA1.g = rect(st, vec2 (0.400),loc1,0.,1.434, vec2(wH1));

vec3 colourA2 = vec3(0.554,1.000,0.673);
colourA2.r = rect(st, vec2 (0.400),loc1,0.,1.434, vec2(wH1));

vec3 colourA = mix(colourA1,colourA2,0.460);

//Left cube face
//Variables
vec2 wH2= vec2(0.98,0.97);
vec2 loc2= vec2 (0.172,-0.052);

//Colour mixing to get the right colour

vec3 colourB1= vec3(0.767,0.785,0.595);
colourB1.r = rect(st, vec2 (0.448),vec2 (0.228,-0.044),0.,0.858, vec2(0.95,0.97));
colourB1.g = rect(st, vec2 (0.400),loc2,0.,0.858, vec2(wH2));

vec3 colourB2= vec3(0.990,0.985,0.995);
colourB2.r = rect(st, vec2 (0.400),loc2,0.,0.858, vec2(wH2));

vec3 colourB = mix(colourB1,colourB2,-0.172);

// mixing the faces and animation
float amt= sin((st.x+u_time)*(6.28*0.276)+0.5)*cos((st.x+u_time)*(6.28*0.276)+0.5);
vec3 colour= mix(colourA, colourB,amt);
result;
}
```

## Week 5 Homework

```
precision mediump float;
uniform vec2 uResolution;
uniform vec2 uMousePosition;
// lets grab texcoords just for fun
varying vec2 vTexCoord;

// our texture coming from p5
uniform sampler2D tex0;
uniform sampler2D tex1;

void main() {

vec2 uv = vTexCoord;
// the texture is loaded upside down and backwards by default so lets flip it
uv = 1.0 - uv;

// to pixelate an image we need to alter our uvs so that instead of being a smooth gradient it steps from one color to the next
// in order to do this we will use the floor function
// floor will round a float down to the nearest int, so 4.98 would become 4.0, and -37.2 would become -37.0
// first the uv's are multipled times a tiles variable
float tiles = (uMousePosition.x/3.0+5.0);
uv = uv * tiles;

// second the uvs are rounded down to the nearest int
uv = (floor(uv));

// lastly we divide by tiles again so that uvs is between 0.0 - 1.0
uv = uv / tiles;

// often times in glsl you will see programmers combining many operation onto one line.
// the previous three steps could have also been written as uv = floor( uv * tiles ) / tiles

// get the webcam as a vec4 using texture2D and plug in our distored uv's
vec4 color0 = texture2D(tex0, uv);
vec4 color1 = texture2D(tex1, uv);

float blend = clamp(uMousePosition.y / uResolution.x, 0., 1.0);

// use blend to cross-fade with mix()
vec4 color = mix( color1, color0, blend);

gl_FragColor = vec4(color);

// if you'd like a debug view of what the uv's look like try running this line
// gl_FragColor = vec4(uv.x, uv.y, 0.0, 1.0);
}

```

I took a look at Adam Ferriss’ pixel sketch and merged it with the texture blend example from class. I added interaction using mouse X and mouse Y so that when the mouse is moved horizontally the image output becomes pixelated and when the mouse is moved vertically the camera output and image are blended. Figuring out these interactions took quite a while because I’ve never looked at GLSL with P5 but I was glad to get this little sketch functioning!

For this first shader I took inspiration from the webcam displacement example and instead used two images together. I took a picture of a wolf’s head and a picture of water from the internet and added the sin() function to create a murky, watery effect. I used millis() in x position for the set.Uniform statement (myShader.setUniform(“uDisplacement”, map(millis()/50, 0, width, 0, 5));) to produce a u_time effect like in GLSL. In a way, the water image is being animated to displace the wolf image.

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

uniform vec2 uMousePosition;
uniform vec2 uResolution;

uniform sampler2D uTexture0; //wolf
uniform sampler2D uTexture1; //water
uniform float uTime;
uniform float uDisplacement;

varying vec2 vTexCoord;

//takes rbg of a pixel and calculates luminosity
float rgb_to_luma( vec3 color ){
return 0.2126*color.r + 0.7152*color.g + 0.0722*color.b;
}

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

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

void main() {

vec4 color = vec4(0.0, 1.0, 1.0, 0.0);

vec2 offset = vec2(0.0, 0.0);

offset = texture2D(uTexture0, vec2(vTexCoord.x, 1.0-vTexCoord.y)).gb;
offset *= 1.0;

//colours to luminosity
float c = rgb_to_luma(texture2D(uTexture0, vec2(vTexCoord.x, 1.0-vTexCoord.y)).rgb);

offset = vec2(c, c) + uDisplacement;

vec2 uv = vec2(vTexCoord.x, 1.0-vTexCoord.y) + offset;
//vec2 uv = vec2(uTime(vTexCoord.x), 1.0-vTexCoord.y) + offset;
//using sin() to distort the image
color = texture2D(uTexture1, sin(uv) * 0.5);

gl_FragColor = vec4(color);
}

```

For WEEK 5, I worked with Mahnoor. I was tasked with the initial porting of our Week 3 shaders into p5.js and creating an image distortion shader.

For the image distortion shader, I created a distorter that affects the texture UV coordinates of the image, based on Simple Texture Distort by mikiex on Shader Toy. Instead of using a noise texture as mikiex did, I replaced it with generated simplex noise from the Book of Shaders. To create an inverted colour filter for the image, I divided the initial image that I added the distortion value to the UV with a mix of the distorted initial image texture with an altered second version of the image that instead subtracted the distortion from the UV. Mixing the two versions of the distorted image, one that follows the original colour scheme and another that is inverted distorts them in opposite directions. This results in a swipe effect where the value of distortion would become zero in both directions (looped using sin) and will form the original non-distorted image of the flowers for a split second.

The distorted colours and rounded shapes that the noise forms the image into reminds me of the psychedelic closeups of the surface of a soap bubble (caused by a two-beam interference of light).

Overall, I enjoyed the Shader exercises this week and had fun seeing how my partner, Mahnoor, approached shader art. It was also great to have immediate feedback during the process and to support each other and help when we got stuck.

There is not much to say about porting our Week 3 shaders into p5.js, other than every line of setup code counts. It was more complicated than I thought it would be, although fairly straightforward to execute once you are used to the process. I did have fun applying the shaders as textures to some simple (default) shapes (a sphere and box). I added simple interaction to the p5.js sketch to switch between 3D shapes and shaders on mouse click as well allow the viewer to rotate the shapes using mouse coordinates.

```
//Title: Image Distortion

#ifdef GL_ES
precision mediump float;
#endif

//get texture coordinates from vert shader
varying vec2 vTexCoord;

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

//texture coming from p5.js
uniform sampler2D imgtext;

//Book of Shaders Simplex Noise (based off Ian McEwan, Ashima Arts)
// Some useful functions
vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }
vec2 mod289(vec2 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }
vec3 permute(vec3 x) { return mod289(((x*34.0)+1.0)*x); }
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 &amp;amp;gt; 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);
}

void main() {

// position of the pixel divided by resolution, to get normalized positions on the canvas
vec2 st = gl_FragCoord.xy/u_resolution.xy;

vec2 uv = vTexCoord;

//texture is loaded upside down and backwards by default, so flip it
uv.y = 1.0 - uv.y;

//create a distorter (based off Simple Texture Distort by mikiex, instead of another texture it uses snoise)
vec2 pos = vec2(st.x*10.0 - (u_time*0.2), st.y*10.0 + (u_time*0.2));

vec3 dist = vec3(snoise(pos)*0.5+0.5);

vec2 distorter = vec2(dist.rg) * vec2(0.1-sin(u_time*0.2));

//zoom in and out of image by multiplying the "UV" value, use fract to tile zoomed out images
vec4 imgText = texture2D(imgtext, fract(uv)+distorter);
vec4 imgText2 = texture2D(imgtext, fract(uv)-distorter);

float grey = (imgText.r + imgText.g + imgText.b)/3.0;

vec3 color = vec3(0);

//grey filter
// color = vec3(grey);

//default (full) color
color = vec3(imgText.r,imgText.g, imgText.b);

//blend in an "inverted" color filter version of the image
// color /= mix(color, vec3(1.0), vec3(imgText2.r,imgText2.g, imgText2.b));

color /= mix(color, vec3((sin(u_time*0.1))), vec3(imgText2.r,imgText2.g, imgText2.b));

//direct image color
// gl_FragColor = vec4(imgText);

//filtered camera feed
gl_FragColor = vec4(color, 1.0);
}
```

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[0], hsbtemp[1]*0.5, hsbtemp[2]*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