html5 canvas - Compose an image with floating point layers in webgl -


i have trying render image in browser built this:

  • a bunch of rectangles each filled radial gradient (ideally gaussian, can approximated few stopping points
  • each rectangle rotated , translated before being deposited on drawing area

  • the image flattened summing intensities of rectangles (and cropping drawing area's dimensions )

  • the intensity rescaled highest intensity 255 , lowest 0 (ideally can apply sort of gamma correction too)

  • finally image drawn color of each pixel taken palette of 256 colors.

the reason cannot canvas object need working in floating points or i'll lose precision. not know in advance maximum intensity , minimum intensity be, cannot merely draw transparent rectangles , hope best.

is there way in webgl? if so, how go it?

you can use regular canvas perform task :

1) check min/max of rects, can build mapping function double -> [0-255] out of range.

2) draw rects in 'lighter' mode == add component values.

3) might have saturation when several rects overlaps : if so, double mapping range , go 2).
if don't have saturation adjust range use full [0-255] range of canvas, , you're done.

since algorithm makes use of getimagedata, might not reach 60 fps on browsers/devices. more 10fps on desktop/chrome seems possible.

hopefully code below clarify description :

//noprotect  // boilerplate  var cv = document.getelementbyid('cv');  var ctx = cv.getcontext('2d');    // rectangle collection  var rectcount = 30;  var rects = buildrandrects(rectcount);      iteratetomax();      // --------------------------------------------    function iteratetomax() {      var limit = 10; // loop protection      // initialize min/max mapping based on rects min/max      updatemapping(rects);      //      while (true) {          // draw scene using current mapping          drawscene();          // max int value canvas          var max = getmax();          if (max == 255) {              // saturation ?? double min-max interval              globalmax = globalmin + 2 * (globalmax - globalmin);          } else {              // no sauration ? adjust min-max interval              globalmax = globalmin + (max / 255) * (globalmax - globalmin);              drawscene();              return;          }          limit--;          if (limit <= 0) return;      }  }    // --------------------------------------------  // --------------------------------------------    // oriented rectangle class.  function rect(x, y, w, h, rotation, min, max) {      this.min = min;      this.max = max;      this.draw = function () {          ctx.save();          ctx.fillstyle = createradialgradient(min, max);          ctx.translate(x, y);          ctx.rotate(rotation);          ctx.scale(w, h);          ctx.fillrect(-1, -1, 2, 2);          ctx.restore();      };      var = this;        function createradialgradient(min, max) {          var gd = ctx.createradialgradient(0, 0, 0, 0, 0, 1);          var start = map(that.min);          var end = map(that.max);          gd.addcolorstop(0, 'rgb(' + start + ',' + start + ',' + start + ')');          gd.addcolorstop(1, 'rgb(' + end + ',' + end + ',' + end + ')');          return gd;      }  }    // mapping : float value -> 0-255 value  var globalmin = 0;  var globalmax = 0;    function map(value) {      return 0 | (255 * (value - globalmin) / (globalmax - globalmin));  }    // create initial mapping   function updatemapping(rects) {      globalmin = rects[0].min;      globalmax = rects[0].max;      (var = 1; < rects.length; i++) {          var thisrect = rects[i];          if (thisrect.min < globalmin) globalmin = thisrect.min;          if (thisrect.max > globalmax) globalmax = thisrect.max;      }  }    // random rect collection  function buildrandrects(rectcount) {      var rects = [];      (var = 0; < rectcount; i++) {          var thismin = math.random() * 1000;          var newrect = new rect(math.random() * 400, math.random() * 400, 10 + math.random() * 50, 10 + math.random() * 50, math.random() * 2 * math.pi, thismin, thismin + math.random() * 1000);          rects.push(newrect);      }      return rects;  }    // draw rects in 'lighter' mode (=sum values)  function drawscene() {      ctx.save();      ctx.globalcompositeoperation = 'source-over';      ctx.clearrect(0, 0, cv.width, cv.height);      ctx.globalcompositeoperation = 'lighter';      (var = 0; < rectcount; i++) {          var thisrect = rects[i];          thisrect.draw();      }      ctx.restore();  }      // maximum value r canvas   //   ( == max r, g, b value gray-only drawing. )  function getmax() {      var data = ctx.getimagedata(0, 0, cv.width, cv.height).data;      var max = 0;      (var = 0; < data.length; += 4) {          if (data[i] > max) max = data[i];          if (max == 255) return 255;      }      return max;  }
<canvas id='cv' width = 400 height = 400></canvas>


Comments

Popular posts from this blog

c++ - Difference between pre and post decrement in recursive function argument -

php - Nothing but 'run(); ' when browsing to my local project, how do I fix this? -

php - How can I echo out this array? -