The above 4 images show several iterations of my code below. I had a lot of fun experimenting with creating a kaleidoscope effect by overlapping several dynamic circles (their shapes were altered/deformed using noise) at varying opacities, colour schemes/noise-based gradients, and offsets. Like in the noise tutorial from class, I decided to create the background with a dynamic gradient of colours also controlled by offset noise. Originally the circles used a similar rainbow noise gradient, but I felt that I wanted to create more contrast between the background and circles. I experimented (as shown above) with white, black, grey, and blue. It appeared that using other solid colours like red, green, and yellow didn’t create enough contrast.

I find it really cool how the circles are not the “main” kaleidoscope shapes but are used to create negative space that cuts through the background in order to create the effect. I added a basic outlined square to the tile pattern to add more-dynamic overlay effects. The brightness and opacity of the squares are controlled using horizontal mouse movements.

```
// Title: 2D Perlin Simplex Noise V12

#ifdef GL_ES
precision mediump float;
#endif

#define PI 3.142

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

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

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

//rotation functions from the Book of Shaders "Patterns"
vec2 rotate2D(vec2 st, float angle){
st -= 0.5;
st = mat2(cos(angle), -sin(angle),
sin(angle), cos(angle))*st;
st += 0.5;
return st;

}

vec2 rotateTilePattern(vec2 st){

//scale coordinate system by 2x2
st *= 6.0;

//give each cell and index number according to its position
float i = 0.0;
i += step(1.0, mod(st.x,2.0));
i += step(1.0, mod(st.y,2.0))*2.0;

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

//rotate each cell according to index
//use matrix to rotate the space

if(i == 1.0){
st = rotate2D(st, PI*-0.5);
} else if (i == 2.0){
st = rotate2D(st, PI*0.5);
} else if (i == 3.0){
st = rotate2D(st, PI*2.0);
} else if (i== 0.0){
st = rotate2D(st, PI);
}

return st;

}

float drawCircle(vec2 st, vec2 position, float size){

float result = distance(st, position);
result = 1.0 - step (size, result);

return result;

}

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

//invert size so the size variables will control the size based on the white dimensions
vec2 border = (1.0-size)/2.0;

result = step(border.x + pos.x, st.x);
result *= step(border.x - pos.x, 1.0-st.x);
result *= step(border.y + pos.y, st.y);
result *= step(border.y - pos.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(0.0);

//scale coordinate system to see noise
vec2 pos = vec2(st.x*1.0 - sin(u_time*0.2), st.y*1.0 + cos(u_time*0.2));

//BACKGROUND
color.r = snoise(pos) * 0.5 + 0.5;
color.b = snoise(pos + vec2(u_time*0.3)) * 0.5 + 0.5;
// color.r = snoise(pos + vec2(u_time*0.3)) * 0.5 + 0.5;
// color.g = snoise(pos + vec2(u_time*0.3)) * 0.5 + 0.5;
color.g = snoise(pos + vec2(u_time*0.1)) * 0.5 + 0.5;

//TILE and ROTATE
st *= vec2(0.5, 0.5);
st += rotate2D(st,PI*0.5);

//then rotate title patterns based on index/location
st = rotateTilePattern(st+0.25);

//CIRCLE SETUP
//Animated circle size with noise function, add "st" in vector with noise to create a dynamic shape
//create an offset in size and opacity for each subsequent circle
float circle = drawCircle(st, vec2(0.580,0.550), (snoise(st + vec2(u_time*0.2))*0.5 +0.5) * 0.5 + 0.1)*1.0;
float circle2 = drawCircle(st, vec2(0.500,0.500), (snoise(st + vec2(u_time*0.2))*0.5 +0.5) * 1.0 + 0.1)*0.75;
float circle3 = drawCircle(st, vec2(0.710,0.330), (snoise(st + vec2(u_time*0.2))*0.5 +0.5) * 1.5 + 0.1)*0.5;

vec3 circleColor = vec3(0.005,0.005,0.005);

// circleColor.r = snoise(pos) * 0.5 + 0.5;
// circleColor.b = snoise(pos + vec2(-u_time*0.3)) * 0.5 + 0.5;
// circleColor.g = snoise(pos + vec2(-u_time*0.1)) * 0.5 + 0.5;

// circleColor.b *= (snoise(pos) * 0.5 + 0.5)*0.2;
// circleColor.b += (snoise(pos + vec2(-u_time*0.3)) * 0.5 + 0.5)*0.2;
// circleColor.b += (snoise(pos + vec2(-u_time*0.1)) * 0.5 + 0.5)*0.2;

//circle color normal black and white gradient
circleColor = vec3(snoise(pos) * 0.5 + 0.5)*0.2;
circleColor += vec3(snoise(pos + vec2(-u_time*0.3)) * 0.5 + 0.5)*0.2;
circleColor += vec3(snoise(pos + vec2(-u_time*0.1)) * 0.5 + 0.5)*0.2;

//RECTANGLE OVERLAY
//solid black outline
// float rectangle = drawRect(st, vec2(0.0), vec2(0.9)-0.1);

//low opacity outline
float rectangle = drawRect(st, vec2(0.0), vec2(0.6)-0.1);
rectangle -= drawRect(st, vec2(0.0), vec2(0.8)-0.1);

//full opactity fill of rectangle
// rectangle = drawRect(st, vec2(0.0), vec2(0.8)-0.1);

//MIX/LAYER CIRCLES
//second mix parameter controls color of shape (circle)
color = vec3(mix(color, circleColor, circle));
color = vec3(mix(color, circleColor, circle2));
color = vec3(mix(color, circleColor, circle3));

//second mix parameter controls brightness/opacity of rectangular overlay
color = vec3(mix(color, vec3(u_mouse.x/u_resolution.x), rectangle));

gl_FragColor = vec4(color,1.0);
}

&amp;amp;amp;nbsp;

```

