Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changes to Blender to improve engine export support #2422

Open
reduz opened this issue Mar 7, 2021 · 44 comments
Open

Changes to Blender to improve engine export support #2422

reduz opened this issue Mar 7, 2021 · 44 comments

Comments

@reduz
Copy link
Member

reduz commented Mar 7, 2021

Note: This is a proposal that includes very slight changes to Blender mostly, but I am creating this here so there is a place to discuss.

Describe the project you are working on

Godot

Describe the problem or limitation you are having in your project

Exporting from Blender to Godot more or less works OK nowadays, via GLTF2, FBX and Collada. There are, however, limitations that make the workflow not as efficient/ideal as it could be. These types of information can't be exported to Godot (or any other game engine) via conventional means:

  • UUIDs for Materials, nodes, etc. This way, if anything is renamed, the engine can keep track of it (including changes done in import, instancing or inheritance).
  • Blender Materials (shader graphs). Material export support is very limited in existing format. We could make the exporter just convert the Blender material to a Godot shader.
  • More detailed parameters on lights, cameras, IK, etc. that Godot supports but export formats do not.
  • Information on physics constraints, which Godot also does support.
  • Other types of objects such as Splines, which Godot supports (Collada actually supports this, but the other formats do not).

We currently have the Godot ESCN exporter for Blender, but this is a huge exporter and a large hassle to maintain. It would be much easier for us to piggyback on existing Blender exporters for metadata.

It was also suggested that we do this using Blender's custom property support, but this is not practical or usable because the information we require to export is something that only needs to be generated at the time of export, and not stored in the object.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

The solution is to do a small extension to blender created "Export Metadata Plugins", these plugins would be registered somehow in the Blender API (with an ID), then existing exporters would need to be modified to query every object exported for metadata (which would most likely return a dictionary associating the ID and the metadata), and save it using each format's extension support.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

From the plugin side, it would probably look something like this:

class MyExportMetadataPlugin:

	def onObjectMetadata(object):
		if (object is of some supported type):
			return generated metadata
		else:
			return None
			


def initialize_plugin():

	bpy.registerExportMetadataPlugin("MyEngineName",MyExportMetadataPlugin())
	

Exporters would only need to be modified to query and save this metadata from objects it cares about (like objects, meaterials, meshes, etc). It would just mean a tiny bit of code added like this:

metadata = object.export_metadata # some dictionary like { "MyEngine":{ExportDataForThisObject} }
converteMetadataToText(document,metadata)	

This would allow engines to create export metadata plugins to more efficiently transfer information from Blender to the respective engines.

@MartinHaeusler
Copy link

The ability to create/edit a material in Blender nodes and then use it in Godot sounds too good to be true. It would be awesome if that would work one day.

@Calinou
Copy link
Member

Calinou commented Mar 7, 2021

The ability to create/edit a material in Blender nodes and then use it in Godot sounds too good to be true. It would be awesome if that would work one day.

It will probably never work in all cases, as Blender shaders are often too complex to accurately replicate in a real-time game engine. That said, for basic PBR use cases, that should be possible already.

@reduz
Copy link
Member Author

reduz commented Mar 7, 2021

@Calinou afaik the conversor in the ESCN exporter can already do pretty complex Materials, so this is not so much of a problem. We would only need to copy this code to an export metadata plugin.

@aaronfranke aaronfranke added this to the 4.1 milestone Mar 7, 2021
@jcostello
Copy link

Te export of materials is as baked or as a shader?

@nonunknown
Copy link

Awesome, I was having some problems these days, so here's my opinion:

Improve the reimport workflow

The actual way if you, for example, modify the imported Model (take a gltf character model with two animations Idle and Run). If the user for example add a collision mesh inside the character (directly inside mesh/bones hierarchy), and after some time goes back to blender, and add a new animation, Jump, then the modifications get lost, and need to be remade

Support Blender's Softbody

This way the user can make a softbody directly inside blender and when reimported the softbody are reimported inside the engine with at least approximate precision

Improve auto material generated from mesh

Well, sometimes large scenes dont gets automatically texture when imported (other times it work). Also if the materials have some parameters made in blender (roughness/metallic) import that from blender too.

