Geometry Nodes: new Bake node #115466
No reviewers
Labels
No Label
Interest
Alembic
Interest
Animation & Rigging
Interest
Asset Browser
Interest
Asset Browser Project Overview
Interest
Audio
Interest
Automated Testing
Interest
Blender Asset Bundle
Interest
BlendFile
Interest
Collada
Interest
Compatibility
Interest
Compositing
Interest
Core
Interest
Cycles
Interest
Dependency Graph
Interest
Development Management
Interest
EEVEE
Interest
EEVEE & Viewport
Interest
Freestyle
Interest
Geometry Nodes
Interest
Grease Pencil
Interest
ID Management
Interest
Images & Movies
Interest
Import Export
Interest
Line Art
Interest
Masking
Interest
Metal
Interest
Modeling
Interest
Modifiers
Interest
Motion Tracking
Interest
Nodes & Physics
Interest
OpenGL
Interest
Overlay
Interest
Overrides
Interest
Performance
Interest
Physics
Interest
Pipeline, Assets & IO
Interest
Platforms, Builds & Tests
Interest
Python API
Interest
Render & Cycles
Interest
Render Pipeline
Interest
Sculpt, Paint & Texture
Interest
Text Editor
Interest
Translations
Interest
Triaging
Interest
Undo
Interest
USD
Interest
User Interface
Interest
UV Editing
Interest
VFX & Video
Interest
Video Sequencer
Interest
Virtual Reality
Interest
Vulkan
Interest
Wayland
Interest
Workbench
Interest: X11
Legacy
Blender 2.8 Project
Legacy
Milestone 1: Basic, Local Asset Browser
Legacy
OpenGL Error
Meta
Good First Issue
Meta
Papercut
Meta
Retrospective
Meta
Security
Module
Animation & Rigging
Module
Core
Module
Development Management
Module
EEVEE & Viewport
Module
Grease Pencil
Module
Modeling
Module
Nodes & Physics
Module
Pipeline, Assets & IO
Module
Platforms, Builds & Tests
Module
Python API
Module
Render & Cycles
Module
Sculpt, Paint & Texture
Module
Triaging
Module
User Interface
Module
VFX & Video
Platform
FreeBSD
Platform
Linux
Platform
macOS
Platform
Windows
Priority
High
Priority
Low
Priority
Normal
Priority
Unbreak Now!
Status
Archived
Status
Confirmed
Status
Duplicate
Status
Needs Info from Developers
Status
Needs Information from User
Status
Needs Triage
Status
Resolved
Type
Bug
Type
Design
Type
Known Issue
Type
Patch
Type
Report
Type
To Do
No Milestone
No project
No Assignees
8 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: blender/blender#115466
Loading…
Reference in New Issue
No description provided.
Delete Branch "JacquesLucke/blender:bake-geometry-nodes"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
This adds a new
Bake
node which allows saving and loading intermediate geometries. Typical use cases we want address with this currently are:For now, the format that is written to disk is not considered to be an import/export format. It's not guaranteed that data written with one Blender version can be read by another Blender version. For that it's better to use proper interchange formats. Better support for those will be added eventually as well. We also plan an
Import Bake
node that allows reading the blender-specific baked data independent of the Bake node and at different frames.The baking works very similar to the baking in the simulation zone (UI and implementation wise). Major differences are:
Bake Still
andBake Animation
mode.After this basic implementation is merged, we can focus on making bake functionality available in other places in the UI (like the outliner) to improve the workflow in a production. For now, the focus lies on getting similar UI features for simulation-baking and the bake node.
Implementation details:
ModifierCache
stores an independent map ofSimulationNodeCache
andBakeNodeCache
, but both share a common data structure for the actually baked data.Bake
node is added as a side-effect-node in the modifier. This will make sure that the node is baked even if it's currently not connected to the output.DEG_id_tag_update_for_side_effect_request
function that is used during baking. It's necessary because I want to evaluate the object again even though none of its inputs changed. The reevaluation is necessary to create the baked data. UsingDEG_id_tag_update
technically works as well, but has the problem that it also uses theDEG_UPDATE_SOURCE_USER_EDIT
flag which (rightly) invalidates simulation caches which shouldn't happen here.NodeBakeRequest
which makes the code easier to follow compared to the previous nestedObjectBakeData > ModifierBakeData > NodeBakeData
data structure.Bake
nodes andSimulation Zones
. On top of that, there are separate operators of baking and deleting all simulation bakes (those ignore bake nodes).Bake
node remembers which inputs have been fields and thus may be baked as attributes. For that it uses anIs Attribute
flag on the socket item. This is needed because the baked data may still contain attribute data, even if the inputs to the bake node are disconnected.Bake
nodes is passed into the geometry nodes evaluation from the outside (from the modifier only currently). This is done by providing the newGeoNodesBakeParams
inGeoNodesCallData
when executing geometry nodes.Next Steps (mostly because they also involve simulations):
I have built with the latest commit and it seems to work pretty well (MacOS, M2 Max).
Some minor things: material is lost on baking (example):
I wasn't able to get the baking to work unless I used a custom path, but then I realised I needed to have the file saved somewhere for the automatic path to work. Maybe a warning / message that the file hasn't been saved yet in the node, as the default is to not use a custom path.
I also conducted some tests, but first, as a disclaimer, my intended use case is not the typical intended use of 'baking.' The problem I aimed to solve is: how can I transfer instances (or any multi-component geometry) created through GN to a client without giving them the whole GN setup? Using the bake node, it's now possible.
As I mentioned, I don't believe the purpose of baking is to be used as a general 'geometry set' import-export format, nor as a substitute for applying modifiers to multi-component geometry; this would be better done as part of the old 'geometry object' proposal.
With that context in mind, here are some points I have found:
Crash:
Bug:
Thanks for testing!
That's still a known issue unfortunately. The underlying issue is the same as for simulation baking. It will be fixed by #109703.
I disabled the bake button now when the file is not saved yet.
It is a typical use case, but not one we are trying to solve right now with this patch. In general, each
Bake
node should have a separate bake path. We do plan to have a separateImport Bake
node that will allow you to do what you want, and more. This goes more in the direction of general import and export in geometry nodes which we'll get to a little later. I think some of your comments invalidated by this for now.Could be solved as part of the copy node operator but doesn't have high priority right now since we don't really want people to use the same file path in two bake nodes.
Next time please try to provide more exact steps to reproduce the issue (and a .blend file). I committed a fix now that I believe also fixes your issue, but hard to be sure.
WIP: Geometry Nodes: new Bake nodeto Geometry Nodes: new Bake node@Sergey For the bake operator to work well I had to add a new
DEG_id_tag_update_for_side_effect_request
function. It's similar toDEG_graph_id_tag_update
but usesDEG_UPDATE_SOURCE_SIDE_EFFECT_REQUEST
instead ofDEG_UPDATE_SOURCE_USER_EDIT
asupdate_source
. This is necessary, because I want to trigger a reevaluation of an object even though none of its dependencies have changed. The reevaluation is required because the to-be-baked geometry is generated during the modifier evaluation.Using
DEG_graph_id_tag_update
technically works, but also (rightly) causes e.g. simulation caches to invalidate because ofDEG_UPDATE_SOURCE_USER_EDIT
. Those shouldn't be invalidated because I'm not actually changing any dependencies.Does this sound ok to you?
@blender-bot build
This looks fairly straightforward actually. I left some inline comments, but nothing that needs another review iteration I don't think.
@ -1148,0 +1199,4 @@
layout.use_property_split = True
layout.use_property_decorate = False
layout.prop(active_item, "socket_type")
if active_item.socket_type in {'VECTOR', 'INT', 'BOOLEAN', 'FLOAT', 'RGBA'}:
This is missing rotation sockets
@ -298,0 +306,4 @@
NodesModifierData &nmd = *request.nmd;
bake::ModifierCache &modifier_cache = *nmd.runtime->cache;
const bake::NodeBakeCache *bake_cache = nullptr;
switch (request.node_type) {
How about splitting this to a function called
get_node_bake_cache
or something?@ -820,0 +892,4 @@
if (BKE_main_blendfile_path(bmain)[0] == '\0') {
/* Saving the .blend file is not technically necessary in all cases but only when the bake path
* depends on the .blend file path (which is the case by default). */
CTX_wm_operator_poll_msg_set(C, TIP_("Save file before baking"));
I think it's a bit more consistent/friendly if this is phrased more like
File must be saved before baking
.Also
TIP_
is unnecessary here, these are extracted by a regex and translated inside@ -292,6 +292,7 @@ DefNode(FunctionNode, FN_NODE_VALUE_TO_STRING, 0, "VALUE_TO_STRING", ValueToStri
DefNode(GeometryNode, GEO_NODE_ACCUMULATE_FIELD, 0, "ACCUMULATE_FIELD", AccumulateField, "Accumulate Field", "Add the values of an evaluated field together and output the running total for each element")
DefNode(GeometryNode, GEO_NODE_ATTRIBUTE_DOMAIN_SIZE, 0, "ATTRIBUTE_DOMAIN_SIZE", AttributeDomainSize, "Domain Size", "Retrieve the number of elements in a geometry for each attribute domain")
DefNode(GeometryNode, GEO_NODE_ATTRIBUTE_STATISTIC, 0, "ATTRIBUTE_STATISTIC",AttributeStatistic, "Attribute Statistic", "Calculate statistics about a data set from a field evaluated on a geometry")
DefNode(GeometryNode, GEO_NODE_BAKE, rna_def_geo_bake, "BAKE", Bake, "Bake", "Cache the incoming data so that it can be used without computing it every time")
computing it every time
->without recomputation
maybe?@ -0,0 +413,4 @@
return false;
}
r_ctx.bake = nullptr;
for (const NodesModifierBake &iter_bake : Span{r_ctx.nmd->bakes, r_ctx.nmd->bakes_num}) {
I usually prefer the
()
constructors, they're a bit more well defined and safe in general@ -0,0 +454,4 @@
}
else {
SNPRINTF(
str, N_("Baked %d - %d"), int(ctx.baked_range->first()), int(ctx.baked_range->last()));
N_
doesn't really make sense here. If it's translated later, that will include the numbers which will make the lookup fail.How about including
<fmt/format.h>
and usingreturn fmt::format(TIP_("Baked {} - {}"), ctx.baked_range->first(), ctx.baked_range->last());
Just replacing it with
TIP_
seems fine as well. Don't really want to start using<fmt/format.h>
here now, I haven't looked into it much yet.It's used in other similar places. It's a required dependency, and it's just a much nicer way to do that sort of formatting that's faster and doesn't require the temporary buffer.
@ -0,0 +569,4 @@
}
}
static void node_rna(StructRNA *srna)
Might as well just remove this?
Functionality wise this works great in my tests! My feedback is mainly about UI/UX.
So other than the things mentioned below and the loss of materials I think this is mainly just leaving open the need for better interaction with the bake settings/baking itself in an overview like the outliner, that we talked about.
Regarding your question of the frame range:
I think that it is reasonable to fall back to the same range as the simulation baking. While the main reason for detaching that range with simulations is preroll, which is not necessarily something that is needed for baking animated data, it is reasonable to assume that some of the simulation might rely on data that uses a bake node. So I think it makes sense to use the same by default and rely on the custom range , if people need to change this.
UI
Bugs/Issues
UX
Since there might very well be a dependency between different bake and simulation nodes, I personally don't think it would be too unreasonable to provide a button that bakes both at the same time in the physics panel. At least until the better solution exists.
I fixed some of the issues you mentioned. Others I added as next steps to the patch description.
Could work in theory, but it's fairly difficult to implement I think.
What do you mean by "the context" here exactly?
I think it's definitely something we need, but I'd like to keep separate if possible to be able to make progress..
I'm really not a fan of adding a button for baking all bake nodes without any kind of tagging. We could do it as a last resort if we don't manage to finish something more useful for the release. Implementation wise it's easy.
Here, by context, I mean all bakes of all modifiers of all selected objects. This ties in to your last point as well.
We definitely need some sort of handling for baking several bakes without needing to hunt them down individually. I'm fine with handling that in a separate task, but if the final solution is not ready for 4.1, I'd strongly suggest to go for a simpler approach that at least gives some of that functionality.
In my personal opinion, the need for baking in the bake node and the simulation zone is really not too different. So handling them the same, even before the nice overview is available, would make sense to me.
@blender-bot build
Okay, with greying out the mode when it's baked I also meant that you shouldn't be able to change it. I should have been more specific about that. You can still change it atm. Now I'm noticing that this is also the same with the other settings in the properties panel. Shouldn't these be locked for the UI while they are greyed out? I don't see a use-case for changing these after baking.
I see you added a warning in node and modifier when Blender fails to load the bake data, that's great! I'm a bit confused that this is not the case after I bake and directly delete the bake data from disk. Does Blender keep all of it in memory from the baking process? This changed since your last update, right?
Once I change the active object the bake data seems to be lost but the warning does not show up. Would be good if this could be more consistent with the data that is actually there on disk if possible.
Other than that this looks good to me as the initial state tbh.
What is your plan regarding exposing the bake functionality in other places? Again, imo this is a topic that definitely needs to be addressed in some way for the release, even if the proper solution will not be ready in time.
Done.
Yeah, Blender keeps the bake in memory, same with simulations. I think there was a related bug were it would try to reload on every evaluation. Maybe the change in behavior you found is caused by that. It's fairly clear to me that we don't want to access the disk on every evaluation as that can be slow (even just checking if a file is still there).
Not entirely sure what changing the active object has to do with that. I think I don't understand what you mean.
I want to start working on that next week.
@blender-bot build
I was mainly surprised that the behavior changed. And yes, of course we should keep the data in memory and not reload it from disk all the time. I wasn't sure how expensive checking the existance would be, but it's fine with me to only do that when the files actually need to be read.
I figured out that the issue of changing the active object was my fault, I was using the viewer node. Just confirmed that this is working as expected.
Okay, just gave it another quick check, for me this is good to go!
@blender-bot build
Was wondering, for quick playback - does this data live in a array on the gpu or is the geo still fed each frame to the gpu?
Is it possible to add frame offset option for baked animation? like in mesh cache sequence modifier
This is not planned currently. Instead we want to have a separate Import Bake node where you can load any frame you want.
cache node crash Blender every time with GN hairs
@ramonkarlos please create a proper bug report with instructions on how to replicate the issue, so it can be investigated and fixed.