UVFace with simple DynamicTexture

I’m having a rather noobish issue understanding UV face and how it should be applied to my project. I’ve been working on a custom frame design tool (which is almost done!) and one of the last details is ensuring that I can texture the frame in a different way.

Here’s my playground link: https://www.babylonjs-playground.com/#2CU0P1#10

My understanding is that the only way to texture a polygon with multiple assets is by a sprite or maybe decals. I already attempted using decals but it didn’t work out too well. I’m resorting to using a sprite dynamically created from two separate images. Unfortunately I can’t pre-process the sprite and it MUST come in as two assets.

The images are always 700px tall however are variable in width. Once I determine the basic solution I’ll calculate the canvas resolution (after loading the image assets). For now the canvas is hard coded to this particular textures dimensions (30px + 20px by 700px tall):


My goal is to set the proper UV faces so that the dynamic texture is rendered along the correct sides of my geometry (which consists of 4 separate “sticks” that I’m positioning). My geometry can’t change either which I feel is going to make the UV mapping a bit more complex.

In my example I’m trying to ensure that the red texture is on the face of the artwork and the purple is on the outside edge. I’ve been messing around with different positions of the UV face vector3s and didn’t get anywhere trying to rationalize how they’re placed. Any suggestions would be extremely appreciated!

Am I going in the right direction or overcomplicating it (as usual?).

The faceUV vectors give the coordinates to use to apply the texture to the top/side/bottom of the extruded shape.

So, in your case:

  • top = 0,0,30/50,1 because you want to use the part (0,0,30,700) of the texture for the top and the full texture is (0,0,50,700) (x,y,width,height)
  • side = 30/50,0,1,1 because you want to use the part (30,0,50,700) of the texture for the side
  • bottom = 0,0,30/50,1 assuming you want the same mapping than for the top

https://www.babylonjs-playground.com/#2CU0P1#11

The problem is the side: the algorithm is assuming you take an “horizontal” chunk of the texture to map to the sides, whereas in your case your texture is very thin and tall. You would need to rotate the uv coordinates for the sides but AFAIK it’s not supported by extrudePolygon.

What you can do is writing your side texture in the right orientation in the dynamic texture:

https://www.babylonjs-playground.com/#2CU0P1#13

In this PG, the dynamic texture is like this:
image

So a lot of space is lost…

Ahhaaaa that’s really clever! The proportions are maxed because you use the height consistently. If I wanted to support an inner texture I could right align it and change the UV faces as well.

That’s so awesome. Thanks @Evgeni_Popov

I attempted a basic implementation and getting a black border (likely because positioning is off). I used most of properties you supplied but having trouble rationalizing where the math went wrong. If you have an idea, let me know. If not I’ll plug away at understanding this.

PS. Do you know of any easy tutorial or explanation docs. I want to understand UV faces. They’re really important and the Babylon docs on them aren’t helping from a learning perspective.

Yes the black border is probably because of some values passed to faceUV[] or to ctx.translate / ctx.drawImage being off. Hard to tell more without a repro, though.

Do you mean the faceUV array you pass to extrudePolygon or uv coordinates in general? If the latter, I think you should find some video tutorials on the net (width Blender, for eg) and if the former maybe this doc can help: https://doc.babylonjs.com/how_to/createbox_per_face_textures_and_colors

Awesome thanks for the link I’m going to dig in.

I’m drawing to the canvas properly (I tested it elsewhere). It must be my faceUV properties. Hmmmm, it’s likely me being silly. If I really can’t get it I’ll reach out for now thanks so much again.