WIP: Single-frame job compiler #104194
No reviewers
Labels
No Label
Good First Issue
Priority
High
Priority
Low
Priority
Normal
Status
Archived
Status
Confirmed
Status
Needs Info from Developers
Status
Needs Information from User
Status
Needs Triage
Status
Resolved
Type
Bug
Type
Design
Type
Job Type
Type
Known Issue
Type
Patch
Type
Report
Type
To Do
No Milestone
No Assignees
3 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: studio/flamenco#104194
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "k8ie/flamenco:single-frame"
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?
Same as #104189, aims to implement #104188. I accidentally closed the original PR by typing into the wrong window. I am very sorry about that.
Current task list:
Split the logic for the tiling into a function so that I can use it again for denoising
Denoising - I'll reuse the above mentioned tiling logic
The tiling logic math could use splitting into human-understandable variable names
Replace
os
withpathlib
Create helper variables for
bpy.context.scene
, etc.Reject when not using Cycles
Fix merging being totally broken when using denoising (don't know the cause)
Don't hard-code EXR layer names, they might change between Blender versions
Don't hard-code the scene name, the scene can be renamed by the user
46a83336f5
tob9aca93b54
No worries, things like that happen.
When you want me to review, be sure to remove the
WIP:
prefix from the title.Hi, I rewrote the chunking to be tile-based.
Overall this seems to work very well, path guiding works as expected. I still don't have overlap between tiles for adaptive sampling to work because I don't know how exactly I would go about cropping them before the merge.
There is one regression that bothers me quite a bit. I switched to using the compositor to merge the image. The node network I use looks like this:
The problem with this approach is that in order for the merge to happen, Blender has to keep all the files in memory. In a test with a 1080p image split into 100 tiles, the memory usage for a merge was ~4GB. 12GB for the same image but with denoising.
I thought about splitting the merging into separate tasks, but I don't know if that would be the ideal approach especially when you compare Blender's startup time with the amount of time it takes to merge two tiles.
There is another issue, and that is keeping the denoising data from the individual tiles. I'm not aware of any way to get the denoising data back into a multi-layer OpenEXR outside of the "File Output" node. This node allows adding an arbitrary amount of input sockets which will be stored in layers in the EXR file. I think I've read that the File Output node is a pretty hacky thing to use, so I would like to avoid using it if possible.
You made some nice progress!
About the memory usage, I think
bpy.context.scene.render.use_crop_to_border = False
is the culprit. If you set that toTrue
, the image files will be much smaller, and only contain the rendered pixels. Of course you'll get a bit more complex flow with the merging, as you have to position each image correctly.As for the Python code, there are some things to adjust.
bpy.context....
everywhere. It's harder to read, and it's also slower for Python to execute (but that doesn't matter too much in the grander scheme of things). If you need repeated access to the scene, just usescene = bpy.context.scene
and then usescene
. Same for accessing the node tree, etc.${settings.tile_size} / 100
, so just calculate that once, put the result in a variable, and use that instead. Having said that, I think it might be better to just input the desired number of tiles? The JS code can then determine how to split up the frame into that many tiles by itself. This avoids having to deal with remainders, like passing 33% as the tile size, but that leading to four tiles (3x 33% + 1x 1%).os.path
for handling paths. Restricting yourself topathlib.Path
will reduce the number of APIs you use, and make things simpler to read and understand. And it'll be less fragile. To make things a little shorter, you can usefrom pathlib import Path
..
Hi, thanks for the feedback. You're probably right about the tile cropping and memory usage, fixing that is priority number one for me at the moment.
Sorry about the development being slower and slower, I have a bunch of IRL stuff that keeps me pretty busy, but rest assured, I'd still like to finish implementing this and get this merged.
That's fine, you working at a slow pace on this is still infinitely faster than me not doing anything at all here ;-)
Alright, I finally got the memory usage under control. I still have a few things to do tho.
os
withpathlib
bpy.context.scene
, etc.Oh, and looks like the merging doesn't work as expected for some tile sizes (interestingly enough, only the nice ones that fit the image exactly like 50%, 10%, etc.).
Please don't track sub-tasks in a comment, just edit the PR description and put them there. That way Gitea recognises them (it shows like
3/5
in the PR list) and your local reviewer doesn't have to scroll up & down to find them ;-)Oh, ok, that makes sense, sorry 😅
Is faaaaaaaaaaaaaaain, we all learn all the time ;-)
Alright, I think I'm pretty much done with the implementation of denoising.
There is an issue I ran into though. When combining the Denoising Albedos and Normals, the results are glitchy.
What's even weirder is that every time I run the composite, the result is glitched out in a different way.
I'll attach the two tiles I'm testing with.
This node network:
Results in this image:
For the complete context, this is the full node network I use:
Do you have any idea why this could be happening?
Sorry, I don't have the time to dive into this myself.
@dr.sybren No worries ;)
Hey! How's the progress? The PR is still marked as 'work in progress', so I haven't looked at it in depth. Is there anything that's blocking you from removing the 'WIP' prefix?
Hey, I haven't worked on this for a while.
Last time I checked, I still had this happening when tiling denoising data together. I (hopefully) left enough info in that comment for anyone to be able to try it manually in Blender and reproduce the issue. The two EXR files used are included.
Unrelated - I think the layer names may have changed in EXRs somewhere between Blender versions, I'll need to account for that. (I'll add that to the original comment, should be pretty easy to do)
Otherwise I believe it should be pretty much ready. Just some cleanup here and there. Nothing huge other than that pesky tiling issue.
Did you file a bug report for Blender itself? If not, then this isn't going to get fixed. Blender developers (well, except me) aren't going to check this repository to find bugs. So if you haven't, please report it.
It would help to keep track of what still needs doing in the PR description. That way its current status is clear for anyone looking at it (without having to read through each comment in detail).
I didn't file a bug report, I'll try doing that hopefully this week. Thanks for the pointer.
Yup, that's what I meant 😉
It's added in there as a checkbox.
@dr.sybren I have reported the issue upstream, we'll see what we learn 😉
75f8068eae
to9048b23eb6
Heyyyy you're back!
Please be aware that @David-Zhang-10 is also working on a single-frame custom job type. Maybe it's a good idea to discuss things with him in #flamenco to see if you can join forces, or at least see if there are any differences between your approaches.
Oh, that's cool, I'll check his approach as well. Maybe I'll be able to assist in some way. Thanks for letting me know!
Hi! I am David, and I am also working on implementing distributed rendering for single images. Could you share how you find implementing denoising within Flamenco would be useful? How is it different from using the built-in denoising (not the denoising node)? Thank you so much for sharing!
@David-Zhang-10 Hi, I'm glad there is also someone else working on this. I'm not exactly a developer by trait nor a Blender expert.
Doing the denoising itself is not an issue, like you said, there is a node that does that.
The problem comes from using tiled rendering. To my knowledge you can't denoise the individual tiles and merge them afterwards. Like @dr.sybren mentioned here, the problem is that Blender doesn't currently export all data needed for denoising into a multilayer EXR file.
I still haven't had the time to dive into this again, my last experiment here was with Blender 4.0.1 ~8 months ago. Just for info the issue that caused the merging to screw up the image should be fixed because the default compositor in current versions is now full-frame although I haven't tested that.
Checkout
From your project repository, check out a new branch and test the changes.