I pushed my week 2 tiled/grid shader further by animating it.

I also refactored the code into less lines while making it more semantically legible.

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

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 drawRectangle(vec2 st,vec2 pos,vec2 size){

float result=1.;
vec2 border=(1.-size)/2.200;

// border animations
// vec2 border = (1.0t-size)/2.200 + cos(st.x *6. + u_time)*0.508;
// border.x =  0.25*sin(st.x*u_time);
// border.y = -0.25*cos(st.y*u_time);

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

float drawCircle(vec2 st,vec2 pos,float size){
float d=distance(st,pos);
// step shows values > argument 1, and we want the opposite
// so we invert the results by subtraction 1.0 - the value
return 1.-step(size,d);
}

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

vec2 st0=st;
vec2 indices;
st=createGrid(st,vec2(10.,10.),indices);

float delay=.45;
float circSize=.5;

vec2 size=vec2(.25,.25);
vec2 pos=vec2(.5,.5);

vec3 white=vec3(1.);
vec3 black=vec3(0.);
vec3 canvas=vec3(0.);

// animations
// 0 to 1
float animation0to1=map(sin(u_time*delay),-1.,1.,0.,1.);
// 1 to 0
float animation1to0=map(sin(u_time*delay),-1.,1.,1.,0.);

// bg rect
float rect=drawRectangle(st,vec2(.5),vec2(1.));

// top edge, Left To Right circle
float circleTLTR=drawCircle(st,vec2(animation0to1,1.),circSize);

// bottom edge, Right To Left circle
float circleBRTL=drawCircle(st,vec2(animation1to0,0.),circSize);

// left edge, Top To Bottom circle
float circleLTTB=drawCircle(st,vec2(0.,animation1to0),circSize);

// right edge, Bottom To Top circle
float circleRBTT=drawCircle(st,vec2(1.,animation0to1),circSize);

if((mod(indices.x,2.)==0.&&mod(indices.y,2.)==1.)||(mod(indices.x,2.)==1.&&mod(indices.y,2.)==0.)){

canvas=mix(canvas,white,rect);
canvas=mix(canvas,black,circleTLTR);
canvas=mix(canvas,black,circleBRTL);

}else{

canvas=mix(canvas,black,rect);
canvas=mix(canvas,white,circleRBTT);
canvas=mix(canvas,white,circleLTTB);

}

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

This is a result of experimentation. I just multiplied the canvas by 12, a line that was formed and commented out following along to class. Adding zeroes to 12 till it was 1.2 million, with no particular reason, just liked the result at 1200000.

My approach is usually pushing/decimating a quality, attribute, variable to see what happens and is saved based on interesting results.

I was trying to make a pattern design that I liked, satisfied with a result I went on to push some numbers to see what some lines of code actually do. Pushed the pattern to the point that it seemed to render blank and return to a result along the way that I liked.

I made a shapes shader but ended up animating it and although very pleased with the tweaked and experimented results it doesn’t open the same as it was made, though sometimes it does?

Throughout this lesson I grasped a lot more understanding of coding shaders. Review and iterations are likely approaches to further learning.

```
// Author: Joshua Linton
// Title: Breaking Patterns
// Reference: code is derived from following along to Shader Session: 2D Patterns, asynchronous lecture,
// from DIGF3011 - OCADU - Prof. J. Rotsztain

#ifdef GL_ES
precision mediump float;
#endif

uniform vec2 u_resolution;
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 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.-st.y);

return result;
}

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

st *= 1200000.;
//It is through this line that I have transformed a 64 by 24 grid with internal grids into this result.
//Multiplying the canvas by 1.2 million.
//This is quite typical, my immediate experimentation is always to begin adding zeroes to any number in formula.

vec2 indices;

st = createGrid( st, vec2(64., 24.), indices);

vec3 color = vec3(0.);

if( mod(indices.x, 2.) == 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);
}

gl_FragColor = vec4(color,1.0);
}

```

I wanted to explore creating textures through black and white gradients. As well as using the idea of truchet tiles.

I began with simple shapes and gradients.

Tiling them generates a texture.

Moving the location of the circles will create different patterns, some becoming almost seamless.

Code:

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

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

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

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.;
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;
}

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

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;