@jejay
Copy link

jejay commented Mar 7, 2021

  • UUIDs for Materials, nodes, etc. This way, if anything is renamed, the engine can keep track of it (including changes done in import, instancing or inheritance).

This is AFAIK currently not possible and will likely not happen. Object identity is preserved in memory only and should be lost once saved/reloaded. And I don't see a good reason for blender itself to implement UUIDs. Honestly its also an ugly and insufficient concept for what I expect you want to use it. If I copy objects, blender mostly does deep copies, except for the obvious like linked textures. So I need to make sure to not have a copy/delete workflow (which are very common in blender!) so that can Godot can make use of that information. On the other hand I might change an object so far that the changes I once applied in Godot and want to see re-applied on re-import (I assume that's what you want) don't make any sense anymore. If you really want to make this work robustly you'll need two way sync of metadata (or a "diff"). Otherwise you would violate the concept that it should be irrelevant how you arrive at certain identical result, given that blender supports so many workflows. You can obviously try to heuristically "hacksume" what the user wants, but even there I would prefer a feature based matching over obscure object identity that has no meaning in blender itself.

  • Blender Materials (shader graphs). Material export support is very limited in existing format. We could make the exporter just convert the Blender material to a Godot shader.
  • More detailed parameters on lights, cameras, IK, etc. that Godot supports but export formats do not.
  • Information on physics constraints, which Godot also does support.
  • Other types of objects such as Splines, which Godot supports (Collada actually supports this, but the other formats do not).

All these things can be easily accessed in the API. But I think you know that, just wanted to clarify for everyone else.

The solution is to do a small extension to blender created "Export Metadata Plugins", these plugins would be registered somehow in the Blender API (with an ID), then existing exporters would need to be modified to query every object exported for metadata (which would most likely return a dictionary associating the ID and the metadata), and save it using each format's extension support.

All these exporters are all written and maintained (or even not) by different persons. Every format is different in how it can handle meta information. You can program a similar functionality for an exporter locally already. What you propose is global setting that will create a lot of headaches, will still need to be implemented locally everywhere and might randomly work or not work dependent on which exporter it has been implemented in. I promise you they will hate that idea.

Edit: I just realised that I did not understand it 100% correct how you meant it, but I think this is still true to some extent. It might be easier to implement than I first thought, but its still something that needs to be implemented everywhere locally.

We currently have the Godot ESCN exporter for Blender, but this is a huge exporter and a large hassle to maintain. It would be much easier for us to piggyback on existing Blender exporters for metadata.

The right way to go is to pick the format that suits Godot best (e.g. gltf) and strategically work together with the blender people on that blender exporter instead of trying to force something globally onto blender core. There is no need that all blender export channels work equally good, imho. This is still more efficient than maintaining a direct exporter.

@ArdaE
Copy link

ArdaE commented Mar 8, 2021

As an alternative idea, why not a new custom exporter for Blender that piggybacks on an existing one to create a standard file (e.g. gltf) while also creating a companion file with all the extra information that Godot can use? You should be able to achieve all your goals this way without having to modify anything in Blender.

If desired, the two files can be combined into a single file by the super-exporter in order to eliminate any chances of the user unwittingly losing the synchronization between them e.g. by copying only one of them with the assumption that the other one isn't important.

@justinbarrett
Copy link

Sorry if "off topic" but I feel the expot for general purpose is pretty good at this point...though it is always a moving target with the frequency of updates between the two applications...I feel it would be far more useful to tackle full scene export..the direction you describe with getting more data from cameras and lights etc is a better direction....lending itself better for full level exports.
Handling the materials seems like it is better suited for how they are handled on import...e.g. if the material attached to a model has the same material in the resources of your project it should be recognized and automagically assigned. I don't speak for everyone ofc....but one of blenders "powers" is being more useful as a level editor as well. godot already recognized instances as instances from blender. Why not push this further?...like with the particles, physics, cameras and lights(as mentioned)..all in all, whatever does come of this, it should be helpful to someone...if not everyone.

@my-ijet
Copy link

my-ijet commented Mar 8, 2021

why not add an import of .blend files? This alone will solve a lot of problems

