Skip to content

Shiny Sphere

Experimenting with raytracing in p5.strands. Also seen in Chasing Shiny Things.

A yellow-gold sphere spins in a circle, reflecting light.

let myShader

function setup() {
  createCanvas(600, 600, WEBGL);
  // https://iquilezles.org/articles/simplegpurt/
  myShader = baseFilterShader().modify(() => {
    let sphereOrigin = uniformVector3(() => [cos(millis() / 1000) * 3, 0, sin(millis() / 1000) * 3]);
    let rayOrigin = uniformVector3(() => [0, 0, -10]);
    getColor((inputs, canvasContent) => {
      var rayDir = [inputs.texCoord.x - 0.5, inputs.texCoord.y - 0.5, 1] * 2
      rayDir = normalize(rayDir)
      //var lightDir = normalize([0.2, -1, -0.2])
      var lightPos = [5, -20, -4]
      var d = rayOrigin - sphereOrigin
      var b = dot(rayDir, d)
      var r = 1
      var c = dot(d,d) - r*r
      var t = b*b - c
      var dis = -b - sqrt(max(t, 0.0))
      
      // Can't use if...
      var cond = smoothstep(0.0, 0.08, t) * smoothstep(0.0, 0.08, dis)
      
      var hitPos = rayOrigin + rayDir * dis
      var lightDir = normalize(lightPos - hitPos)
      
      var nor = normalize(hitPos - sphereOrigin)
      var back = [0.8, 0.7, 0.4, 1]
      var amb = [1, 1, 1] * 0.3
      var lcol = [1, 1, 0] * 1
      var col = [1, 1, 1] * 0.5
      var spec = [1, 1, 1] * 0.5
      var res = col * (amb + lcol * max(dot(nor, lightDir), 0.0)) + spec * pow(max(dot(reflect(rayDir, nor), lightDir), 0.0), 4.0)
      return [res.xyz, 1] * cond + back * (1 - cond)
    });
  });
}

function draw() {
  filter(myShader);
}

(Originally seen at https://editor.p5js.org/bojidar-bg/sketches/PwFumWmKdo)

Experiments tagged p5 (47/85)

Experiments on this site (47/85)