Vertex animation textures, beanbags and boneless animations.

Sdílet
Vložit
  • čas přidán 11. 10. 2020
  • The skeletal animation workflow is very common in realtime applications due to its flexibility and performance, but it can make certain types of animations tricky to pull off. In this video I explore using vertex animation textures to get realtime-friendly per-vertex animations from Blender into Godot.
    References:
    / texture-animation-tech...
    Me:
    Patreon / bolddunkley
    Twitter / bolddunkley
    itch.io bolddunkley.itch.io/
    Software used for this video:
    Blender 2.8 www.blender.org/
    Godot 3.2 godotengine.org/
    OBS obsproject.com/
    Kdenlive kdenlive.org/en/

Komentáře • 130

  • @alejmc
    @alejmc Před 3 lety +185

    I was not expecting this to tackle Python in Blender with such a practical example. Greatly appreciated, what a complete 10mins... concepts, scripting, baking, shaders, etc.

    • @curtisnewton895
      @curtisnewton895 Před 2 lety +1

      practical ? you dont get the whole code, so you'll spend time figuring out every bits
      this is bullshit

    • @Barnaclebeard
      @Barnaclebeard Před 2 lety +3

      @@curtisnewton895 lurk moar

    • @kinoko384
      @kinoko384 Před 2 lety +9

      @@curtisnewton895 If you can't even put in the effort to read some code that he explained nicely and instead make multiple comments insulting him, you should probably give up making games

    • @antoinefortin1386
      @antoinefortin1386 Před 2 lety

      @@curtisnewton895 Full code is on Patreon.

  • @ArthurPhoenix
    @ArthurPhoenix Před měsícem +4

    Actual topic aside, this might be the most incredible informational video I have ever seen. The information density is extremely high, yet at no point did I not understand what was going on, or feel the need to pause or rewind.

    • @MartinDonald
      @MartinDonald  Před měsícem

      Thank you so much! This is absolutely the goal I set out for with these videos.

  • @harshmudhar96
    @harshmudhar96 Před 2 lety +70

    One of the best things about VATs is that objects using the same VAT material can be batched into one draw call.

    • @NielsGx
      @NielsGx Před 2 lety +10

      Vulkan laughing in the corner

  • @kolupsy
    @kolupsy Před 2 lety +14

    Man i just love when people appreciate the power of python in blender. Also just the fact that not having a builtin tool for something should mean game over

  • @jacobcowan3599
    @jacobcowan3599 Před 2 lety +29

    This is the coolest thing I've learned all week while studying asset creation for my game. You've earned a subscriber, my friend!

  • @YouCodeThings
    @YouCodeThings Před měsícem +1

    This is an exceptional video. Thank you for making this!

  • @Thomason1005
    @Thomason1005 Před 7 měsíci +2

    i was like "i didnt know blender can do that", and it canot, but he just wrote the whole thing from scratch. nice work!

  • @FlaschDrive
    @FlaschDrive Před 3 lety +8

    Every video you post is consistently high quality, and I'm super excited to see what content you post in the future!
    Something tells me this will get some use in my own Godot game as well!

  • @RussDnB
    @RussDnB Před rokem +6

    Your work is truly fascinating. I could listen to you for hours.
    Love how you explains in reasonable detail, but don’t go on for way too long. Also love how clear and concise you are, highlighting both what you’re covering and points of interest that we can pause the video at.
    I’m no programmer, but fancy dabbling with screensavers. I’m sure I’ll be utilising some of your guidance in my learning.
    Thank you.

  • @alessandropantano9863
    @alessandropantano9863 Před 3 lety +2

    Amazing as always. I love the fact that you talk about like, patron, subscription at the end.

  • @Raformatico
    @Raformatico Před 3 lety +14

    You're great Martin congrats!!!

  • @ColinTimmins
    @ColinTimmins Před 8 měsíci

    Fantastic set of videos you have made. Your visuals have helped so much in understanding these concepts.

  • @RealPigeonz
    @RealPigeonz Před 3 lety +2

    Dude you are a wizard! xD How useful tutorials you create... each one is a gold mine...

  • @pavanbhadaja8859
    @pavanbhadaja8859 Před 3 lety +1

    Came from WFC video, and after watching this video i can say that your channel has quality content and you earned a new subscriber ;)

  • @cintron3d
    @cintron3d Před 3 lety +1

    This is really cool, thanks for all your hard work creating these tutorials.

  • @lewisbowes4921
    @lewisbowes4921 Před rokem +2

    This was fantastic, thanks so much for uploading!

  • @davidmurphy563
    @davidmurphy563 Před 3 lety +14

    That was super helpful, thank you so much.

  • @Eddddden
    @Eddddden Před rokem +1

    This is absolutely insane! How does someone even arrive at this solution is incredible, thank you so much for what you do!!!!!

  • @lordkelvin1
    @lordkelvin1 Před 2 lety +2

    Hope you'll keep making these in the future because they're really excellent! :) Not many videos on youtube on these higher level tech art concepts.

  • @mapopi-mm
    @mapopi-mm Před 2 lety +1

    This was an amazing tutorial on a deep topic and clearly explained. Thank you so much!

  • @bodamat
    @bodamat Před 2 lety

    Wow, I’m surprisingly happy :) Very well explained and I will defiantly use it in my future Godot projects. Thanks a lot 🥰

  • @styliann
    @styliann Před 3 lety +2

    This is excellent work.

  • @urjasolanki8833
    @urjasolanki8833 Před 3 lety +1

    This was very informative! Thank you Martin!

  • @XtremeZero
    @XtremeZero Před 3 lety +3

    That's actually brilliant, previously I used to use vertex colors to assign delays and randomness to various parts of the model then I apply a complex shader to do the rest of the animation...
    damn if I knew about this earlier, thnx for sharing

  • @AgnisNeZvers
    @AgnisNeZvers Před 3 lety +3

    Again my mind is blown. I had idea that such concept might exist but DAMN.

  • @Wave_Commander
    @Wave_Commander Před 2 lety +1

    Discovered you last week with the signed distance fields video. I just finished by BSc in Computer Science and took intro to graphics 1 and 2 this year. Very cool content; love having more tools in my toolbox. I'm a Patron now!

  • @VladgavligGapchich
    @VladgavligGapchich Před 3 lety +1

    Great tutorial as usual!

  • @SmilingRob
    @SmilingRob Před 3 lety +11

    This is so helpful thank you! I think when I implement it I will bake the -y,z transformation into the texture instead of doing it in the shader.

  • @RoboClonk
    @RoboClonk Před 2 lety +1

    This is explained so well, thanks!

  • @gouthamkancherla5571
    @gouthamkancherla5571 Před 3 lety +1

    This is one of my favourite channels
    Not kidding!

  • @horsethi3f
    @horsethi3f Před 3 lety +40

    Thank you! Made it to work for my use case, would not have made it if you didn't show any code. But here are some suggestions:
    - In bpy.data.images.new(), pass "is_data=True" otherwise the pixels gets affected by colorspace. To export in 16bits per channel, pass "float_buffer=True" and set color_depth in scene.render.image_settings to 16. Saving to OPEN_EXR format works best for me, blender seems to save them in float instead of rounding to ints if you choose that format.
    - Instead of saving vertex positions, saving delta positions might increase accuracy. In UVMap2, the V component can be used to store your "scale" value (maximum distance moved by that vertex). With this, you dont have to pass scale values to the shader anymore. To further improve on this, each vertex can have different scale values to increase accuracy per vertex.
    - You can further remove texture_width and num_frames from the shader by adjusting the U in the UVMap2 and calculating "frame" adjusted to num_frames before passing them to the shader.

    • @arthurjvnb
      @arthurjvnb Před 2 lety

      Martin Donald, please do an updated video using Azmi's tips. So you could do another great example for us to learn :D

    • @chadykarlitch3975
      @chadykarlitch3975 Před 2 lety

      Good tips! Thanks for adding to the video

    • @comedyclub333
      @comedyclub333 Před 2 lety

      I know UVs may be outside the range of 0-1 because only the fract get's used to achieve tiling, but do values greater than 1 (e.g. for storing the scale in the V component) actually get stored or are they remapped to 0-1? Did you try this? It might fall or stand with the way Blender or the target file format handles UV coordinates outside this range. OBJ for example unfortunately does not standardize multiple UV channels so this might not even work in the first place at all.

    • @marcwakefield2840
      @marcwakefield2840 Před rokem

      I would be really interested to give your version a try Amzi Shah. I am very inexperienced with Python but I'd love to see the difference between using delta positions and vertex positions.

    • @mateuniverse
      @mateuniverse Před 8 měsíci

      when saving deltas, how would you maintain state between frames (as shaders don't have states)

  • @mourirsilfaut6769
    @mourirsilfaut6769 Před 2 lety +1

    Thank you for making these videos

  • @casanova2829
    @casanova2829 Před 3 lety +3

    Golden channel 🌟

  • @ahreuwu
    @ahreuwu Před 2 lety

    I'm not a game dev, I only know basic programming so pretty much all of the info here completely blew over my head. still very interesting, such a great video!

  • @albarnie1168
    @albarnie1168 Před 2 lety

    Happy to have found your video. Best of luck!

  • @nyscersul42
    @nyscersul42 Před 2 lety +1

    Your channel is gold dust for an algorithm lover hehe

  • @TinyWorlds
    @TinyWorlds Před 3 lety +1

    This is super interesting, thank you! Didn't know this was a thing

  • @stefanguiton
    @stefanguiton Před 2 lety

    Excellent video!

  • @marbles3662
    @marbles3662 Před 2 lety

    Amazing, great content.

  • @nicobu
    @nicobu Před 2 lety +1

    Holy sh*t! Thanks so much! Absolutely awesome!

  • @bur1t0
    @bur1t0 Před 2 lety

    That's awesome! New technique to me.
    If you want to make the shader texture size agnostic, you can get the texture dimensions inside the shader itself using the ivec2 texSize = textureSize(texture, miplevel); function, where miplevel in this case would always be 0.

  • @isaacgreen9495
    @isaacgreen9495 Před 2 lety

    Fantastic!

  • @hongphat85
    @hongphat85 Před 5 měsíci

    Thank you so much.

  • @drekenproductions
    @drekenproductions Před 2 lety +1

    i will have to figure this out later but thats nuts

  • @Najebanski
    @Najebanski Před rokem

    good stuff

  • @Caslte371
    @Caslte371 Před 2 lety +1

    Спасибо большое за видео.

  • @jefflhama
    @jefflhama Před 3 lety +5

    Crazy! I'm looking for flow maps and find your channel and in my mind I was, ok, ill have to translate it to glsl for godot, now I have a channel with advanced techniques directly in godot! Thanks. I'm learning godot and shaders to use it as a creative coding framework and I'm thinking the crazy s*** i can do with procedural vertex animations in this way instead of a simple vertex animation.

  • @AirmanCS
    @AirmanCS Před rokem +1

    Martin where are you, your videos are absolute gold mine! I just tinkered a lot with the wave function one and got it working on Godot4, pls tell me you moved to another platform and I just need to find it T_T

  • @CAyou
    @CAyou Před 3 lety +2

    I needed that a couple of days ago, with blender and unity. I definitely need to learn python... Thanks for sharing, super useful!

    • @jamesuniverss
      @jamesuniverss Před 2 lety

      Hi ! did you achieve to make it works for Unity ? If yes I'm interested, really need to make it works with unity too ;)

    • @DanKaschel
      @DanKaschel Před 2 lety

      @@jamesuniverss try asking a specific question and someone might be able to help you

  • @Alander787
    @Alander787 Před 11 měsíci +1

    This is such a great content!
    How did you learn all this?

  • @Q269
    @Q269 Před 2 lety

    This was neato

  • @joshleap
    @joshleap Před 2 lety +3

    The value per second of this video is out of control.

  • @simpson6700
    @simpson6700 Před 11 měsíci

    digging through game files, i always wondered what these textures were for, but didn't even know where to begin googling them.

  • @shrippie-4214
    @shrippie-4214 Před 2 lety +1

    Coolest shet i ever seen how did ye get so gud at life?

  • @DerCooleVonDem
    @DerCooleVonDem Před 2 lety

    Sheesh i didn't use that before which is SAD omg helpful lol

  • @ruyabaraz
    @ruyabaraz Před rokem

    this is amazing. have you ever worked with meta spark? if so, how would you integrate this into sparkSL? thanks in advance.

  • @chrisdelpire5221
    @chrisdelpire5221 Před 3 lety +1

    Any advice for someone who's verts indices are all screwed up when I go into Godot? I think I have a decent export of the textures, my animation in Godot looks correct when I scrub through the frames, except all the triangles are incorrect, its as though my vertex positions are all correct, but the order of the vertex indices are incorrect. My guess is this must be an error in my export somewhere.
    By the way, your videos are really unique and fantastic. Always excited for a new video. :)

    • @MartinDonald
      @MartinDonald  Před 3 lety

      Sounds like an export problem indeed! Be sure to apply any transforms to your object (ctrl-A -> All Transforms). Maybe try exporting your object in a couple of different formats. I find Collada (.dae) to be the most reliable way of getting meshes from Blender to Godot right now.

    • @sakattodesign9927
      @sakattodesign9927 Před 2 lety

      @@MartinDonald so where is the addon to export blender animation to VAT? i cannt find the link..

  • @sobertillnoon
    @sobertillnoon Před 2 lety +2

    I initially heard "per vertex" as "pervert ex"'. My brain is broken.

  • @grittynerd
    @grittynerd Před 3 lety +2

    The same set of vertices with different sets of positions reminds me of the blend shape concept, with an array of shapes made from each frame state, with blending of 2 elements each time sequentially over time. Probably too many states ;) I wonder if there's any standard in baking simulation data, in Houdini you can export in a vdb format but i don't know if it's more for particle systems. Maybe it could be possible to use the blend shapes to have the raw data in Godot and then make an addin to bake from the editor what you want with a script (with helper functions that make the work of compressing/decompressing spatial data).

    • @MartinDonald
      @MartinDonald  Před 3 lety +3

      You're right there! You'll often hear this technique referred to as "blend textures" or "morph textures" because it's also a good way to get blend shapes/morph targets into a game engine that doesn't support them (most game engines).

    • @ph0ax497
      @ph0ax497 Před 2 lety +1

      @@MartinDonald Unreal Engine and Unity use just Alembic file system, which stores every frame as vertex vector of the geometry. Its basically obj. sequencer but in one file. Only downside of it is that the .abc size is straight proportional to the amount of vertices of the animated polygon. So if you have high poly mesh procedural deformations and/or simulations, the file will use a lot of space.
      It is still efficient per CPU and GPU usage, since the only thing that actually do work is ROM + RAM pipeline.

  • @laer96
    @laer96 Před rokem

    Is there a way to use this with multiple objects? like to achieve a demolition VAT using fractured objects, at the moment the plug in only allows a single object to be selected, wich means every piece of debris would have a separate VAT, and I'm looking for a way to have a single texture for the hole effect

  • @nerdydrow
    @nerdydrow Před 3 lety

    very cool! seems very useful.
    I have some question however :
    can it work with a rigged mesh (using bone animation+ vertex animation maps)?
    what are the limits of the map? how many vertex can it control, and how long is the animation possible?

    • @MartinDonald
      @MartinDonald  Před 3 lety +1

      In order: yes. As many verts as your texture has horizontal pixels, doesn't need to be a power-of-two because we're not compressing it. The animation length is determined by how many vertical pixels your texture has. This implementation uses one row == one frame, but you could reduce the quality by skipping every other frame. You also have control of the playback speed of the animation so it can be made longer/shorter that way.

    • @nerdydrow
      @nerdydrow Před 3 lety

      @@MartinDonald nice thanks, I was asking about the limits of the maps because in DX11 the biggest possible size a texture can be is 8192 pixels, but I don't know about OpenGL (or Vulkun for that matter)

  • @Paulo_Dirac
    @Paulo_Dirac Před 11 měsíci

    Nice tuto, what is purpose of tangents though? aren't pos + norm is enough for a triangle/quad mesh to be animated accuratly?

  • @JourtCester
    @JourtCester Před 2 lety +1

    Awesome video, greatly appreciated! :)
    One question:
    Why is "texture_width = 128"? Should this not be equal to the number of animated vertices? I looked at the project file and your page seems to have only 102 vertices.

    • @JourtCester
      @JourtCester Před 2 lety +1

      Ah, I get it: The value is overwritten in the GUI in the Godot file. Strange, for some reason it is still not working with my example...

  • @benceblazsovics9123
    @benceblazsovics9123 Před 2 lety +1

    you can use sampler2D in a vertex shader in GLSL3.3? well one learns something new everyday i guess
    cheers!

  • @kimbrandwijk
    @kimbrandwijk Před 3 lety +1

    Awesome work, are those code snippets available anywhere?

  • @weightednormal3682
    @weightednormal3682 Před 2 lety +1

    Tried this in Unity. So close - there is always a slight offset which throws everything off. ***edit*** - use exr as mentioned in other comments. The error was precision - of course the textures end up quite a bit larger...

  • @SEOTADEO
    @SEOTADEO Před 2 lety

    Maybe the resolution of the animation yould be improved a bit by saving not the absolute position/tangent/normal but the change to the previous frame in the texture.

  • @SoftYoda
    @SoftYoda Před 2 lety

    How performant is it compared with for example alrmbic cache ?

  • @TheSoulmarine
    @TheSoulmarine Před 2 lety

    I've been using vertex animation for my Quake 1,2,3 models for years...

  • @GeorgeTsiros
    @GeorgeTsiros Před 2 lety

    precalculations
    got it

  • @silvaright
    @silvaright Před 11 měsíci

    Just out of curiosity, what would be the difference between vertex animation textures and using alembic files, I can't quite remember but I think alembic files are animated vertices right?

  • @omri1324
    @omri1324 Před 2 lety

    I try to do this with UE4. Are you gonna release this addon? Is it available on your Patreon?

  • @MrReactric
    @MrReactric Před rokem +1

    did you share blender script ? I could not see.

  • @Asdayasman
    @Asdayasman Před 2 lety

    A vertex isn't likely to get too far from its adjacent vertices, nor from the position it was at on the previous frame. I wonder if you could have more detailed animations with less data by storing differences from the previous frame or a specific adjacent vertex in really thin data types. Maybe have some k-frames to deal with zeroing.

    • @DanKaschel
      @DanKaschel Před 2 lety

      Another comment mentioned storing deltas instead of positions

    • @Asdayasman
      @Asdayasman Před 2 lety

      @@DanKaschel They're not me though so they're not cool.

  • @imrsvhk
    @imrsvhk Před rokem

    This is super cool.. I ended up here after trying to figure out similar approach to going from C4D to SparkAR... Would anyone happen to know if this python code would also work in C4D?

    • @ruyabaraz
      @ruyabaraz Před rokem

      were you able to get it into spark?

  • @ranjanachauhan8253
    @ranjanachauhan8253 Před 3 lety +2

  • @lilianahategan7939
    @lilianahategan7939 Před 3 lety

    I was trying to follow through your video but when applying the shader, the mesh becomes invisible no matter what I do. What would be the problem? Also, if you could 'remake' this video/ or a part 2 with more in depth info that would be very much appreciated. There's just a lot of info in such a short time.

    • @MartinDonald
      @MartinDonald  Před 3 lety +1

      That sounds like your new vertex positions aren't being set correctly. A good way to debug this is to add a mix(old_vertex, new_vertex, blend) and use blend to interpolate between the original vertex position and the modified vertex position. This visualisation should help you get an idea of where your verts are ending up, and hopefully give you a clue as to what's wrong. Hope that helps!

  • @Kevin-jb2pv
    @Kevin-jb2pv Před rokem

    Now teach us how to emulate the wobbly vertex animations that are _the_ iconic style of the Quake 2 engine :D
    Technically, I think Quake 1 also has this "feature", but the textures were so low-res and there was no fancy-schmancy "model interpolation" bullshit to pamper us with "animations that don't look like 2 FPS stop-motion" so nobody could tell that the textures were getting warped between each frame of animation. I know that some of the source ports added this in and caused some... interested effects (especially to the weapon firing animations). But even in vanilla Quake 1 without interpolation modded in, I think that you could see the model warping happening on the weapons as they bobbed up and down while running. Only when using the OpenGL, DirectX (Or, D3D, I suppose), and Glide renderers, though. I'm sure that on a technical level, the same thing is happening in the software renderer, but, frankly, if you're running in software mode then you're dealing with much bigger graphical degradation issues than a little bit of wobble in the edges lol.

  • @LeonardoSantagada
    @LeonardoSantagada Před 3 lety +1

    Wouldn't it be better to use lossless compression than uncompressed?

    • @MartinDonald
      @MartinDonald  Před 3 lety +2

      Good question! I was actually seeing some artifacting with lossless compression when making this example, but there are also some other good reasons to not bother with compression at all.
      In order to take full advantage of tex compression your texture size should ideally be a power-of-two (or made up of 4x4 pixel blocks), otherwise compression is less effective, and our anim textures can be all sorts of odd sizes so they don't compress nicely. Since this texture is tiny anyway we don't lose much memory by skipping compression, plus you'll get better performance out of an uncompressed texture since it doesn't need to spend any time being decompressed. I think for this case it's an all-round win to go uncompressed.

  • @MutohMech
    @MutohMech Před 2 lety +2

    Can I get uhh boneless animation with 2L of coke

  • @TheFoxfiend
    @TheFoxfiend Před 2 lety

    I get the feeling you have done a lot of transferring between blender and godot.

  • @Rundik
    @Rundik Před 2 lety

    Are images really more performance friendly than arrays?

    • @DanKaschel
      @DanKaschel Před 2 lety +1

      An image is just an array of bytes. The performance benefit comes from being able to calculate an animation using a shader rather than a physics simulation.

  • @Topyy
    @Topyy Před 4 měsíci +1

    Is the script downloadable anywhere?

  • @RobertFletcherOBE
    @RobertFletcherOBE Před 2 lety

    Cant blender now write arbitrary information per vertex using geometry nodes? Thats got to make encoding this sort of data so much easier.

    • @MartinDonald
      @MartinDonald  Před 2 lety +2

      Yes but you then have to get that data into a game engine and it's unlikely that your engine or export format will support arbitrary vertex data. That's why encoding the animation as a texture works well, because game engines are very well equipped to handle textures.

  • @JustYesntMan
    @JustYesntMan Před 2 měsíci

    where is blender script link

  • @mslmanni
    @mslmanni Před 2 lety

    Why not use blendshapes instead.

    • @DileepNow
      @DileepNow Před 2 lety +6

      Blendshapes are calculated by CPU while Vertex animation is done by GPU, which gives more performance. Also, to get a curved animation like a page turning, you will have to make many blendshapes for intermediate steps also costing more CPU and memory performance.

  • @DogeisCut
    @DogeisCut Před rokem

    i need this for a godot project im doing for a spring pad but its 4 am and im way too lazy to type out all this code rn
    and no im not buying your Patreon

  • @DeathxStrike18
    @DeathxStrike18 Před 2 lety

    This is an interesting way to go about it, but you can also just simply bake physics animation with blender where blender keyframes the changes in the mesh and is included in the metadata of the model as long as its exported as an FBX. Most of blenders physics modifiers have a bake or catch tab for this reason.

  • @DogeisCut
    @DogeisCut Před 2 lety +1

    could you not just use shape keys?

    • @danbellian5617
      @danbellian5617 Před 2 lety +1

      From what I've messed with, shapekeys will only do direct interpolation from one set of vertices to another. Animations such as bending an arm for instance, do not really look like bending with shapekeys, but more like melting into a bent shape. Also, shape keys will require the mesh to be Skeletal/Skinned rather than static, which is handled differently during batching and has a higher performance cost.

    • @DogeisCut
      @DogeisCut Před 2 lety

      Ah true. I see the use in this method now.

  • @xiphosura413
    @xiphosura413 Před 2 lety +1

    🅱oneless animation

  • @softviz
    @softviz Před rokem

    Now you can go with houdini without coding.

  • @Foodius
    @Foodius Před 2 lety +1

    Gosh i hate python so much, thanks for the infos though

  • @badradish2116
    @badradish2116 Před 2 lety

    SUBUSCIRIBESD

  • @OriginRow
    @OriginRow Před 8 měsíci

    I think it's time to revise this tutorial from blender to Unreal Engine while Houdini wiping up all industry.

  • @curtisnewton895
    @curtisnewton895 Před 2 lety

    why the fuck would you need to do that ? why not using shape keys ?

    • @DanKaschel
      @DanKaschel Před 2 lety +6

      Try doing this with shape keys and you'll quickly see why.

  • @mateuniverse
    @mateuniverse Před 8 měsíci

    great stuff! started playing with it! I did have to change the blender script somewhat to get it to work with blender 3.x though: MD_MorphTexture.py
    This makes sure that the proper object is exported (didn't work OOTB IDK maybe something changed in blender) and also that the object is exported as FBX, because the GLTF/GLB export (for some blender reason) changed the UVMap name. Enjoy.
    def export_mesh(obj, output_dir, name):
    if obj.name not in bpy.context.view_layer.objects:
    bpy.context.view_layer.active_layer_collection.collection.objects.link(obj)
    bpy.ops.object.select_all(action='DESELECT')
    obj.select_set(True)
    bpy.context.view_layer.objects.active = obj
    output_dir = output_dir + name + "_" + "mesh.fbx"
    bpy.ops.export_scene.fbx(filepath=output_dir, use_selection=True)