@antont
Copy link

antont commented Mar 8, 2021

This seems to boil down to having some way to store metadata about exports.

Apparently one place to store custom data is in scene properties, you can say:
bpy.context.scene.collection["yourPropertyName"] = "hello world"

Discussed in: https://devtalk.blender.org/t/store-variable-within-blender-scene/5070/5

It's also possible to save add-on specific preferences: https://devtalk.blender.org/t/how-to-save-custom-user-preferences-for-an-addon/10362

Maybe one of these existing places for storing metadata works for you, to store UUIDs and whatever you want to create at export time?

I think datablock custom props can also work, if you want to tie the data to the object, I don't get why generating at export time would be problem there.

But maybe the scene or addon data is good to collect the data for the whole export.

I think you basically just need to choose where you want to put the data.

@Saran-Pranavv

This comment has been minimized.

@reduz
Copy link
Member Author

reduz commented Mar 8, 2021

@jejay

This is AFAIK currently not possible and will likely not happen. Object identity is preserved in memory only and should be lost once saved/reloaded. And I don't see a good reason for blender itself to implement UUIDs. Honestly its also an ugly and insufficient concept for what I expect you want to use it. If I copy objects, blender mostly does deep copies, except for the obvious like linked textures. So I need to make sure to not have a copy/delete workflow (which are very common in blender!) so that can Godot can make use of that information.

As long as the plugin can tell when something is created or copied (does blender have callbacks for this?), the plugin can do the UUID itself and save it to the object metadata. I don't think this is a problem, nor it involves adding anything to Blender core.

All these things can be easily accessed in the API. But I think you know that, just wanted to clarify for everyone else.

Accessing is not the problem, the actual issue is that they need to be "converted" at export time. and saved as metadata in each format.

It might be easier to implement than I first thought, but its still something that needs to be implemented everywhere locally.

All the exporter needs to do is take the metadata and save it based on its text format. Metadata can be just strings for all I care.

The right way to go is to pick the format that suits Godot best (e.g. gltf) and strategically work together with the blender people on that blender exporter instead of trying to force something globally onto blender core. There is no need that all blender export channels work equally good, imho. This is still more efficient than maintaining a direct exporter.

Then we need to get into politics with Blender and with Khronos on what is a valid extension, what is valid for each game engine, etc. Because as this would be exporter wise and not metadata wise. This hugely raises the politics and maintenance burden on the Blender side and our side.

So I think you start getting the message here, this extension is explicitly to avoid getting into politics or design decisions with Blender. All we need is to export a custom string for each object type exported and be left alone, so we can export anything we want in the way we want and not get in your way. The only way I can see this happening is with an extension like the one I described.

@reduz
Copy link
Member Author

reduz commented Mar 8, 2021

@my-ijet the difficulty of doing this is so big that it's not even worth trying.

@antont
Copy link

antont commented Mar 8, 2021

export a custom string for each object type exported and be left alone

Blender properties seem to support that, for example that scene property place I mentioned above?

I think you can do what you want with current Blender, it has APIs for storing your own data and of course in the exporting you can write whatever you want. Blender already has the plugin system and metadata, you don't need a metadata plugin system, or in other words, it already has the metadata plugin system, no?

Exports can of course also create e.g. JSON or whatever addition metadatafiles externally, but those e.g. scene props seem to work if you want your data to stay within the blends, they get stored there.

Finally, I think you are free to use custom data in glTF also if you need that for some reason, usually formats have specificied support for extending and custom properties and using your own fields does not involve politics. I vaguely remember seeing this in glTF, it was in the predecessor COLLADA too.

@reduz
Copy link
Member Author

reduz commented Mar 8, 2021

@antont Blender properties are not useful for this because:

  • You need to generate this data on export. As an example, if you edited the material nodes in Blender, you would only want to generate a target engine shader at the time you are exporting the file, as this can be a costly process. Doing it at any other time is unnecessary and inefficient.
  • Custom properties are meant to be user-facing, there is zero benefit in users seeing data meant for the exporter.
  • Again remember, the use of this is to take data that already exists in blender (not that was created by the user) and send it to a game engine. It's a different use case (and hence, feature).

