How do I convert 2D Canvas to WEBGL?

Hi,

I was wondering if it's possible to convert a 2D sketch to a 3D WEBGL.

I gave it a shot by simply adding WEBGL at the end of createCanvas, but then I get a lot of P5.js errors

If you can't simply do this, then what is the easiest way to convert a 2D sketch to 3D?

I'm asking this because I'm having trouble with the performance of the sketch and I want to utilise the CPU to run it more smoothly

Tagged:

Answers

  • Case: Custom Mesh

    Send data CPU > GPU > Apply Materials > Render

    I think, it would help if you can create a minimal exampel, what you a tying to do and where the error ocours.

  • I've got a really simple sketch as an example that checks the amount of touches currently on the screen.

    background(51);
      fill(255);
      textSize(height/5);
      textAlign(CENTER);
      var touchesDown = 0;
      touchesDown = touches.length;
      text(touchesDown, width/2,height/2);
      for (var i = 0; i < touches.length; i++) {
        textSize(35);
        text(touches[i].x.toFixed(2) + ", " + touches[i].y.toFixed(2), touches[i].x, touches[i].y - 50);
      }
    

    The error I'm getting is: text commands not yet implemented in webgl p5.js:34308

  • edited May 2017

    @SaintPepsi

    Text rendering in raw WebGL would be an Image (a Bitmap, a uncompressed Texture). With some background knowledge, like VRAM and the intern process of unpacking from formats like *.jpeg *.png to raw WebGL >GPU readable format, you probably come to the conclusion, to have less Textures in your App is more performant. Since you only save the downloadtime with a 160kB *.jpg but unpacked to VRAM your Texture will have the full e.g 2MB again.

    And since text mostly used for UI Overlays, it is more common to use a second Canvas.

    I recomend to optimize your code! Try to split your tasks to different Canvas. You can create a second Canvas(2d) and draw the text on it.

    Hope this helps

    Best

  • So if I understand correctly, Having your main sketch draw in WEBGL mode but all your text elements drawn in in a 2d canvas improves performance overall? I'm still quite new to the whole canvas thing, i've done a lot of coding with it but haven't really come around to performance enhancement.

  • Hi again,

    I did a little test, I drew some circles on random locations and moved them across the screen, when WEBGL mode is on, after about 10 circles the sketch slows down dramatically almost to a halt, but without WEBGL i can do up to 511 circles before it slows down,

    Does WEBGL have issues running 2d elements?

  • edited May 2017

    @SaintPepsi

    I would like to see your Source (also please with createCavase draw etc.)

  • Hi sorry, Here's the code:

    var movers = [];
    
    function setup() {
      // WEBGL
      createCanvas(window.innerWidth, window.innerHeight, WEBGL);
    
      // non WEBGL
      // createCanvas(window.innerWidth, window.innerHeight);
    }
    
    function draw() {
      background(51);
      // non WEBGL
      // translate(width/2, height/2);
      for (var i = 0; i < movers.length; i++) {
        movers[i].update();
        movers[i].show();
      }
    }
    
    function mousePressed() {
      var temp = new Mover();
      movers.push(temp);
      var ml = movers.length;
      console.log(movers.length);
      for (var i = 0; i < ml; i++) {
        var temp = new Mover();
        movers.push(temp);
      }
    }
    
    function Mover() {
      this.pos = createVector(random(-(width/2) + 40, (width/2) - 40), random(-(height/2) + 40, (height/2) - 40));
      this.velocity = createVector(random(-2, 2), random(-2, 2));
    }
    
    Mover.prototype.update = function() {
      this.pos.add(this.velocity);
      if (this.pos.x > width/2) {
        this.pos.x = 0;
      }
      if (this.pos.y > height/2) {
        this.pos.y = 0;
      }
      if (this.pos.x < -(width/2)) {
        this.pos.x = width/2;
      }
      if (this.pos.y < -(height/2)) {
        this.pos.y = height/2;
      }
    }
    
    Mover.prototype.show = function() {
      // non WEBGL
      // fill(255);
      // ellipse(this.pos.x, this.pos.y, 25,25);
    
      // WEBGL
      push();
      translate(this.pos.x, this.pos.y);
      sphere(25);
      pop();
    }
    
  • edited May 2017

    For me they behave the same. Note: The WebGL Render -Canvas is ~4 times bigger and still i can get 'til 4095 Spheres where it starts to render really slow.

    @SaintPepsi What is your hardware ?

    Tested on:

    • Windows 10
    • Firefox 53.0.3 (32-Bit)
    • Intel(R) HD Graphics 630
  • Did you try doing the non WEBGL ellipse in WEBGL?

  • @SaintPepsi
    Yes both works great!

  • Send your scetch to a friend ! And ask for opinion

  • So you tried this:

    var movers = [];
    
    function setup() {
      // WEBGL
      createCanvas(window.innerWidth, window.innerHeight, WEBGL);
    
      // non WEBGL
      // createCanvas(window.innerWidth, window.innerHeight);
    }
    
    function draw() {
      background(51);
      // non WEBGL
      // translate(width/2, height/2);
      for (var i = 0; i < movers.length; i++) {
        movers[i].update();
        movers[i].show();
      }
    }
    
    function mousePressed() {
      var temp = new Mover();
      movers.push(temp);
      var ml = movers.length;
      console.log(movers.length);
      for (var i = 0; i < ml; i++) {
        var temp = new Mover();
        movers.push(temp);
      }
    }
    
    function Mover() {
      this.pos = createVector(random(-(width/2) + 40, (width/2) - 40), random(-(height/2) + 40, (height/2) - 40));
      this.velocity = createVector(random(-2, 2), random(-2, 2));
    }
    
    Mover.prototype.update = function() {
      this.pos.add(this.velocity);
      if (this.pos.x > width/2) {
        this.pos.x = 0;
      }
      if (this.pos.y > height/2) {
        this.pos.y = 0;
      }
      if (this.pos.x < -(width/2)) {
        this.pos.x = width/2;
      }
      if (this.pos.y < -(height/2)) {
        this.pos.y = height/2;
      }
    }
    
    Mover.prototype.show = function() {
      // non WEBGL
      fill(255);
      ellipse(this.pos.x, this.pos.y, 25,25);
    
      // WEBGL
      // push();
      // translate(this.pos.x, this.pos.y);
      // sphere(25);
      // pop();
    }
    

    Also my specs:

    Macbook Pro 13-inch model macOS Sierra v 10.12.5 2.0GHz dual-core Intel Core i5, Turbo Boost up to 3.1GHz, with 4MB shared L3 cache

  • Both on my mac and on my windows it gets really slow with the sketch shown in the previous comment.

  • @SaintPepsi

    Your Browser ?

  • Browser: Google Chrome

  • I think this is calling for a video

  • @SaintPepsi

    Okay this is really slow

  • You see what i'm doing? I'm rendering a 2D primitive in the WEBGL 3D environment. you'd think it would be an easy job since 3D objects require more math, but for some reason 2D objects slay the canvas.

  • edited May 2017

    Okay so you are trying to draw this way

    // non WEBGL
      fill(255);
      ellipse(this.pos.x, this.pos.y, 25,25);  
    
     // WEBGL
      createCanvas(window.innerWidth, window.innerHeight, WEBGL);  
    

    and it's is slow

  • Okay so you are trying to draw this is slow

    // non WEBGL
      fill(255);
      ellipse(this.pos.x, this.pos.y, 25,25);  
     
     // WEBGL
      createCanvas(window.innerWidth, window.innerHeight, WEBGL);   
    

    Yes

  • @SaintPepsi

    Interessting observation.

  • @nabr

    You'd expect a 3D engine to have no problem calculation 2D objects since 2D is less math heavy.

  • @SaintPepsi

    First your right, if you want to use WebGL you have to modify your code, this is undocumented!

    I will debug your code later, with just a singel Mover it works great. Meanwhile look at your code a second time, i will come back later to this thread!

    //createCanvas(window.innerWidth, window.innerHeight, WEBGL);
        function draw() {
          background(51);
            var temp = new Mover();
            movers.push(temp);
    
          //mover 0
            movers[0].update();
            movers[0].show();
           //clear the stack
            movers.pop(temp);
        }
    
  • @nabr

    I'm not sure what you're showing me in your snippet of code.

    Could you explain it a little?

  • @SaintPepsi

    I also not sure jet, i need more time for debug.

    This is the mousePressed Function on P5 Github

    @GoToLoop

  • Plain Highscool Javascript Lib 1000Chai Test

  • edited May 2017

    @SaintPepsi

    You could do two things

    Try to figure you where the "bug " is (but first try to rewrite your code)

    I think it should be a better handling by Javascript addEventListener and the draw Loop in P5Js. I'm not sure how both are scoped and how they communicate.

    MousePressed() means something is running in a loop and listen to UserInput
    draw() means the same with different main emphasis draw should have a higher order mousePressed should scope the values and overload some others ...

    Look at the implementation
    https://github.com/processing/p5.js

    Text should work like this in WebGL https://webglfundamentals.org/webgl/lessons/webgl-text-texture.html

    As i allready said, i currently out of time.

    Good Luck.

  • edited May 2017

    @nabr

    I've updated the WebEditor to only add 1 Mover on click:

    http://alpha.editor.p5js.org/SanCoca/sketches/Bkh607uZZ

    Are you sure this has to do with the way the mouseClick event is fired?

    To me it seems that the WEBGL mode has trouble rendering 2D objects.

  • @SaintPepsi

    I think you just to slow, can you speed thigs up ???

    Mover.prototype.update = function() {
      this.pos.add(this.velocity);
      if (this.pos.x > width/2) {
        this.pos.x = 0;
      }
      if (this.pos.y > height/2) {
        this.pos.y = 0;
      }
      if (this.pos.x < -(width/2)) {
        this.pos.x = width/2;
      }
      if (this.pos.y < -(height/2)) {
        this.pos.y = height/2;
      }
    }
    
  • @SaintPepsi

    like this

    this.velocity = createVector(random(20, 200), random(20, 200));

  • edited May 2017

    Yes, i have to go now.

    Good Luck

    Exiting potential infinite loop at line 15. To disable loop protection: add "// noprotect" to your code

  • It stops at 19 for any reason you have to wait for 30 sec and then it speeds up again funny alt text

  • I still found not time to for debug.

    I can confirm, you have to modifiy your code to use it with a P5js renderer, some undocumented code inconsistency from side of the devs.

    Best

  • @nabr

    I'm sorry but I don't know how to do that :(

  • @kfrajer The Problem here is everytime a new Object is created the random/velecoty values gets strange result.

    http://alpha.editor.p5js.org/SanCoca/sketches/Bkh607uZZ

  • @nabr When I try to console log the velocity it says this:

    Uncaught TypeError: Converting circular structure to JSON (: line 19)

Sign In or Register to comment.