Example #1
0
resl({
  manifest: {
    texture: {
      type: 'image',
      src: sat8x8pnguri,
      parser: (data) => regl.texture({
        data: data,
        mag: 'nearest',
        min: 'nearest',
        flipY: true
      })
    }, digitsTexture: {
      type: 'image',
      src: numerify.digits.uri,
      parser: (data) => regl.texture({
        data: data,
        mag: 'nearest',
        min: 'nearest',
        flipY: true
      })
    }
  },
  onDone: ({texture, digitsTexture}) => {
    // make a bunch of fbos for ping-ponging intermediate computations, and the output buffer etc.
    let fbos = [null, null, null, null].map(function () {
      return regl.framebuffer({
        color: regl.texture({
          width: texture.width,
          height: texture.height,
          stencil: false,
          format: 'rgba',
          type: 'float',
          depth: false,
          wrap: 'clamp',
          mag: 'nearest',
          min: 'nearest'
        }),
        stencil: false,
        depth: false,
        depthStencil: false,
        wrap: 'clamp',
        mag: 'nearest',
        min: 'nearest'
      });
    });

    // use one FBO for the output.
    let outFbo = fbos.pop();

    // and another for the input, for later use.
    let inFbo = fbos.pop();

    computeSat({texture: texture, fbos: fbos, outFbo: outFbo, regl, components: 'rgb', type: 'vec3'});

    let upscaledCellWidth = 32;
    let upscaledCellHeight = 32;
    let upscaledWidth = texture.width * Math.max(upscaledCellWidth, upscaledCellHeight);
    let upscaledHeight = texture.height * Math.max(upscaledCellWidth, upscaledCellHeight);

    // a command to take an input texture and "numerify" it and place it in a destination FBO.
    const drawNumbersToFbo = regl({
      frag: numerify.makeFrag({ multiplier: 256.0,
                                sourceSize: `vec2(${texture.width}, ${texture.height})`,
                                destinationCellSize: `vec2(${upscaledCellWidth - 1}, ${upscaledCellHeight - 1})`,
                                destinationSize: `vec2(${upscaledWidth}, ${upscaledHeight})`,
                                component: 'r'}),
      vert: numerify.makeVert(),
      attributes: {
        a_position: quad.verts,
        a_uv: quad.uvs
      },
      elements: quad.indices,
      uniforms: {
        digits_texture: digitsTexture,
        source_texture: regl.prop('texture'),
        u_clip_y: 1
      },
      framebuffer: regl.prop('fbo')
    });

    // allocate two FBOS to store the numerified textures.
    let numbersFBOs = [null, null].map(function () {
      return regl.framebuffer({
        color: regl.texture({
          width: upscaledWidth,
          height: upscaledHeight,
          stencil: false,
          format: 'rgba',
          type: 'uint8',
          depth: false,
          wrap: 'clamp',
          mag: 'nearest',
          min: 'nearest'
        })
      });
    });

    // one FBO to store the input texture as a numerified texture.
    let inNumbersFBO = numbersFBOs[0];
    // and a second FBO to store the SAT result texture as a numerified texture.
    let outNumbersFBO = numbersFBOs[1];

    // copy the input texture to the `inFbo`.
    drawTextureToFbo({texture, fbo: inFbo});
    // "numerify" the input texture.
    drawNumbersToFbo({texture: inFbo.color[0], fbo: inNumbersFBO});
    // "numerify" the SAT result texture.
    drawNumbersToFbo({texture: outFbo.color[0], fbo: outNumbersFBO});

    // draw the stuff to img tags, and put everything into the DOM for display.

    let $srcDiv = $('<div class="source-images"></div>').css('text-align', 'center').appendTo('body');
    $('<h3>').appendTo($srcDiv).css('text-align', 'center').text('Source image (upscaled)');

    let $resultDiv = $('<div class="result-images"></div>').css('text-align', 'center').appendTo('body');
    $('<h3>').appendTo($resultDiv).css('text-align', 'center').text('Result image (upscaled)');

    function figureTemplate ({src, captionHtml = '', alt = ''}) {
      return `
      <figure>
        <img src="${src}" alt="${alt}">
        <figcaption>${captionHtml}</figcaption>
      </figure>
      `;
    }

    let $srcImg = $.parseHTML(figureTemplate({src: dataURIFromFBO({fbo: inFbo, width: upscaledWidth, height: upscaledHeight, regl}),
                                               alt: 'Source image (Rescaled)',
                                               captionHtml: '<strong>Source image (Rescaled)</strong>'}));
    let $srcNumbersImg = $.parseHTML(figureTemplate({src: dataURIFromFBO({fbo: inNumbersFBO, width: upscaledWidth, height: upscaledHeight, regl}),
                                                      alt: 'Source image numerified red',
                                                      captionHtml: '<strong>Source image, numerified red</strong>'}));
    let $satImg = $.parseHTML(figureTemplate({src: dataURIFromFBO({fbo: outFbo, width: upscaledWidth, height: upscaledHeight, regl}),
                                               alt: 'Result SAT image (Rescaled)',
                                               captionHtml: '<strong>Result SAT image (Rescaled)</strong>'}));
    let $satNumbersImg = $.parseHTML(figureTemplate({src: dataURIFromFBO({fbo: outNumbersFBO, width: upscaledWidth, height: upscaledHeight, regl}),
                                                      alt: 'Result SAT image numerified red',
                                                      captionHtml: '<strong>Result SAT image, numerified red</strong>'}));

    $($srcImg).css('display', 'inline-block').appendTo($srcDiv);
    $($srcNumbersImg).css('display', 'inline-block').appendTo($srcDiv);
    $($satImg).css('display', 'inline-block').appendTo($resultDiv);
    $($satNumbersImg).css('display', 'inline-block').appendTo($resultDiv);
  }
});
resl({
  manifest: {
    texture: {
      type: 'image',
      // src: 'docs/numerify-4x4-exemplar.png',
      src: 'data:image/png;base64,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',
      parser: (data) => regl.texture({
        data: data,
        mag: 'nearest',
        min: 'nearest',
        flipY: true
      })
    }, digitsTexture: {
      type: 'image',
      src: numerify.digits.uri,
      parser: (data) => regl.texture({
        data: data,
        mag: 'nearest',
        min: 'nearest',
        flipY: true
      })
    }
  },
  onDone: ({texture, digitsTexture}) => {
    // console.log(texture.width);
    // console.log(digitsTexture.width);

    let fbo = makeFBORgbUint8({width: texture.width * 16, height: texture.height * 16});

    let frag = numerify.makeFrag({ multiplier: 256,
                                   sourceSize: `vec2(${texture.width}, ${texture.height})`,
                                   destinationSize: `vec2(${texture.width * 16}, ${texture.height * 16})`,
                                   destinationCellSize: 'vec2(16, 16)'});
    let vert = numerify.makeVert();

    console.log('vert:', vert);
    console.log('frag:', frag);

    const numerifyToFBO = regl({
      frag: frag,
      vert: vert,
      attributes: {
        a_position: quad.verts,
        a_uv: quad.uvs
      },
      elements: quad.indices,
      uniforms: {
        source_texture: regl.prop('sourceTexture'),
        digits_texture: regl.prop('digitsTexture'),
        u_clip_y: regl.prop('clip_y')
      },
      framebuffer: regl.prop('fbo')
    });

    numerifyToFBO({ sourceTexture: texture,
                    digitsTexture: digitsTexture,
                    fbo: fbo,
                    clip_y: 1});

    drawToScreen({texture: fbo.color[0], clip_y: 1});
  }
});
Example #3
0
var regl = require('regl')()
var camera = require('regl-camera')(regl, {
  distance: 2, center: [0,0.5,0]
})
var resl = require('resl')