// create our grid
st=createGrid(st,vec2(10.,10.),indices);

vec3 color=vec3(0.);

// a float to control animation speed
float speed=.5;

float circle1=drawCircle(st,vec2(1.,1.),.5);
float circle2=drawCircle(st,vec2(0.,0.),.5);

// animations
// float circle1=drawCircle(st,vec2(0.,map(cos(u_time*speed),-1.,1.,0.,1.)),.5);
// float circle2=drawCircle(st,vec2(1.,map(cos(u_time*speed),-1.,1.,1.,0.)),.5);
// float circle1=drawCircle(st,vec2(map(sin(u_time*speed),-1.,1.,0.,1.),map(cos(u_time*speed),-1.,1.,0.,1.)),.5);
// float circle2=drawCircle(st,vec2(map(cos(u_time*speed),-1.,1.,0.,1.),map(sin(u_time*speed),-1.,1.,0.,1.)),.5);

// color = vec3(st.t.y,abs(sin(u_time)));
vec2 size=vec2(.25,.25);
vec2 pos=vec2(.5,.5);

// color = mix( color, vec3(pct2)*(atan(u_time)+1.)*0.03, circle2);

float rect=drawRectangle(st,vec2(.5),vec2(1.));

// various gradients based on different distances
float pct=distance(st,vec2(.5));
float pct2=distance(st,vec2(1.,1.));
float pct3=distance(st,vec2(0.,0.))*2.;
float pct4=distance(st,vec2(0.,0.));
float pct5=distance(st,vec2(map(sin(u_time*speed),-1.,1.,0.,1.),map(cos(u_time*speed),-1.,1.,0.,1.)));

// use the mix function to draw multiple shapes
color=mix(color,vec3(pct2),rect);
color=mix(color,vec3(pct5),circle1);
color=mix(color,vec3(pct),circle2);

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

The above four images show is a sequence of animated shader stills from left to right and top to bottom.

For this week’s homework shader explorations I decided to integrate my first shader, a Piet Mondrian inspired shader (created when I was exploring rectangle placement and layering effects for the Book of Shaders’ “recreate a Piet Mondrian painting” exercise), as I felt the design would make for a cool tile effect. The original colours followed Mondrian’s primary colour scheme (similar to the last still, but the small rectangle was yellow), but I felt that it needed to be more dynamic so I decided to animate a colour shifting gradient using u_time and smoothstep.

I still felt like I needed to add more variety of shapes, as I took the effort to make functions based on all of the shape exercises, so I decided on adding a polar shape. I found experimenting with the different parameters of polar shapes extremely fun, therefore I created a polar shape function that allowed me to control everything from position to length and width of spokes. Although I could have gone for a more complicated shape, I decided against it because the tiling pattern was also complex. It was an awesome moment when I realized I was able to layer the tile pattern over the polar design and see the solar shapes through the gap made with one of the rectangles.

