EpicGamesExt / BlenderTools

Blender addons that improve the game development workflow between Blender and Unreal.
https://epicgamesext.github.io/BlenderTools/
MIT License
2.75k stars 46 forks source link

Send to Unreal - Add support for groom Group ID and other custom properties #557

Open Kyrandis opened 1 year ago

Kyrandis commented 1 year ago

Current workflow: I'll just go through the steps I worked on in the past to maybe help this tool become much stronger and spending more than half a day trying to figure out how to separate grooms into Group IDs with no success.

  1. Sculpting new hair with blender 3.3 tools on a geo surface
  2. when done select all hairs, go sculpt mode -> Curves -> convert to particle system
  3. Select the geometry and Under the Particle Properties tab, Show Emitter should be disabled for Render AND Viewport display
  4. With the geometry selected only -> file export -> alembic(.abc)

    With settings:

    • Manual Transform Scale 100.00
    • Frame Start & End : 1
    • Use Instancing ☑
    • Custom Properties ☑
    • Selected Objects ☑
    • Visible Objects ☑
    • Export Hair ☑
    • Export Particles ☑

This can be helpful as I tried Send2UE with some grooms I already created with this workflow and it can take long if your grooms are really big or complex, whereas going through this hardset manual method it was quite fast but I'm not sure how many attributes or things I'm omitting going this route than using the send2ue tool which is incredible so far. Upon arriving into Unreal you may have to play around with rotation and axis scale -1/1 depending on how you created your asset facing. Send2UE natively accomplishes this but just incase anyone had something super large and halting and needed an extra path. Then I created a binding in engine with the same mesh I sculpted the hair on or at least geometry that was split from the geometry the hair was to be attached to.

I was trying to separate particular hair chunks together into the groom_group_id geometry parameter schema specified in the https://docs.unrealengine.com/4.27/en-US/WorkingWithContent/Hair/AlembicForGrooms/

I don't really know where Blender can fire these in, I've tried custom properties in various areas and can't find it anywhere where Unreal recognizes the attribute. There was an offshoot number of plugins I tried and one of them was a groom exporter also but it only splits all the hair curve assets into their own group IDs instead of being able to name or manually index them to be sorted into a group ID number and the curves arrive at Unreal in a very odd number of settings lost/changed/unexpected with that plugin. It seems to read all curve objects into its own array and how many points its data has as the group ID based on how many hair curve objects there were selected and it seems like it was looking to assigning an Int32TPTraits.arrayType to the object's data "points" as the groom_group_id

image

Through this research I also found that Sybren at Blender was working on the ABC format to take on custom properties and attributes in 2017 all the way up to 2019/2020 but not sure if he ever got around to finishing it and am trying to get his attention. Houdini currently works and was trying to get a friend to help me export an asset out to fire into blender to see how blender reads it so that Unreal would recognize it also the same way it reads the houdini abc file as a groom import into unreal.

The workaround is just making two separate groom assets(hair1, hair2, hair3, eyebrows1, eyebrows2 etc.) but this doesn't seem like the correct way to do this when some of the default metahuman hairs possess similar structure that makes sense(Hair1:GroupID [0-x], Eyebrows:Group ID[0-x]) when it comes to strand based hair grouping.

Currently the Export Settings Dialog in Send2UE Groom for each mesh combines all the hair curves into one group by itself which is pretty close, is there a way to insert groom_group_id integers into a setting here for the Send2UE to target an attribute or a Collection folder named as an integer to be used as Grouping ID assignment for .abc export?

Some of the plugins I tried seem to read from this attributes area here in each hair curve object in Blender but I don't think Unreal reads it from here at all image

james-baber commented 1 year ago

Hey thanks for the detailed post! Just to summarize, send2ue currently does not do anything special to export custom properties. @iigindesign did alot of work to add initial support for the groom asset type. And the hope is to also add support for the custom properties on grooms.

Ill share what I have learned so far:

By following the maya guide and building the groom_root_uv example at the bottom, then inspecting the .abc file with with cask I could at least verify that maya is writing their custom attributes to .arbGeomParams under the .geom properites on a alembic curve object. And this works with the unreal importer and the groom_root_uv prop is imported(I am assuming different props are also expected to be here). For example this script prints out the groom_root_uv values from hair_export.abc. hair_export.zip

import cask
abc_file = cask.Archive("hair_export.abc")

def walk(obj):
    print(obj.name, obj.type())

    if obj.type() == 'Curve':
        pprint(list(obj.properties['.geom'].properties['.arbGeomParams'].properties['groom_root_uv'].values[0]))

    for child in obj.children.values():
        walk(child)

walk(abc_file.top)

I have tried various combinations of custom props on blender objects and so far have not figured out where the blender .abc exporter needs these. It would be possible to write these in with PyAlembic but there is alot of overhead with compiling for different platforms and supporting various blender versions once you look at having to distribute send2ue. Also external dependencies have legal hurdles to jump through (or that could block). So my hope is to find python a solution with the existing blender api and custom props.

I haven't had much time to dig into this, but skimmed through this https://developer.blender.org/T50725

