Week 8 Homework

Life is pretty hectic right now, sorry for the delay in getting to this!

Here’s a sketch that explores the rotate and translate functions:
https://editor.p5js.org/nicoleannevella/sketches/C_zaN7RZk

JS Code:

let d, a = 0;

function setup() {
  createCanvas(windowWidth, windowHeight, WEBGL);
  noStroke();
  background(0);
  colorMode(HSB, 360, 100, 100);
}

function draw() {
  rotateX(a/QUARTER_PI);
  rotateY(a/HALF_PI);
  rotateZ(a/PI);

  fill(frameCount % 360, 35, 100, 100);
  translate(cos(a)*250, sin(a)*250);

  d=tan(a)*(width/12);
  sphere(d);
  
  a+= 0.015;
}

Here’s a sketch that attempts to do the same but with moving a camera object:
https://editor.p5js.org/nicoleannevella/sketches/CE3m6hUmo

JS Code:

// camera object and position
let cam;
let camPos;

// set min and max depth of field
let maxdof = 1500;
let mindof = 1;

let a = 0; // angle used for cos/sin animations

function setup() {
  createCanvas(windowWidth, windowHeight, WEBGL);
  
  // use the HSB coloe mode because it makes most sense to me
  colorMode(HSB, 360, 100, 100);

  // init our camera and use a vector for its position
  cam = createCamera();
  camPos = createVector();
  
  // strokes can be ugly sometimes, lets not use one
  noStroke();
}

function draw() {

  // animate the fov with cos() by an increasing angle value
  let fov = cos(a)*2;
  let aspect = width / height;

  // animate the camera look at positions using the same
  // increasing angle value and some cos/sin functions
  // if we divide the angle by some number we can add
  // a sense of "randomness" to it
  let camLookX = cos(a) * sin(a / HALF_PI) * maxdof * 0.1;
  let camLookY = cos(a) * sin(a / PI) * maxdof * 0.1;
  let camLookZ = cos(a) * sin(a / QUARTER_PI) * maxdof * 0.1;

  // set the perspective, position, and lookAt for our 3D camera
  cam.perspective(fov, aspect, mindof, maxdof);
  cam.setPosition(cos(a) * maxdof, 0, -10);
  cam.lookAt(camLookX, camLookY, camLookZ);

  // animate that fill nicely with the Hue based on framecount
  fill(frameCount % 360, 35, 100, 100);

  // draw a sphere
  sphere(10);
  
  // the magic value used to caluclate cos/sin that's resposible for all our animations
  a += 0.015;
}

Here’s a sketch where I add my liquid gold frag shader to the blob obj file that Jeremy made in Blender. Hope it’s ok that I stole your .obj (obviously I am going to try to get my delicious gold involved somehow).

Getting my gold fragment shader to map onto the 3D object was not trivial. I had to try out all the possible mappings like vEyePosition, vModelView, etc … I set the st to vScreenPosition.xy/vNormal.xy and that showed progress.

The larger issue was how to get my circles drawn in the right place. As it’s no longer a vec2, but a vec3. So, in the drawCircle function, I had to add the three xyz values of vNormal to get it to draw correctly onto the shape.

#define drawCircle(st,pos,size)smoothstep(0.,5./(vNormal.x+vNormal.y+vNormal.z),size-length(pos-st))

https://editor.p5js.org/nicoleannevella/sketches/sEj2HwGv3

Frag Shader Code:

#ifdef GL_ES
precision mediump float;
#endif
  
uniform float uTime;

varying vec3 vScreenPosition;
varying vec3 vNormal;

#define drawCircle(st,pos,size)smoothstep(0.,5./(vNormal.x+vNormal.y+vNormal.z),size-length(pos-st))

#define PI 3.14159265358979323846
#define TWO_PI 6.283185307179586
#define BUTTER TWO_PI/TWO_PI/TWO_PI/TWO_PI/TWO_PI/TWO_PI

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

void main() {
  
    vec2 st=vScreenPosition.xy/vNormal.xy;
    st.y=vScreenPosition.x/vScreenPosition.y;
  
    st.x/=snoise(st+vec2(uTime*BUTTER,0.))*.5+.5;
  
    float cs=snoise(st+uTime*BUTTER)*.5+.5;
  
    float circ=drawCircle(st,vec2(.5),cs*TWO_PI);
    
    vec3 red  =vec3(1.0,0.0,0.0);
    vec3 green=vec3(0.0,1.0,0.0);
    vec3 blue =vec3(0.0,0.0,1.0);
  
    vec3 color = vec3(0.0);
  
    color+=mix(color,red,circ);
    color+=mix(color,green,circ);
    color+=mix(color,blue,circ);
  
    gl_FragColor = vec4(color, 1.0);
}

As a bonus, I added audio reactivity:
https://nicolevella.com/_beta/shaders/goldblob/

Leave a Reply