[Godot 2] Trying to understand the Material's "Uv Xform"

woopdeedoowoopdeedoo Posts: 109Member
edited August 2018 in 3D

In the MeshInstance -> mesh -> Material, there's the Uv Xform matrix, and I'm trying to get a grasp of what it does. I kinda get it, but I'm really confused, as every time I edit the values it doesn't seem to act in a way that makes sense to me, or to act at all.

I made a cube in Blender, and positioned the UVs around a tile in a tileset. I was trying to figure out if the Uv Xform would help me in changing the cube's UVs to point to another tile in the tileset, but not only I'm not quite getting how it works, I'm also not sure if this would do what I'm looking for (what is basically the same as changing the texture region in a 2D sprite, but in a 3D mesh).

I understand that, according to the docs, they're multipliers. But that's about it... Can someone explain to me what each value in the matrix does exactly?

(EDIT: I was also looking for a way to deform the textures, and the Uv Xform kind of also seems like it could do that.)

Best Answer

Answers

  • MegalomaniakMegalomaniak Posts: 3,003Admin
    Accepted Answer

    https://en.wikipedia.org/wiki/Transformation_matrix

    Matrix math is a whole subject unto itself.

  • woopdeedoowoopdeedoo Posts: 109Member
    edited August 2018

    Ha... I think I'm gonna pass on that. :) It doesn't seem to do what I wanted to do anyway. Meanwhile I found out that I can use the MeshData Tool to move UVs, however, I ran into a problem there. Maybe you could help me with it (I can make another thread if you think it's better):

    When I iterate over the uvs of my mesh (which is a cube)...

    for v in range(mdt.get_vertex_count()): # mdt is a MeshData Tool instance
        # I multiply their positions by texture (tileset) width and height so the numbers make more sense 
        print("%d | %s" % [v, str(dt.get_vertex_uv(v) * Vector2(256, 512))] )
    

    ... the order that they're listed doesn't seem to make sense. So when iterating I don't quite know which vertex's uvs I'm changing.

    The output of the code above is this:

    0 | 0, 0       # I would expect it to be something like 
    1 | 32, 32     # 4 vertices listed clockwise or counter-clockwise
    2 | 32, 0      # and then the next 4, and so on
    3 | 0, 0
    4 | 32, 32
    5 | 32, 0
    6 | 0, 0
    7 | 32, 32
    8 | 32, 0
    9 | 0, 0
    10 | 32, 32
    11 | 32, 0
    12 | 0, 0
    13 | 32, 32
    14 | 32, 0
    15 | 32, 32   
    16 | 0, 0
    17 | 0, 32    # these are all out of order
    18 | 0, 32    # and lumped together 
    19 | 0, 32    
    20 | 0, 32
    21 | 0, 32
    22 | 0, 32
    23 | 32, 0
    
  • MegalomaniakMegalomaniak Posts: 3,003Admin
    edited August 2018

    It's triangles not quads. Not sure what's up with the later UV's, bad unwrap? What cube are you using, one you imported or the test object in mesh instance?

  • woopdeedoowoopdeedoo Posts: 109Member
    edited August 2018

    I'm aware that they're triangles, but it seems they share vertices (or else they'd have to be more than 24 of them for 12 triangles), so the effect seems to be much like a quad.

    I forgot to mention that all the UVs are originally overlapping the same tile, so that the whole cube has the same texture all around, and that's why they all have similar positions.

    I'm using a cube imported from blender. I rotated some UV faces to orient the texture the same way for all sides. I didn't use the better collada exporter though. I'm just about to go try it.

  • woopdeedoowoopdeedoo Posts: 109Member
    edited August 2018

    Well, with better collada, if I don't triangulate it, I get exactly what I was expecting: 4 vertices in CCW, then the next 4, etc. But godot throws me a warning in the output.

    If I triangulate it, then I'm back to the problem I was having...

    EDIT: btw, godot keeps reimporting the model every time I stop running the game. How do I stop this? (I had this happening before, but I can't remember what causes it.)

  • woopdeedoowoopdeedoo Posts: 109Member
    edited August 2018

    Not sure if it was because I rotated another UV face int he original 3D model to see if it would make a difference, or if it was better collada, or if it's because I triangulated the cube myself, but the order is a bit more tidy now. Still the same problem, but has a pattern that I can mostly loop through.

    I think this is a bit hacky, but I'll run with this until I figure out how to solve that problem:

    func switch_texture(tile_index):
        cubemesh = get_node("Block/Cube").get_mesh()
        mdt = MeshDataTool.new()
        mdt.create_from_surface( cubemesh, 0 )
    
        var x = (tile_index % 8)*32
        var y = (tile_index / 8)*32
        var tileset_size = Vector2(256, 512)
    
        for v in range(0, 18, 3):
            mdt.set_vertex_uv( v,   Vector2( x   , y    ) / tileset_size )
            mdt.set_vertex_uv( v+1, Vector2( x+32, y+32 ) / tileset_size )
            mdt.set_vertex_uv( v+2, Vector2( x+32, y    ) / tileset_size )
    
        mdt.set_vertex_uv( 18, Vector2( x, y+32 ) / tileset_size )
        mdt.set_vertex_uv( 19, Vector2( x, y+32 ) / tileset_size )
        mdt.set_vertex_uv( 20, Vector2( x, y+32 ) / tileset_size )
        mdt.set_vertex_uv( 21, Vector2( x, y+32 ) / tileset_size )
        mdt.set_vertex_uv( 22, Vector2( x, y+32 ) / tileset_size )
        mdt.set_vertex_uv( 23, Vector2( x, y+32 ) / tileset_size )
    
        mdt.commit_to_surface ( cubemesh )
    

Leave a Comment

BoldItalicStrikethroughOrdered listUnordered list
Emoji
Image
Align leftAlign centerAlign rightToggle HTML viewToggle full pageToggle lights
Drop image/file