drawParentToCanvas

← All Butter documentation
Parameters
drawParentToCanvas()

    NOTE: drawParentToCanvas is only available in WebGL mode.

    Like p5.js sketches, Butter components generally draw to their own blank canvas. If you clear it, you can see through to the content below. But other times, you don't just want to see the content, you want to read it and do something with it!

    In Butter, that's what drawParentToCanvas is for. When you call it, Butter takes a snapshot of the content below the component, and then draws that to your component's canvas. You can call it between the begin() and end() of a framebuffer if you need it stored. Here is an example that just draws it to the main canvas, and then applies a filter shader to it:

    let pixelate
    function setup() {
      createCanvas(windowWidth, windowHeight, WEBGL)
      pixelate = baseFilterShader().modify(() => {
        getColor((inputs, canvasContent) => {
          let numPixels = 20
          return getTexture(
            canvasContent,
            floor(inputs.texCoord * numPixels) /
              numPixels
          )
        })
      })
    }
    function draw() {
      clear()
      drawParentToCanvas()
      filter(pixelate)
    }
    

    For a more complex example, here the parent content is drawn to a framebuffer, and then sampled in a material shader to produce a glass orb effect:

    let refract
    let bg
    let amount
    function setup() {
      createCanvas(windowWidth, windowHeight, WEBGL)
      amount = createSlider(0, 100, 50, 0.1)
      bg = createFramebuffer()
      refract = baseMaterialShader().modify(() => {
        const bgTex =
          uniformTexture(() => bg)
        const bgSize =
          uniformVec2(() => [bg.width, bg.height])
        const refractDist =
          uniformFloat(() => amount.value() / 800)
        let position = sharedVec3()
        let normal = sharedVec3()
        getCameraInputs((inputs) => {
          position = inputs.position
          normal = inputs.normal
          return inputs
        })
        getFinalColor(() => {
          let toSurface = -normalize(position)
          let reflected = reflect(
            toSurface,
            normalize(normal)
          )
          let coord = position.xy / bgSize + 0.5
          coord += reflected.xy * refractDist
          return getTexture(bgTex, coord)
        })
      })
    }
    function draw() {
      clear()
      bg.draw(() => {
        clear()
        drawParentToCanvas()
      })
      push()
      noStroke()
      shader(refract)
      sphere(min(width, height) * 0.45)
      pop()
    }