resl({
  manifest: {
    bliss: { type: 'image', src: 'bliss.jpg' }
  },
  onDone: ready
})

function ready (assets) {
  var draw = {
    feedback: require('regl-feedback')(regl, `
      vec3 sample (vec2 uv, sampler2D tex) {
        vec2 tpos = ((2.0*uv-1.0)+1.0)*0.5;
        vec2 p = vec2(
          cos(tpos.x*${2*Math.PI}*16.0)
            + cos(tpos.x*${2*Math.PI}*4.0)
            + cos(tpos.x*${2*Math.PI}*8.0)
            + sin(tpos.x*${2*Math.PI}*64.0),
          sin(tpos.y*${2*Math.PI}*16.0)
            + sin(tpos.y*${2*Math.PI}*4.0)
            + sin(tpos.y*${2*Math.PI}*8.0)
            + cos(tpos.y*${2*Math.PI}*64.0)
        ) * 0.004;
        return 0.999*texture2D(tex,tpos+p).rgb;
      }
    `),
resl({
  manifest: {
    texture: {
      type: 'image',
      src: './assets/Storm Cell Over the Southern Appalachian Mountains-dsc_2303_0-256x256.png',
      parser: (data) => regl.texture({
        data: data,
        mag: 'nearest',
        min: 'nearest',
        flipY: true
      })
    }
  },
  onDone: ({texture, digitsTexture}) => {
    // make a bunch of fbos for ping-ponging intermediate computations, and the output buffer etc.
    let fbos = [null, null, null, null].map(function () {
      return regl.framebuffer({
        color: regl.texture({
          width: texture.width,
          height: texture.height,
          stencil: false,
          format: 'rgba',
          type: 'float',
          depth: false,
          wrap: 'clamp',
          mag: 'nearest',
          min: 'nearest'
        }),
        stencil: false,
        depth: false,
        depthStencil: false,
        wrap: 'clamp',
        mag: 'nearest',
        min: 'nearest'
      });
    });

    // use one FBO for the output.
    let outFbo = fbos.pop();

    // and another for the input, for later use.
    let inFbo = fbos.pop();

    let radius = 1;
    gaussian.blur.gaussian.compute({regl, texture, radius, fbos, outFbo: outFbo, components: 'rgb', type: 'vec3'});

    let upscaledCellWidth = 16;
    let upscaledCellHeight = 16;
    let upscaledWidth = texture.width * Math.max(upscaledCellWidth, upscaledCellHeight);
    let upscaledHeight = texture.height * Math.max(upscaledCellWidth, upscaledCellHeight);

    // copy the input texture to the `inFbo`.
    drawTextureToFbo({texture, fbo: inFbo});

    // draw the stuff to img tags, and put everything into the DOM for display.

    let $srcDiv = $('<div class="source-images"></div>').css('text-align', 'center').appendTo('body');
    $('<h3>').appendTo($srcDiv).css('text-align', 'center').text('Source image');

    let $resultDiv = $('<div class="result-images"></div>').css('text-align', 'center').appendTo('body');
    $('<h3>').appendTo($resultDiv).css('text-align', 'center').text('Result image');

    function figureTemplate ({src, captionHtml = '', alt = ''}) {
      return `
      <figure>
        <img src="${src}" alt="${alt}">
        <figcaption>${captionHtml}</figcaption>
      </figure>
      `;
    }

    upscaledWidth = texture.width;
    upscaledHeight = texture.height;

    let $srcImg = $.parseHTML(figureTemplate({src: dataURIFromFBO({fbo: inFbo, width: upscaledWidth, height: upscaledHeight, regl}),
                                               alt: 'Source image',
                                               captionHtml: '<strong>Source image</strong>'}));
    // let $srcNumbersImg = $.parseHTML(figureTemplate({src: dataURIFromFBO({fbo: inNumbersFBO, width: upscaledWidth, height: upscaledHeight, regl}),
    //                                                   alt: 'Source image numerified red',
    //                                                   captionHtml: '<strong>Source image, numerified red</strong>'}));
    let $resultImg = $.parseHTML(figureTemplate({src: dataURIFromFBO({fbo: outFbo, width: upscaledWidth, height: upscaledHeight, regl}),
                                               alt: 'Result blurred image',
                                               captionHtml: `<strong>Result blurred image (kernel radius of ${radius})</strong>`}));
    // let $resultNumbersImg = $.parseHTML(figureTemplate({src: dataURIFromFBO({fbo: outNumbersFBO, width: upscaledWidth, height: upscaledHeight, regl}),
    //                                                   alt: 'Result blurred image numerified red',
    //                                                   captionHtml: '<strong>Result blurred image, numerified red</strong>'}));

    $($srcImg).css('display', 'inline-block').appendTo($srcDiv);
    // $($srcNumbersImg).css('display', 'inline-block').appendTo($srcDiv);
    $($resultImg).css('display', 'inline-block').appendTo($resultDiv);
    // $($resultNumbersImg).css('display', 'inline-block').appendTo($resultDiv);
  }
});
resl({
  manifest: {
    texture: {
      type: 'image',
      src: 'https://raw.githubusercontent.com/realazthat/glsl-gaussian/master/assets/Storm%20Cell%20Over%20the%20Southern%20Appalachian%20Mountains-dsc_2303_0-256x256.png',
      parser: (data) => regl.texture({
        data: data,
        mag: 'nearest',
        min: 'mipmap',
        flipY: true,
        mipmap: 'nice'
      })
    }
  },
  onDone: ({texture}) => {
    
    let L = Math.ceil(Math.max(Math.log2(texture.width), Math.log2(texture.height)));
  
    function makeUint8Fbo ({width, height}) {
      return regl.framebuffer({
        color: regl.texture({
          width: width,
          height: height,
          stencil: false,
          format: 'rgba',
          type: 'uint8',
          depth: false,
          wrap: 'clamp',
          mag: 'nearest',
          min: 'nearest'
        }),
        width: width,
        height: height,
        depth: false,
        stencil: false,
        depthStencil: false,
        depthTexture: false,
        colorType: 'uint8',
        colorFormat: 'rgba'
      });
    }
  
    let scaledFbos = range(L + 1).map(function (level) {
      // level 1 should have a mipmap size of 2^(L-1)
      // level 2 should have a mipmap size of 2^(L-2)
      let mipmapSize = 1 << (L - level);

      return makeUint8Fbo({width: mipmapSize, height: mipmapSize});
    });
  
    for (let levelZeroOnly of [false, true]) {
      for (let level = 1; level < L + 1; ++level) {
        // level 1 should have a mipmap size of 2^(L-1)
        // level 2 should have a mipmap size of 2^(L-2)
        let mipmapSize = 1 << (L - level);

        let scaledFbo = scaledFbos[level];
        extractMiplevel({texture, regl, outFbo: scaledFbo, level: levelZeroOnly ? 0 : level});
      }


      let viewport = {
        x: levelZeroOnly ? 0 : 1 << L,
        y: 0,
        width: 1 << L,
        height: 1 << L
      };
      for (let level = 1; level < L + 1; ++level) {
        let lastMipmapSize = 1 << (L - (level - 1));
        let mipmapSize = 1 << (L - level);

        viewport.y += lastMipmapSize;
        viewport.width = mipmapSize;
        viewport.height = mipmapSize;
        draw({
          texture: scaledFbos[level].color[0],
          viewport: viewport
        });
      }
    }
  }
});