Overall, I had a lot of fun learning about shapes and creating my own functions for them.

```// Author: Madelaine Fischer-Bernhut
// Title: Animated Piet Mondrian Pattern v2

#ifdef GL_ES
precision mediump float;
#endif

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

#define PI 3.14159265358979323846

//rotation and tile functions from the Book of Shaders "Patterns"
vec2 rotate2D(vec2 st, float angle){
st -= 0.5;
st = mat2(cos(angle), -sin(angle),
sin(angle), cos(angle))*st;
st += 0.5;
return st;

}

vec2 tile(vec2 st, float zoom){
//scale up space
st *= zoom;

//wrap around 1.0
return fract(st);
}

vec2 rotateTilePattern(vec2 st){

//scale coordinate system by 2x2
st *= 2.0;

//give each cell and index number according to its position
float i = 0.0;
i += step(1.0, mod(st.x,2.0));
i += step(1.0, mod(st.y,2.0))*2.0;

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

//rotate each cell according to index
//use matrix to rotate the space

if(i == 1.0){
st = rotate2D(st, PI*-0.5);
} else if (i == 2.0){
st = rotate2D(st, PI*0.5);
} else if (i == 3.0){
st = rotate2D(st, PI*2.0);
} else if (i== 0.0){
st = rotate2D(st, PI);
}

return st;

}

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

//invert size so the size variables will controle the size based on the white dimensions
vec2 border = (1.0-size)/2.0;

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

return result;
}

float createPolShape(vec2 st, float size, float spokesNum, vec2 spokeSize, vec2 pos, float rot, float blur){
float result = 1.0;

//control the position of the shape
pos -= st;

//control the size of the shape
float r = length(pos)*size;
float a = atan(pos.y, pos.x);

//control the number of "spokes" and their shape
//rotate and animate the shape by adding or subtracting from the "a" in cos or sin
float f = cos(a*spokesNum + rot)*spokeSize.y+spokeSize.x;
f = abs(cos(a*spokesNum+rot)*sin(a*spokesNum+rot))*spokeSize.y+spokeSize.x;
// f = smoothstep(-.5,1.0, cos(a*spokesNum+rot))*spokeSize.y+spokeSize.x;

//changing f+value effects focus of shape (blurred)
result = 1.0-smoothstep(f,f+blur,r);

return result;
}

void main() {
//st are texture coordinates, s is along the horizontal axis and t along the vertical axis (surface)
vec2 st = gl_FragCoord.xy/u_resolution.xy;
st.x *= u_resolution.x/u_resolution.y;

float outline = 0.05;

//for testing: centre of polar shape position is based on mouse
vec2 pos = u_mouse/u_resolution;
pos = vec2(0.5);

vec3 color = vec3(0.0);

//polar shape will appear underneath Piet Mondrian pattern
color = vec3(createPolShape(st, 2.15, 10.0, vec2(0.350,0.860), pos, u_time*2.0, -0.260));

//divide space by value
st = tile(st, 1.0);

//first rotate entire space by 90 deg
st += rotate2D(st,PI*0.5);

//then rotate title patterns based on index/location
st = rotateTilePattern(st);

//create bordered rectangles

//white rectangles
//adding the initial rectangle layer instead of multiplying results in the Piet Mondrian Pattern being masked by the polar shape
// color += vec3(drawRect(st, vec2(0.360,0.590) - vec2(outline), vec2(-0.320,0.210)));

//multiplying a rectangle layer in with the other two added results in that rectangle becoming "transparent"
color *= vec3(drawRect(st, vec2(0.360,0.590) - vec2(outline), vec2(-0.320,0.210)));
color += vec3(drawRect(st, vec2(0.480,0.585) - vec2(outline), vec2(0.259,-0.067)));
color += vec3(drawRect(st, vec2(1.0,0.165) - vec2(outline), vec2(0.000,-0.417)));

//coloured rectangles (with animated gradient overlay effect using smoothstep to control placement, and offsetting those colour gradients by overlaying sin &amp; cos time animations)
color.r += drawRect(st, vec2(0.540,0.300) - vec2(outline), vec2(0.105,0.350)) * smoothstep(sin(u_time*0.4)*0.9,1.1,st.x) ;
color.g += drawRect(st, vec2(0.540,0.300) - vec2(outline), vec2(0.105,0.350)) * smoothstep(cos(u_time*0.4)*0.9,1.1,st.x) ;
color.r += drawRect(st, vec2(0.150,0.3) - vec2(outline), vec2(0.425,0.35))* smoothstep(cos(u_time*0.4)*0.9,1.5, st.y);
color.g += drawRect(st, vec2(0.150,0.3) - vec2(outline), vec2(0.425,0.35))* smoothstep(sin(u_time*0.4)*0.9,1.5, st.y);
color.b += drawRect(st, vec2(0.540,0.300) - vec2(outline), vec2(-0.230,-0.210)) * smoothstep(sin(u_time*0.4)*0.95,1.2, 1.0-st.x);
color.g += drawRect(st, vec2(0.540,0.300) - vec2(outline), vec2(-0.230,-0.210)) * smoothstep(cos(u_time*0.4)*0.95,1.2, 1.0-st.x);

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

Note: someone please tell me how to embed the code in these posts because it seems I am the only one who can’t figure it out, and here I am pastebin-ing like a chump. Thanks in advance!

Code: https://pastebin.com/iu7Q6nai

This was an exercise in getting accustomed to using shapes to create images. These are layered circles – including the curves, which are made using background-coloured circles to cover other circles. I found the book of shaders editor’s built in number and colour adjustment tools made it pretty easy to arrange the shapes. In terms of tweaking the circle to take on slightly different curves, I’m still figuring that out.

Code: https://pastebin.com/ndrG1uTa

This is a simple pattern made using a grid. I struggled to figure out how to get access to use the pixel position within the larger canvas, rather than within the grid cell itself. (I still haven’t figured it out). I understand manually designating which row and column combinations to render which set of instructions, but I wonder how to introduce a bit more randomness.

I spent some time playing around with the border function. I ended up with this gradient that slowly moves towards the bottom left of the screen. The colors mix in weird way with this one so I decided to leave it as is.

```// Author:Mark Herod
// Title: Shape/Pattern