@reduz reduz closed this as completed Mar 8, 2021
@reduz reduz reopened this Mar 8, 2021
@reduz
Copy link
Member Author

reduz commented Mar 8, 2021

oops, closed by accident, ropened.

@jejay
Copy link

jejay commented Mar 8, 2021

As long as the plugin can tell when something is created or copied (does blender have callbacks for this?), the plugin can do the UUID itself and save it to the object metadata. I don't think this is a problem, nor it involves adding anything to Blender core.

I think this is an exhaustive list of callbacks of that sort. There is something to get notified when the dependency graph changes; you could then hack it like here by comparing/matching features. You would also need to save this information somewhere in blender (the properties metadata?) so that it can be persistent through save/load. I can really not see this coming to life in a core mechanism; but this is of course highly subjective.

All the exporter needs to do is take the metadata and save it based on its text format. Metadata can be just strings for all I care.
[...]
Then we need to get into politics with Blender and with Khronos on what is a valid extension, what is valid for each game engine, etc. Because as this would be exporter wise and not metadata wise. This hugely raises the politics and maintenance burden on the Blender side and our side.

If gltf can handle meta data (I'm not an expert here) then you could just do locally what you wanted to do globally. You don't need to change the spec / discuss with Khronos. BUT I agree that it could raise eyebrows because this circumvents the idea of open standards. What if people start to export stuff that actually can be handled by gltf (or any other format if you do it globally). In the long run it could hinder the standardisation process since it "already works somehow in blender". But all of this politics will be worse if you do it globally for all plugins than just on a single plugin locally.

@reduz
Copy link
Member Author

reduz commented Mar 8, 2021

@jejay

There is something to get notified when the dependency graph changes; you could then hack it like here by comparing/matching features. You would also need to save this information somewhere in blender (the properties metadata?) so that it can be persistent through save/load. I can really not see this coming to life in a core mechanism; but this is of course highly subjective.

It's not subjective, take as the best example converting Blender shaders to Godot shaders. This is costly and will take a while to do. The only place where this can be done efficiently is on export AND if the object is going to be exported, so a per exported object on callback can't be avoided.

What if people start to export stuff that actually can be handled by gltf (or any other format if you do it globally). In the long run it could hinder the standardisation process since it "already works somehow in blender".

There is no point in most of these things to be part of the spec. Again, we want to data that only Godot is meant to chew and process on import, there is zero interest by the format users in implementing this functionality in a standard way. Also if you are not exporting to Godot, then none of this will be added, as the extra metadata will only be present if you enable the Godot export plugins.

@jejay
Copy link

jejay commented Mar 8, 2021

It's not subjective, take as the best example converting Blender shaders to Godot shaders. This is costly and will take a while to do. The only place where this can be done efficiently is on export AND if the object is going to be exported, so a per exported object on callback can't be avoided.

Okay so if its just about identifying that the same material/shader has been used for 17 different objects, that is of course simple; as long as its is the exact same material/shader and has not been duplicated for e.g. a color change. I thought you meant identifying whether this shader is the same compared to the last export, which is quite complex as I described. Or rather impossible without feature matching.

What if people start to export stuff that actually can be handled by gltf (or any other format if you do it globally). In the long run it could hinder the standardisation process since it "already works somehow in blender".

There is no point in most of these things to be part of the spec. Again, we want to data that only Godot is meant to chew and process on import, there is zero interest by the format users in implementing this functionality in a standard way. Also if you are not exporting to Godot, then none of this will be added, as the extra metadata will only be present if you enable the Godot export plugins.

You already said that splines are in Collada, but missing in other formats ;-) If you want to make sure it works for all possible export formats you need to assume the common denominator which will lead to duplicate information. Another example: physics, I think you can't assume that no one else is interested in this. Apart from this, you need to sell the core changes to the blender team. You need to imagine what other people might want to do with it and how they can screw up. Otherwise they might tell you: If you want to export something specific, write a specific exporter. But as I said (and what I meant with being subjective) I am not a blender gatekeeper.

