Week 5

I worked with Nicole Vella for this week’s homework.

This one which resembles a diffractive glass wall (or kind of like tiny glass brick) is achieved by creating a large grid (with tiny units) where each grid unit has its webcam image shifted slightly to focus on the part where it lies in the greater grid. A brownian noise was added on top by Nicole and then I also added an interactive “clear” spot that can be moved by the mouse. View on p5 here

screenshot-2021-02-22-054756

precision mediump float;

// lets grab texcoords just for fun
varying vec2 vTexCoord;

// our texture coming from p5
uniform sampler2D tex0;
uniform float time;
uniform vec2 uMousePos;

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

float result = distance( st, pos);
result = smoothstep( result, result + 0.1 * (sin(time* 2.) * 0.5 + 0.5), 0.15);

return result;
}

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

st *= grid;

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

return st;
}

void main() {

vec2 uv = vTexCoord;
// the texture is loaded upside down and backwards by default so lets flip it
uv = 1.0 - uv;
vec2 st = uv;
vec2 test = uv;
vec2 indices;
st = createGrid(st, vec2(100.), indices);

float n=snoise(vTexCoord+time*0.3)*.5+.5;

// add the distortion to our texture coordinates
vec4 tex = texture2D(tex0, uv + st / 9. * n);
float c = drawCircle(test, uMousePos, 0.05);

vec2 toCenter = vec2(0.5)-st;
float angle = atan(toCenter.y,toCenter.x);
float radius = length(toCenter)*2.0;
float z = radius * 10.*sin(time/1.+ atan(st.y, st.x));

vec4 originalTex = texture2D(tex0, test);
tex = mix(tex, originalTex, c);

gl_FragColor = tex;
}

The second randomly samples a gridded colour palette to create multiple moving shapes which are then mixed using brownian motion.
The grid size of the palette needs to be specified, and it will generate a different result every time. View on p5 here

screenshot-2021-02-17-220830
palette

screenshot-2021-02-22-055437

precision mediump float;

// lets grab texcoords just for fun
varying vec2 vTexCoord;

// our texture coming from p5
uniform sampler2D u_tex0;
uniform float u_time;
uniform vec2 u_mouse;
uniform vec2 u_resolution;
uniform vec2 randCoord1;
uniform vec2 randCoord2;
uniform vec2 randCoord3;
uniform vec2 randCoord4;
uniform vec2 randCoord5;
uniform vec2 randCoord6;
uniform vec2 randCoord7;
uniform float gridSize;

float random (in vec2 st) {
return fract(sin(dot(st.xy,
vec2(12.9898,78.233)))*
43758.5453123);
}

// Based on Morgan McGuire @morgan3d
// https://www.shadertoy.com/view/4dS3Wd
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));

vec2 u = f * f * (3.0 - 2.0 * f);

return mix(a, b, u.x) +
(c - a)* u.y * (1.0 - u.x) +
(d - b) * u.x * u.y;
}

#define OCTAVES 6
float fbm (in vec2 st) {
// Initial values
float value = 0.0;
float amplitude = .5;
float frequency = 0.;
//
// Loop of octaves
for (int i = 0; i < OCTAVES; i++) {
value += amplitude * noise(st);
st *= 2.;
amplitude *= .5;
}
return value;
}

float drawCircle(in vec2 st, in float radius, vec2 pos){
vec2 dist = st-vec2(pos);
return 1.-smoothstep(radius-(radius*0.01),
radius+(radius*0.01),
dot(dist,dist)*4.0);
}

float drawBlurryCircle(in vec2 st, in float radius, vec2 pos){
vec2 dist = st-vec2(pos);
return 1.-smoothstep(radius-(radius*0.3),
radius+(radius*0.1),
dot(dist,dist)*4.0);
}

vec4 sampleRandomColour(vec2 randCoord, vec2 uv) {
// set up uv fields to sample colours from the image grid. divide by the cells per side so that it 'zooms' up on one colour
vec2 colourField = uv / gridSize;
// the coords provided need to be normalized
// to shift the canvas the right amount
// to focus on a single random colour
colourField += randCoord / gridSize;
// sample the colour from the image texture
return texture2D(u_tex0, colourField);
}

void main() {

vec2 uv = vTexCoord;

// flip because it's backwards
uv.y = 1.0 - uv.y;

vec4 colour;

vec4 colour1 = sampleRandomColour(randCoord1, uv);
vec4 colour2 = sampleRandomColour(randCoord2, uv);
vec4 colour3 = sampleRandomColour(randCoord3, uv);
vec4 colour4 = sampleRandomColour(randCoord4, uv);
vec4 colour5 = sampleRandomColour(randCoord5, uv);
vec4 colour6 = sampleRandomColour(randCoord6, uv);
vec4 colour7 = sampleRandomColour(randCoord7, uv);

uv += fbm(uv * 3.0);
uv -= 0.3;
uv /= 2.;

vec2 circleField = uv;
circleField.y += sin(sin(u_time) * uv.x * 20.) * 0.1;

float c = drawBlurryCircle(circleField, 0.3, vec2(0.3 + (sin(u_time) *0.5 + 0.5) * 0.2, 0.4));

vec2 circleField2 = uv;
circleField2.x *= 2.0;
circleField2.x += cos(sin(u_time / 4.) * uv.x * 100.) * 0.1;
float c2 = drawBlurryCircle(circleField2, 0.3, vec2(0.5 + (sin(u_time) *0.5 + 0.5) * 0.2, 0.6));

vec2 circleField3 = uv;
circleField3.x *= 3.0;
circleField3.y += sin(sin(u_time / 6.) * uv.x * 50.) * 0.1;
float c3 = drawBlurryCircle(circleField3, 0.7, vec2(0.1 + (sin(u_time) *0.5 + 0.5), 0.8 - (sin(u_time)*0.5 + 0.5)));

vec2 circleField4 = uv;
circleField4.y *= 5.0;
circleField4.x += sin(cos(u_time / 6.) * uv.x * 50.) * 0.1;
float c4 = drawBlurryCircle(circleField4, 0.2, vec2(0.3 + (sin(u_time) *0.5 + 0.5), 0.7 + (sin(u_time)*0.5 + 0.5)));

vec2 circleField5 = uv;
circleField5.y *= 5.0;
circleField5.x += sin(cos(u_time / 3.) * uv.x * 50.) * 0.1;
float c5 = drawCircle(circleField5, 0.4, u_mouse + vec2(0.0, 1.0));

colour = mix(colour1, colour2, dot(uv.x * 2., uv.y * 2.));
colour = mix(colour, colour3, c3);
colour = mix(colour, colour4, c);
colour = mix(colour, colour5, c2);
colour = mix(colour, colour6, c4);
colour = mix(colour, colour7, c5);

gl_FragColor = colour;
}

One thought on “Week 5”

Leave a Reply