#ifdef GL_ES
precision mediump float;
#endif

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

float drawRect (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;
}

float drawCircle(vec2 st, float size){
float result = distance(st, vec2(0.5));
result = 1.072-step(size,result);

return result;
}

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

vec3 color = vec3(0.);

float border = 0.178 + (cos(st.x * 98.008 + u_time * 2.112) *0.732 *0.5);

//applies border and movement to each shape.
// also give shader the squarish shape
border /= + (cos(st.y * 99. + u_time * 1.792) *2.444 *1.284);

vec2 size = vec2 (0.5,0.5);

//draws squares
color.g = drawRect( st, size );
color.g = (asin(drawRect( st, size - vec2(border))));

//draws circle.
color.r = drawCircle(st, border);
color.b += drawCircle(st,border/st.y);

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

This was just an experimentation of shapes and seeing how things worked together. I used the square as more of a light source to shine in from the right.

```// Author: Mark Herod

#ifdef GL_ES
precision mediump float;
#endif

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

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

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

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

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

result =(border.x, st.x);

return result;
}

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

vec3 color = vec3(0.042,0.575,0.396);
//color = vec3(st.x,st.y,abs(sin(u_time)));

float c1 = drawCircle(st, vec2(0.320,0.470),0.4);
float c2 = drawCircle(st, vec2(0.360,0.270),0.560);
float c3 = drawCircle(st, vec2(0.320,0.470),4.);

float r1 = drawRect( st, vec2(2.0, 0.2) );

color = mix(color, vec3(0.0,1.1,3.0),c1*0.5 );
color = mix(color, vec3(2.499,3.000,0.306),c2*0.5 );
color = mix(color, vec3(0.209,0.405,0.036),c3*0.5 );
color = mix(color, vec3(3.000,1.086,2.930),r1/1.8);

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

I feel like I had even more trial and error this week than I did previously, as I actually had a very hard time trying to learn how to combine shapes and colors, so I was very pleased when I figured it out.

Because of that, I ended up working on the pattern shader first. It ended up being more of an aesthetic exploration where I played with rotating tiles and optical illusions, using some of the functions from the Book of Shaders and tweaking with the numerical values. Initially, I wanted to play with changing colors on each tile rather than rotating but as I was having trouble finding out how to add colors, I decided to focus on the other aspects.

```
// Author: Dawn Murphy