I think in general working on blender-Godot interoperability is awesome and I am really happy to see these thoughts here being proposed. But to be honest I would overall I would still prefer the concept behind the Godot ESCN exporter for Blender. You can just do so much more. Imagine it could tell you directly in blender which objects in your project it can't process / don't know what to do with. You could have a whole "Godot compliance" window/panel. There are really some additional possibilities that might make the hassle worth its time. Maybe more people (like myself) would be won as contributors if it would be strategically announced as the path to go.

@reduz
Copy link
Member Author

reduz commented Mar 8, 2021

@jejay

Okay so if its just about identifying that the same material/shader has been used for 17 different objects, that is of course simple; as long as its is the exact same material/shader and has not been duplicated for e.g. a color change. I thought you meant identifying whether this shader is the same compared to the last export, which is quite complex as I described. Or rather impossible without feature matching.

I think you are misunderstanding this. All I mean is that from the time you edit the material in Blender to the time it's exported, it needs to be converted at some point in time to a Godot shader for export as metadata. So, when do you do this? Currently there is no proper time or callback to do this conversion, but if Blender had these callbacks, which would be the best time?

  • Callback on editing: Would force generating the Godot shader every time, making things inefficient.
  • Callback before exporting: If Blender had this callback, it could work because shader would be generated and stored in the object metadata (then exporters would not need to be modified). It's not entirely ideal because then this data will persist in the .blend file and because the material might be generated even if the material is not actually exported.
  • Callback to obtain data on export: This callback is called for every object exported only if exported. The data generated is never stored within Blender (does not need to be). Only drawback is that exporters need to check this, like they do with the custom metadata.

So, where should this happen?

@antont
Copy link

antont commented Mar 8, 2021

@antont Blender properties are not useful for this because:

  • You need to generate this data on export.

So what's the problem of saving data to properties at export? Blender has the same API at editor use and at export time, you can create e.g. the UUIDs when you want.

  • Custom properties are meant to be user-facing, there is zero benefit in users seeing data meant for the exporter.

Maybe you can hide them?

Also, am not sure that e.g. scene properties are visible anywhere in the GUI, maybe they are, but it does not seem like a showstopper that the metadata would be visible somewhere.

If hidden properties are not supported yet, and there is no other good place to save the data, maybe the property UI hiding would be a useful feature on the Blender side for this.

  • Again remember, the use of this is to take data that already exists in blender (not that was created by the user) and send it to a game engine. It's a different use case (and hence, feature).

Different from what?

Properties are AFAIK fine for custom data e.g. for your art pipeline., like the UUID you used in the export or some material setting or whatever, no?

@reduz
Copy link
Member Author

reduz commented Mar 8, 2021

@antont Using hidden properties could work, but there are still two things that need to be changed in Blender.

  • A pre-export callback is needed (before the exporter runs), so data (such as shaders) is generated for use in the exporter.
  • A flag to indicate that the hidden property needs to be exported. By default, exporters don't export custom data in Blender, so this can be an usability problem. Users would activate the plugin and nothing would happen.
  • For the expected work honestly, It still sounds like my proposal is simpler, more efficient, and more to the point than doing this.

@ArdaE
Copy link

ArdaE commented Mar 8, 2021

Allowing the expansion of an existing format with not-so-well-defined extensions is a very dangerous slope. Imagine what'll happen if e.g. Unity were to take advantage of the new "Export Metadata Plugins" you propose. You'll end up with countless artists exporting and sharing/selling models in various standard formats that include metadata that only Unity understands, and because the files are "standard" (same extension and fully compliant with the standard assuming the standard allows such loose metadata), everyone would expect Godot to support them too. (Replace the word "Unity" with any other 3D tool/engine name here; do the same for "Godot"). This would undermine interoperability among 3D tools/engines, in a field where interoperability is already a major issue. Any expansion of a standard format should be registered with the standardization body, imo, even if it's a custom one.

I think your best bet is still to define a new file format, with a different extension, that combines a standard file with a custom companion file. This would make it clear to everyone that this is a Godot-only export format, while you'd take full advantage of an existing Blender exporter for most of the functionality.

@jejay
Copy link

jejay commented Mar 8, 2021

@reduz