And based on what Sybren A. Stüvel says it seems that the abc exporter does write custom props to .arbGeomParams for meshes at least... And maybe other objects.

I haven't done any blender C++ development before, but just looking at the source it does seem there is some kind of support for custom properties on curves. (don't know if it is correct for unreal, but I can verify with cask that I can't find the properties, at least where Id expect.)

And this looks likes the implementation of the custom property writer that is being referenced https://github.com/blender/blender/blob/master/source/blender/io/alembic/exporter/abc_custom_props.cc

Here is the spec for unreal grooms interms of geometry params https://docs.unrealengine.com/5.1/en-US/using-alembic-for-grooms-in-unreal-engine/

I believe with some more investigation the correct inputs might be found, but I am currently out of time to work on this at the moment, but thought I would post what I have found.

Kyrandis commented 1 year ago

Oh awesome! That's really good to know, I will try my best to connect the dots a bit better from whatever information I can find to try and assist in this area and hopefully find a solution. Some of which you shared has given some insights~!

I am currently just doing trial and error with just pieces of hair curve objects, I think the answer may lie within Blender's Geometry Nodes after looking a bit more deep into some of the exporter plugins I have and to how Blender's Hair Curve sculpting system was created that they introduced in 3.3+ which is derived off Geometry Nodes.

I don't have too much experience in these areas yet but I noticed there's a Store Named Attribute directly into Geometry Nodes and shows up on the columns that I think some of the exporters write out into its .abc format and Unreal actually sees them here after playing around with it and just doing numbers matching with other export plugins image , however without converting it to a particle hair system in the Blender 3.3- days there's a lot more processing going on to store the hair curves as an object group to be assigned its groom_group_id and a lot of attributes/assets are different much like how Blender's scale is 1:100 with Unreal

The exporters I'm using seem to package the hairs to Unreal a different way but they also land entirely different too but with a lot of attributes checked and able to be used, I'm just not familiar with the tool is probably all. The two cases I'm encountering is:

  1. Passing through as a converted hair particle system it seems accurate of what I made gets to Unreal as it is seen in Blender and
  2. Without conversion to a particle system and hair curves directly through a groom exporter written by a user named TurboCheke. Currently the Send2UE tool is the expected result, but doesn't have the Group ID separation function 😥 This exporter from the other author has the expected function but the unexpected results of the entire hair asset 😅(this may be due to inexperience with their tool is why I'm having unexpected results)

This becomes problematic as the grooms and their physics assignment will behave very differently from one export method vs. the other. The conversion to particle export type is the closest resemblance to Unreal's characteristics, but the Hair Curve groom type has a lot more customization/flexibility/additional features that just need to be bridged, but all the settings like width, group id, groom id, etc. need to be navigated through which is challenging and time consuming.

I believe the custom properties may be an overall scene thing at a parent level in its functionality currently in Blender too but the Hair Groom and Curves system in Blender is mostly stored within Geometry Nodes is where I believe the correct inputs will be found for all of the alembic and groom features that Unreal will recognize/see when the format is exported out from Blender.

Through this I also learned there's no real way to write attributes into the particle hair systems currently Blender, I think? but I may be mistaken as I've tried a bit but haven't had too much time to dive deeper into the issue and will try to discover more over time. I've attempted to write/store/fire some form of attribute in the hair curves prior to conversion but it appears nowhere in its traits or data anywhere post conversion to a hair particle system which pointed my conclusion back towards Geometry Nodes.

These are some other sources and areas I was looking at trying to figure out how this was built up from blender python api's Depsgraph Context Access Properties

ItamarBN commented 1 year ago

In regards to the Root UV's topic. After researching a lot I found a tutorial and a plugin, that kind of work.

Im not trying to divert attention from Send2UE, I only want to try and inspire new thinking/ideas for solutions.

The first workaround is a YouTube Tutorial. Its a nice workaround for simple Hair Systems. Its a good workaround, but... well its a workaround.

The Second one which got me really exited, and kind of works is an Addon for Blender called Groom Exporter. It Worked wonderfully with the Einar - hair grooming file. But its not reliable. It seems to some times work and some times dos not.

I hope this helps.

LucianoDaluz commented 1 year ago

Yeah, I use this one to get the RootUvs to Unreal, but seems like it is not working on 3.5.

ZeChArtiahSaher commented 1 year ago

I've looked around and didn't really find a way to do this. I think there is a need to at least add support for custom attributes in the pipeline. I also found myself relying on procedural UV generation in geom nodes and as far as I can tell it's not a thing with this plug. Basically what needs to exist is ability to pipe custom attributes to unreal mat/object.

ben-mkiv commented 10 months ago

i wrote a fix for unreals alembic importer regarding rootuv, not sure if epic will ever merge it since it's been a while...

https://github.com/EpicGames/UnrealEngine/pull/10617

Hopefullyidontgetbanned commented 9 months ago

maybe this has been already mentioned but doesn't blender's native alembic exporter already write these necessary attributes? If blender's native alembic exporter has these same issues wouldn't it be a limitation with Unreal not reading it, or Blender not conforming to a standard attribute format?