#ifdef GL_ES
precision mediump float;
#endif

#define PI 3.14159265358979323846

uniform vec2 u_resolution;
uniform float u_time;

vec2 rotate2D (vec2 _st, float _angle) {
_st -= 0.5;
_st = mat2(cos(_angle),-sin(_angle),
sin(_angle),cos(_angle)) * _st;
_st += 0.5;
return _st;
}

vec2 rotateTilePattern(vec2 _st){

// Scale the coordinate system to 2x2
_st *= 3.0;

//number each cell
// |
// 2 | 3
// |
//--------------
// |
// 0 | 1
// |

float index = 0.0;
index += step(1., mod(_st.x,2.0));
index += step(1., mod(_st.y,2.0))*2.0;

// 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 45 degrees
_st = rotate2D(_st,PI*0.75);
} else if(index == 2.0){
// Rotate cell 2 by 145 degrees
_st = rotate2D(_st,PI*-0.75);
} else if(index == 3.0){
// Rotate cell 3 by 180 degrees
_st = rotate2D(_st,PI);
}
return _st;
}

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

//Make 4 tiles
st *= 2.0; // Scale up the space by 3
st = fract(st); // Wrap around 1.0
st = rotateTilePattern(st);

// Remap the space to -1. to 1.
st = st *2.-1.;

// Make the distance field
d = length( abs(st)-1.0);

// Visualize the distance field
gl_FragColor = vec4(vec3(fract(d*5.0)),1.0);

}

```

For the shape and color-based shader, I did a lot more digging, examining examples from the book, and (of course) trial and error until I was able to find a way to functionally combine shapes with colors using mix(). For the result, I worked on making shapes in different colors and positions and with layering them in a pleasing way.

```
// Author: Dawn Murphy

#ifdef GL_ES
precision mediump float;
#endif

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

//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);

vec3 pct = vec3(st.x);

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

//combine time
color = mix(colorF,vec3(0.066,0.273,1.000),colorT); //adds the third circle and colors it blue
color = mix(color,vec3(0.592,0.129,0.730),colorS); //adds the second circle and colors it purple
color = mix(color,vec3(0.995,0.280,0.695),colorFo); //adds the fourth circle and colors it pink
color = mix(color,vec3(0.066,0.273,1.000),colorFi); //adds the fifth circle and colors it blue
gl_FragColor = vec4( color, 1.0 ); //draws
}

```

I enjoyed experimenting with colours for this week’s homework. I was able to get some interesting results by just repeating shapes and adding exponential functions to them. I only implemented slight animation for this image so it has a subtle, hypnotic feel to it.

```
// Author: Emily Flood
// Title: Wavy circles

#ifdef GL_ES
precision mediump float;
#endif

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

float drawRect(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.-st.y);

return result;
}

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

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

//animating the shapes slightly
st.x += sin(st.y *20. + u_time) * -0.0;
st.y += cos(st.x *1. + u_time) * -0.01;

vec3 color = vec3(0.);

//delcaring border for rectangle
float border = 0.01;

//drawing all the circles
float c1 = drawCircle(st, vec2(0.210,0.180),0.4);
float c1b = drawCircle(st, vec2(0.320,0.400),0.512);
float c2 = drawCircle(st, vec2(0.740,0.400),0.4);
float c2b = drawCircle(st, vec2(0.380,0.250),1.088);
float c3 = drawCircle(st, vec2(0.200,0.990),0.472);
float c4 = drawCircle(st, vec2(0.040,0.540),0.240);
float c5 = drawCircle(st, vec2(0.870,0.880),0.288);
float c6 = drawCircle(st, vec2(0.840,0.270),0.152);
float c7 = drawCircle(st, vec2(0.840,0.020),0.320);

//drawing all the rectangles
float r1 = drawRect(st, vec2(0.740,0.720));
float r2 = drawRect(st, vec2(0.550,0.550));
float r3 = drawRect(st, vec2(0.430,0.440));