So, where should this happen?

  • Option 1 might look fancy if you can make it work on a differential basis but there is no straight forward way to do it except querying the whole scene every time something changes.

  • Option 2 is a little bit unspecific. When exactly before exporting? You'd still need to update it according to edits. And yeah there is still no callback I know of that does this.

  • Option 3 is probably the typical lemma for this.

@reduz
Copy link
Member Author

reduz commented Mar 8, 2021

@ArdaE That's just too much speculation imo, and does not solve any problem.

@reduz
Copy link
Member Author

reduz commented Mar 8, 2021

@jejay

Option 1 might look fancy if you can make it work on a differential basis but there is no straight forward way to do it except querying the whole scene every time something changes.

This is impractical from any angle you see it.

Option 2 is a little bit unspecific. When exactly before exporting? You'd still need to update it according to edits. And yeah there is still no callback I know of that does this.

Well, exporters are registered and activated in the Blender API , before activating them (calling the export function) you call this callback and all conversions and storing metadata in objects takes place.

Option 3 is probably the typical lemma for this.

Well, this proposal is clearly the simplest and most practical way to implement this in my opinion.

@marcotrosi
Copy link

Hi guys, I have a question, and I hope it's the right context for that. If not please forgive me and ignore my question.

Why all this importing and/or exporting? In my mind I just would like to connect ones a blend file (or many) with my Godot project, and if the blend files changes Godot shall notice and ask if I would like to update my Godot project. Maybe you know from Blender how you can import specific parts from another blend file. Similarly I would like to select in Godot which parts of the blend file I would like to connect with my Godot project. What is your opinion on that?

@reduz awesome project btw. thank you.

@reduz
Copy link
Member Author

reduz commented Mar 8, 2021

@marcotrosi parsing blend files is extremely difficult and a moving target, totally out of the picture. Everyone gave up on this long ago.

@SIsilicon
Copy link

@reduz Well technically, you could just leave the blender parsing to blender. Call an exporter function (like ESCN exporter) via OS.execute() and have the results be the imported data.
Obviously the main disadvantage would be a dependency on blender, but honestly, most people who would use such an importer would likely have blender installed already.

@reduz
Copy link
Member Author

reduz commented Mar 8, 2021

@SIsilicon sure but it misses the whole point of the proposal.

@SIsilicon
Copy link

SIsilicon commented Mar 8, 2021

@reduz Indeed it does. Just wanted to point out that possiblity since you brought it up. We can drop that subject for now.

@Calinou Calinou changed the title Changes to Blender to improve engine export support. Changes to Blender to improve engine export support Mar 9, 2021
@antont
Copy link

antont commented Mar 9, 2021

@antont Using hidden properties could work, but there are still two things that need to be changed in Blender.

Ok, so maybe we can consider that part solved: existing data storage in Blender works for this need.

  • A pre-export callback is needed (before the exporter runs), so data (such as shaders) is generated for use in the exporter.

That is simple to add, if needed.

But why do you need a callback, when the exporter itself can call the pre-export work too?

It can be either a part of Blender, or just a part of the API for exporters, to call some code to run before the export. That's easy and can be done in any exporter today.

  • A flag to indicate that the hidden property needs to be exported. By default, exporters don't export custom data in Blender, so this can be an usability problem. Users would activate the plugin and nothing would happen.

I don't get what you say here.

Isn't it your code that creates the data?

Say you want to create UUIDs for the objects you export. You store them in object or scene properties in Blender, from your exporter.

You don't need any flag, it can be a feature that's on by default, that you create UUIDs and convert materials how you want. It's just how exporting works, I don't see anything that would lead to usability problems .. just press export and it works.

  • For the expected work honestly, It still sounds like my proposal is simpler, more efficient, and more to the point than doing this.

I don't understand what you propose yet.

Just using current Blender API seems straightforward, with the possible addition of an option for export machinery to hide properties if that's necessary, and would anything else be needed even? If a callback hook is useful, that's easy to add too, but I don't get why that would be necessary even, as it's easy to first execute pre-export things and then export code without too, no?

@Flavelius
Copy link

Maybe using custom properties prefixed with a special godot tag that are stripped on import could work. I think exporting an extra file just to transfer some values is unnecessary, also because those will likely not take much space in the file anyway. And if they're stripped for the imported asset there's no additional 'space wasted'.

