<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>P5.treegl on blog</title>
    <link>https://jpcharalambosh.co/tags/p5.treegl/</link>
    <description>Recent content in P5.treegl on blog</description>
    <image>
      <title>blog</title>
      <url>https://jpcharalambosh.co/papermod-cover.png</url>
      <link>https://jpcharalambosh.co/papermod-cover.png</link>
    </image>
    <generator>Hugo</generator>
    <language>en</language>
    <lastBuildDate>Sat, 02 Sep 2023 15:07:24 -0500</lastBuildDate>
    <atom:link href="https://jpcharalambosh.co/tags/p5.treegl/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>GPU-based Photomosaic</title>
      <link>https://jpcharalambosh.co/posts/photomosaic/</link>
      <pubDate>Sat, 02 Sep 2023 15:07:24 -0500</pubDate>
      <guid>https://jpcharalambosh.co/posts/photomosaic/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This demo visualization shows a &lt;a href=&#34;https://en.wikipedia.org/wiki/Photographic_mosaic&#34;&gt;photomosaic (&amp;amp; videomosaic)&lt;/a&gt; implemented in hardware:&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;(press &lt;code&gt;r&lt;/code&gt; to randomly pick another painting)&lt;br&gt;














&lt;iframe
  id=&#34;&#34;
  style=&#34;width:675px; height:675px&#34;
  srcdoc=&#34;
        &lt;!DOCTYPE html&gt;
        &lt;html&gt;
          &lt;head&gt;
            &lt;script src=&#39;https://cdn.jsdelivr.net/npm/p5@1.11.10/lib/p5.min.js&#39;&gt;&lt;/script&gt;
            
            &lt;script src=&#39;https://cdn.jsdelivr.net/gh/VisualComputing/p5.treegl/p5.treegl.min.js&#39;&gt;&lt;/script&gt;
            
            
            
            &lt;script src=https://cdn.jsdelivr.net/gh/objetos/p5.quadrille.js/p5.quadrille.min.js&gt;&lt;/script&gt;
            
            
            
            
            &lt;script&gt;
              
&amp;#39;use strict&amp;#39;
let palette
let fbo
let mosaic
let src
let paintings
let video_src
// ui
let resolution
let video_on
let uv
let mode

// MAX_TEXTURE_SIZE seem to be 4096 in my firefox (others don&amp;#39;t complain)
// see: https://t.ly/k7E_
// palette.width -&amp;gt; n * SAMPLE_RES
// 120 wasn&amp;#39;t disliked before
const SAMPLE_RES = navigator.userAgent.includes(&amp;#39;Firefox&amp;#39;) ? 65 : 150

function preload() {
  video_src = createVideo([&amp;#39;wagon.webm&amp;#39;])
  video_src.hide()
  mosaic = readShader(&amp;#39;mosaic.frag&amp;#39;)
  paintings = []
  for (let i = 1; i &amp;lt;= 30; i&amp;#43;&amp;#43;) {
    paintings.push(loadImage(`p${i}.jpg`))
  }
}

function setup() {
  createCanvas(650, 650, WEBGL)
  textureMode(NORMAL)
  noStroke()
  resolution = createSlider(1, 200, 40, 1)
  resolution.position(10, 35)
  resolution.style(&amp;#39;width&amp;#39;, &amp;#39;80px&amp;#39;)
  video_on = createCheckbox(&amp;#39;video&amp;#39;, false)
  video_on.style(&amp;#39;color&amp;#39;, &amp;#39;magenta&amp;#39;)
  video_on.changed(() =&amp;gt; {
    src = video_on.checked() ? video_src : random(paintings)
    video_on.checked() ? video_src.loop() : video_src.pause()
  })
  video_on.position(10, 55)
  src = random(paintings)
  uv = createCheckbox(&amp;#39;uv visualization&amp;#39;, false)
  uv.style(&amp;#39;color&amp;#39;, &amp;#39;magenta&amp;#39;)
  uv.position(10, 70)
  mode = createSelect()
  mode.position(10, 90)
  mode.option(&amp;#39;original&amp;#39;)
  mode.option(&amp;#39;keys&amp;#39;)
  mode.option(&amp;#39;symbols&amp;#39;)
  mode.selected(&amp;#39;symbols&amp;#39;)
  mode.changed(() =&amp;gt; mode.value() === &amp;#39;original&amp;#39; ? resolution.hide() : resolution.show())
  palette = createQuadrille(paintings)
  fbo = createFramebuffer({ width: SAMPLE_RES * palette.width, height: SAMPLE_RES, format: FLOAT })
  sample()
}

function sample() {
  palette.sort({ ascending: true, cellLength: SAMPLE_RES })
  fbo.begin()
  //resetShader()
  drawQuadrille(palette, { cellLength: SAMPLE_RES, outlineWeight: 0, x: -SAMPLE_RES * palette.width / 2, y: -SAMPLE_RES * palette.height / 2 })
  fbo.end()
}

function draw() {
  applyShader(mosaic, {
    uniforms: {
      source: src,
      palette: fbo.color,
      n: palette.width,
      resolution: resolution.value(),
      uv: uv.checked(),
      keys: mode.value() === &amp;#39;keys&amp;#39;,
      original: mode.value() === &amp;#39;original&amp;#39;
    }
  })
}

function keyPressed() {
  if (key === &amp;#39;r&amp;#39; &amp;amp;&amp;amp; !video_on.checked()) {
    src = random(paintings)
  }
}

            &lt;/script&gt;
          &lt;/head&gt;
          &lt;body&gt;
          &lt;/body&gt;
        &lt;/html&gt;
      &#34;
&gt;&lt;/iframe&gt;
&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