//implementing colours into the rectangles
color = mix(color, vec3(0.418,0.396,0.440),r1*1.);
color = mix(color, vec3(0.048,0.865,0.791),r2*0.992);
color = mix(color, vec3(0.000,1.000,0.536),r3*1.516);

//implementing colours into the circles
color = mix(color, cos(vec3(0.776,0.609,1.000)),c1*1.572);
color -= mix(color, cos(vec3(0.776,0.609,1.000)),c1b*2.364);
color = mix(color, vec3(0.895,1.000,0.674),c2*0.716);
color = mix(color, sin(vec3(0.890,0.665,1.000)),c2b*1.364);
color = mix(color, vec3(0.946,1.000,0.578),c3*2.268);
color = mix(color, vec3(0.270,1.000,0.981),c4*0.732);
color = mix(color, cos(vec3(1.000,0.389,0.711)),c5*1.876);
color = mix(color, vec3(1.000,0.389,0.711),c6*1.364);
color = mix(color, cos(vec3(0.270,1.000,0.981)),c7*0.652);

/*
color.r = drawRectangle(st, vec2 (0.9,0.9) );
color.g = drawRectangle(st, vec2(0.8,0.8));
color.b = drawRectangle(st, vec2(1.,1.));
*/

gl_FragColor = vec4(color,1.0);
}

```

During the first video Jeremy creates a “fiery box” by animating the waves with this:

```
st.x += sin(st.y *20. + u_time) * -0.108;
st.y += cos(st.x *20. + u_time) * -0.540;

```

So I used this code to create some interesting wavy animations. I also experimented with adding several shapes with the mix() function.

```
// Author: Emily Flood
// Title: Fluorescent waves

#ifdef GL_ES
precision mediump float;
#endif

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

//drawCircle function
float drawCircle(vec2 st, vec2 pos, float size){

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

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

vec3 color = vec3(0.);

//animating the waves
st.x += sin(st.y *20. + u_time) * -0.108;
st.y += cos(st.x *20. + u_time) * -0.540;

//declaring size variable
vec2 size = vec2(0.1,0.1);

//drawing circles
float c1 = drawCircle(st, vec2(0.100,0.620),0.4);
float c2 = drawCircle(st, vec2(0.400,0.620),0.4);
float c3 = drawCircle(st, vec2(0.700,0.620),0.4);
float c4 = drawCircle(st, vec2(1.0,0.620),0.4);

color = mix(color, vec3(0.0, 0.0, 1.0),c1*0.908);
color = mix(color, vec3(1.000,0.332,0.198),c2*0.5);
color = mix(color, vec3(1.000,0.036,0.888),c3*0.612);
color = mix(color, vec3(1.000,0.948,0.112),c4*0.652);

gl_FragColor = vec4(color,1.0);
}

```

I realized that I enjoy working with fluorescent colours. I made this vibrant grid pattern with a couple of different tiling methods, including a tile() function as well as using the mod() function to repeat this effect, causing an interesting inconsistency in the grid.

```
// Author: Emily Flood
// Title: Vibrant 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;
}

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,1.184);
st.x += sin(st.y *17. + u_time) * 0.1;
st.y -= cos(st.x *17. + 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,1.072);

//applying colour
color = mix(color, vec3(0.709,0.548,0.870),r1*0.3);
color = mix(color, vec3(0.975,0.423,0.000),c1*0.3);

gl_FragColor = vec4(color,1.0);
}

```

Week 2 Homework

For this shader I began with the Truchet Tile code from The Book of Shaders. Through rotating different tiles and experimentation I was able to create an arrow shape. I immediately knew that I wanted the arrows to move in the direction they are pointing and it didn’t take too long to figure out how to achieve this. I also played around with creating an outline around the entire canvas. I was hoping to outline the arrows but I got stumped and couldn’t figure out how to do it. It’s not the prettiest shader but I found that making the arrow shape and then making them move was a good coding exercise.

```
// Author Max Shapovalov
//Title: Arrows
//Modified work of @patriciogv ( patriciogonzalezvivo.com ) - 2015

#ifdef GL_ES
precision mediump float;
#endif
#define PI 3.14159265358979323846
uniform vec2 u_resolution;
uniform float u_time;