@antont
Copy link

antont commented Mar 10, 2021

I dont think exporters typically write custom props anyway by default. But yes it's easy to decide in the exporter what data you want to write and what not.

@Riteo
Copy link

Riteo commented Mar 30, 2021

@Flavelius IMO a separate file would be better, but if there's data added to the file IMO it should have a custom extension or something, as @ArdaE pointed out this would cause a lot of hassle for other engines and potentially, viceversa.

Going the import-.blends-by-depending-on-blender route that other people proposed is simply impossible. I tried using Unity's .blend support a long time ago and over time my projects quickly messed up, expecially in the big 2.8 update.

IMO a whole metadata exporter system is a bit overkill. Isn't there a way of attaching to an export event on blender? An other idea that comes to mind would be to simply "fork" or at least extend in some way the code of an already existing exporter (maybe an exporter that calls another one? I don't know that well Blender's API, but I think that should be possible). Also, as I said before, embedding the data into the model without an extension change doesn't sound like the greatest idea ever, since one could share it and get used by others not using godot, leading to confusion. IMO a simple metadata file would be the best option, as we already do similary things with .import files (why don't we simply export an .import file with special data on it?).

@antont
Copy link

antont commented Mar 31, 2021

@Flavelius IMO a separate file would be better, but if there's data added to the file IMO it should have a custom extension or something, as @ArdaE pointed out this would cause a lot of hassle for other engines and potentially, viceversa.

If you mean .blend files, those are already extensible by design: you can add custom properties to Blender datablocks, such as objects and scenes, if that's useful for your workflow. No problems there, no need for custom extensions.

They get saved automatically, and are not really a hassle for other engines, because tools for other engines don't need to care about Godot metadata. Then again, having a common UUID system for wider use with Blender might be interesting too and something that Blender devs were open to when this was discussed there.

If you mean some export format, that's another thing.

Going the import-.blends-by-depending-on-blender route that other people proposed is simply impossible. I tried using Unity's .blend support a long time ago and over time my projects quickly messed up, expecially in the big 2.8 update.

Unity does not even try to read .blend files. The blend import in Unity works so that Unity runs Blender in the background and does an automated FBX export. So it works the same as doing FBX export from Blender manually, is just automated. This is invisible to the user, but it requires installing Blender to the system first.

It's possible to read .blend files but I don't recommend that either.

IMO a whole metadata exporter system is a bit overkill. Isn't there a way of attaching to an export event on blender?

Yes there is. Basically everything in this proposal can be done with the current Blender Python API. The 'export event' works so that exporters register to Blender, as an export add-on, and then they show in the File-Export menu. Then when the user triggers the export from there, Blender calls the export plugin/addon/script. Then the exporter can write all the metadata and data it wants.

IMO a simple metadata file would be the best option, as we already do similary things with .import files (why don't we simply export an .import file with special data on it?).

Yep, it's possible to put e.g. the object UUIDs either to the .blend file, as custom properties in Blender, or in .import files.

Putting the export metadata to the .blend can be good because then when people copy blend files across places, but mean to keep it so that when they re-import it to update something in Godot, then e.g. the UUID info has followed.

But if it's fine for people to copy both .blend and .import files that works too.

@Riteo
Copy link

Riteo commented Mar 31, 2021

@antont sorry, most things I said were misunderstood due to the way I wrote them.

If you mean some export format, that's another thing.

Yes, I meant that as reduz talked about saving this metadata "using each format's extension support".

I agree that an UUID system might be cool but only if generalized in blender, otherwise not that much.

Unity does not even try to read .blend files.

I am aware of this, but the update to blender 2.8 messed up the names of the exported objects plus a few other issues. When I was talking about that import-.blends-by-depending-on-blender route I wanted to imply that but failed to see that it could've been misinterpreted. Again, my bad.

IMO the real juicy part here is built-in UUID support, the rest can be avoided.

@antont
Copy link

antont commented Mar 31, 2021

@antont sorry, most things I said were misunderstood due to the way I wrote them.

Ah ok. Quick notes:

I think the UUID thing can well be useful even for just Godot only. We did it ages ago for an extended Ogre3D exporter, was good to have UUIDs in Blender so that you could reliably update scenes via exports, it worked well.

It's easy to use Blender custom properties for the UUIDs today, IIRC that's what we used 8 years ago too.

If Godot exporter wants to start making and using UUIDs I think you can just do it. If Blender gets some sort of standard UUIDs later, maybe the Godot work can be a step towards that. Or if they remain exporter specific I think that's fine too, when the point is simply to make re-exports update game engine side things reliably. It's especially important when you add things to the exported objects on the game engine side.

@fire
Copy link
Member

fire commented Jan 5, 2022

@reduz Where are we at completing this feature proposal? Not happy it's an omnibus issue, and would prefer to break the proposals into individual ones.

@YuriSizov YuriSizov moved this from In Discussion to On Hold in Godot Proposal Metaverse Jul 21, 2022
@YuriSizov YuriSizov moved this to In Discussion in Godot Proposal Metaverse Jul 21, 2022
@RedMser
Copy link

RedMser commented Aug 18, 2022

Another perspective I haven't seen mention of yet is augmenting the glTF exporter specifically. I looked further into this as part of godotengine/godot#63457 and these are my observations:

  • glTF has two ways of extensibility: extras and extensions
  • Extras are used for application-specific metadata, which sounds a lot like the use-case this proposal is going for.
    In Blender's exporter, every Custom Property of a datablock is turned into an "extra" (allowing for custom conversion functions to_list and to_dict on classes). Downside is the addon would have to store these redundant properties, which are just mirrors of actual blender props. Juan already mentioned he does not want this.
  • Extensions enable "the addition of both general-purpose and vendor-specific extensions". While a prefix must be registered at the Khronos repository, they are not officially maintained and can be developed independently from glTF. The main difference is that there is a nice API for Blender to create an extension, basically allowing to intercept the creation of any glTF node and insert the required extension with additional metadata in that place.
    I can't find good example code that works online, but in this MRP for the above-mentioned PR I created a sample project that includes such a Blender addon, whose extension is parsed by GLTFDocumentExtension.
    To summarize: create a class glTF2ExportUserExtension in the addon, which can hook into certain export steps.

For this proposal, I don't see any obvious reasons going against a glTF extension.

  • We don't need to create a custom metadata export pipeline that must be supported by all major exporters.
  • We also don't need new mechanisms to handle the metadata on import. Simply use the existing GLTFDocumentExtension to retrieve any node's json["extensions"] and augment the imported objects - or alternatively, hard-code the extension handling directly into the core classes like GLTFLight and similar.
  • Users that work with Blender already prefer using glTF or Blend file imports into Godot, since those yield the best results anyway.
  • The glTF addon has a simple extensible API to add new extensions at export-time, which avoids polluting the working file with redundant properties.
  • It would still be possible to create custom Godot-specific UI and corresponding properties (e.g. "Skip Export", lightmap/occlusion/navigation settings, ...) and integrate those into the extension as well.

One issue is ensuring that the addon is enabled when the Blender executable is launched by Godot. Possibly look into --addons or --python command line switches.

@Calinou
Copy link
Member

Calinou commented Aug 18, 2022

  • Extras are used for application-specific metadata

There's a proposal about accessing glTF extras from Godot: #4968

@RedMser
Copy link

RedMser commented Aug 18, 2022

There's a proposal about accessing glTF extras from Godot: #4968

@Calinou Yes, it's mine :)
But that's for providing an API to the user. This proposal talks about metadata handled by the engine, which would not need such an API.
Reading extras/extensions is already possible via the GLTFDocumentExtension mechanism that allows to hook into the glTF import, it just wasn't fully exposed to users yet.

@fire
Copy link
Member

fire commented Sep 16, 2022

What is remaining on this? Can we close?

@aaronfranke
Copy link
Member

aaronfranke commented Apr 8, 2023

As of this PR godotengine/godot#66026 there is now support for arbitrarily extending Godot's GLTF importer to handle any extension metadata with GLTFDocumentExtension in Godot 4.0 and 3.6. So that part of this proposal is done.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: On Hold
Development

No branches or pull requests