Fabric + Babylon dynamic texture

Hello,

I want to build a project where you can add image, text and paint on a model.
I use fabric for input of the dynamic texture in babylon, however as you can see in this playground, the canvas cannot take all the place.
https://www.babylonjs-playground.com/#9U086#116

I notice that it’s working in webgl and not in webgl2.

If i switch the engine to webgl it’s working fine, however i don’t want to switch, is anyone has a solution to make it work in webgl2 ?

Thanks

The problem comes from the fact that the first time you browse the page the fabric.js script is not loaded yet because it is downloaded asynchronously. So you get an error when you do fabric.Canvas.prototype._translateObject = ....

You can wait for the script to be loaded before moving on:

https://www.babylonjs-playground.com/#9U086#238

4 Likes

Hello,

Thanks for you fast answer.
I’m able to draw and it renders on the model, however i had another problem.
I’m using now a uv map for my canvas and i’m drawing on the model in 3d, when i move my mouse i get with folowing function the uv of the texture:

var pickResult = scene.pick(scene.pointerX, scene.pointerY);
var texcoords = pickResult.getTextureCoordinates();

And after i draw on the canvas with the converted uv coordinates.
But the problem is that i will have, brush, image … It will not work if i get only one point of the uv.
So i try to get a bunch of point, for example i try this code for a circle brush:

for (let i=-r ; i<r ; i++) {

          for (let j=-r; j<r; j++) {

             if((i*i + j*j)<(r*r)){

              let pick = scene.pick(Math.round(scene.pointerX+i), Math.round(scene.pointerY+j));    

              let pickCoordinates = pick.getTextureCoordinates();

              if(pickCoordinates){

                points.push({x:Math.round(pickCoordinates.x* size.width) , y:Math.round(pickCoordinates.y* size.height)});

              }

             }

          }

      }

It’s working but there is a perfornance issue, if i increment the rayon of the brush, it takes about 169ms to execute this part of code.

I’m wondering if there is another method which is better to solve my problem ?

Thanks

What you can do is creating a render target texture where you render the meshes with a special material that outputs their uvs.

Then, on picking, you read from this texture to get the uv. Note that getting back the RT texture to CPU (using readPixels) is a relatively slow process, so you must make sure to do it only when necessary, meaning when something changes on screen (and only when you need to do some picking). In the PG below I do it only if the camera has moved (=if the scene transformMatrix has changed):

https://playground.babylonjs.com/#HNK4MS#3

1 Like

Thanks a lot for this fast answer !

I never manipulate shader before, this is the PG i make from the PG you provide.

https://playground.babylonjs.com/#HNK4MS#7

I add my model, and when i select the uv, it’s not the good one, i suppose that it’s linked to the shader applied to the material that you create :

mat2.Fragment_MainBegin( gl_FragColor = vec4(vMainUV1.x, vMainUV1.y, 1., 1.); return;);

I’m wondering, what i need to do in order to have the right material that outputs the right uvs ?

My bad, i finally get it. Thanks!