float circle(in vec2 _st, in float _radius){
vec2 dist = _st-vec2(0.5);
dot(dist,dist));
}
vec2 rotate2D (vec2 _st, float _angle) {
_st -= 0.5;
_st = mat2(cos(_angle),-sin(_angle),
sin(_angle),cos(_angle)) * _st;
_st += 0.5;
return _st;
}

vec2 tile (vec2 _st, float _zoom) {
_st.x += step(1., mod(_st.y,2.0)) * 2.;
_st *= _zoom;

return fract(_st);
}

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 = rotate2D(_st,PI*0.25);
} else if(index == 2.0){
// Rotate cell 2 by -90 degrees
_st = rotate2D(_st,PI*-1.);
} else if(index == 3.0){
// Rotate cell 3 by 180 degrees
_st = rotate2D(_st,PI*+0.75);
}

return _st*2.;
}
vec2 brickTile(vec2 _st, float _zoom){
_st *= _zoom;

// Here is where the offset is happening
_st.x += step(1., mod(_st.y+0.5,3.)) * 0.5;

return fract(_st);
}
void main(void){
vec2 st = gl_FragCoord.xy/u_resolution.xy;
vec3 pattern = vec3(0.0);
vec3 pattern2 = vec3(0.0);
vec3 blue=vec3(0.003,0.575,1.000);
vec2 bl = step(vec2(0.05),st); // bottom-left
vec2 tr = step(vec2(0.05),1.-st); // top-right
vec3 outline = vec3(bl.x * bl.y * tr.x * tr.y);

blue = mix(blue,vec3(outline.x,1.0,1.0),.6);
st = tile(vec2(-st.y+(fract(u_time/5.0)),-st.x),1.0);
st = brickTile(st,3.0);
st = rotateTilePattern(st);
pattern = vec3(circle(st-st.x,(0.5-st.y)));
outline = vec3(circle(st,(0.5-st.y)));

blue = mix(blue,vec3(outline.x,1.0,1.0),.1);

pattern=mix(pattern,blue,.9);
pattern=smoothstep(vec3(pattern),vec3(.2),vec3(.5));
gl_FragColor = vec4(pattern,1.);

}

```

In this shader I played around with creating circles and squares overtop of one another and then using the step function to get a silhouette. I found that the order of functions and can drastically change how the shader looks. Lastly I divided the canvas in four quadrants and made them spin.

```// Author @patriciogv ( patriciogonzalezvivo.com ) - 2015
//title: crosses
#ifdef GL_ES
precision mediump float;
#endif

#define PI 3.14159265358979323846

uniform vec2 u_resolution;
uniform float u_time;

vec2 rotate2D (vec2 _st, float _angle) {
_st -= 0.5;
_st = mat2(cos(_angle),-sin(_angle),
sin(_angle),cos(_angle)) * _st;
_st += 0.5;
return _st;
}

vec2 tile (vec2 _st, float _zoom) {
_st *= _zoom;
return fract(_st);
}
vec2 brickTile(vec2 _st, float _zoom){
_st *= _zoom;

// Here is where the offset is happening

_st.x += step(1., mod(_st.y,2.0)) ;

return fract(_st);
}
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 = rotate2D(_st,PI*1.);
} else if(index == 2.0){
// Rotate cell 2 by -90 degrees
_st = rotate2D(_st,PI*-0.0);
} else if(index == 3.0){
// Rotate cell 3 by 180 degrees
_st = rotate2D(_st,PI*-.5);
}
else{
_st = rotate2D(_st,PI*.5);
}

return _st;
}
float circle(in vec2 _st, in float _radius){
vec2 dist = _st-vec2(0.5);
dot(dist,dist)*4.0);
}
void main (void) {
vec2 st = gl_FragCoord.xy/u_resolution.xy;
st = tile(st,1.0);
st = rotate2D(st,-PI*abs(sin(u_time*.01)));
st = rotateTilePattern(st*1.);
st = rotate2D(st,PI*u_time*.011);
st = tile(st,1.5);
st = brickTile(st,2.0);
st = rotateTilePattern(st);
vec3 color = vec3(step(st.x,st.y));
vec3 color2 = vec3(circle(st,0.5));
vec3 color3 = step(color,color2);
vec3 color4=mix(vec3(color),vec3(color2),color3);

st = tile(st,2.0);

gl_FragColor = vec4(color4,1.0);

}
```