MCprep
MCprep copied to clipboard
feat: Upstream Vivy material system
Vivy is a new material system that is based around the concept of templates instead of generation. I created it in my spare time in 2023 and used it for my new year's piece
https://www.standingpad.org/posts/2023/12/new-years/#vivy
Initially, I have said that I didn't want to upstream Vivy in MCprep to avoid users from opening bug reports after underestimating the complexity of using the system. That said, #274 already had plans to revamp the material system for greater user flexibility, and I'm unable to maintain Vivy on my own (given the fast pace of upstream MCprep). Therefore, I've decided to begin the work of upstreaming Vivy into MCprep itself.
I initially tried to merge Vivy into a separate branch, but that turned out to be impossible due to massive changes in mainline MCprep. Thus, I've included the Vivy files here and added the necessary changes to conf.py and load_modules.py. This was made easier by the fact that Vivy does not change anything internal, mostly due to laziness on my part (instead, I just copied and pasted functions I needed to modify for Vivy). As such, everything in Vivy is a separate operator, using the vivy prefix instead of mcprep. I've not included the necessary reference changes for Vivy, since I don't want to start overriding operators yet.
As it stands, Vivy is lacking in the following areas:
- UI for setting up materials
- Documentation for using
- Integration in the rest of MCprep (like mob rigs)
In addition, Vivy also has the following issues due to the way its designed:
- Use of
VIVYandvivyprefixes - Lose integration (again, due to laziness on my part)
- No tests
Seeing as this is more of a long term project however, I think we can get these tackled sometime by MCprep 4.0. Once those are done, we'd also need to discuss how this would coexist with the existing generation based system (should we choose to keep it).
Closes #274
Just to be clear as well, after MCprep 3.6 releases, I'll be taking a break from MCprep development to focus more on college applications and BpyBuild, so @TheDuckCow if you want, you can develop on this branch without conflicts for the most part. This is more of a long term thing anyway.
After a little effort (mostly with missing stuff), I've added the ability to build MCprep with Vivy exposed in the UI through the enable-vivy-system action. This simply flips a global variable to be True instead of False. Note that there's no translation strings for Vivy yet, since the UI is subject to change.
Make sure when enabling Vivy support, you have vivy_materials.blend in MCprep_resources. I've also attached an existing Vivy export that can be imported through the UI.
Updated some of the references so basic things work. Vivy-based textureswap seems to not want to work for some reason, but prepping materials in general works fine
Got the Vivy-based textureswap fixed partially (issue was due to an outdated check for None instead of MCprepError)
Fixed the last remaining issue with Vivy-based textureswap, so now it should work on all texture packs
Alright, got an idea to make merging this PR less of a pain: what if we make this PR solely dedicated to cleaning up and properly upstreaming the Vivy code (for say MCprep 3.7), and then gate the loading of Vivy behind a runtime check (which we do for the UI, but not the actual registration)? This does mean the UI is technically in an incomplete when merged, but it also means less of a pain with merge conflicts as the PR wouldn't be too far behind.
We could also make Vivy usable to end users using the experimental flag in MCprep, so we can get some community feedback (especially when we do start working on the UI).
@TheDuckCow ready for first review. To be clear, this is a long term feature that will be developed over multiple PRs, and perhaps won't be enabled for users until MCprep 4.0. This PR specifically works on cleaning up the code for the Vivy material system, and getting it up to par with upstream standards. That way, we don't have to worry about a single long PR that gains conflicts over time, and instead have smaller PRs merged over a longer period of time. It does mean having unstable code in production, but I think that's a reasonable tradeoff to make.
By default, Vivy modules won't even be registered unless conf.ENABLE_VIVY is set to True, which can be enabled with the new enable-vivy-system action.
Hey @StandingPadAnimations thanks for making a great head start on this! To make things easier, would you be able to record a short demo video of how it's mean to be used right now? That way you save some time documenting and it's easier for me to see how it's currently working. I installed the branch to see that at the very least, nothing appears broken per-se, but wasn't too sure where to go after there (without diving more into the code first).
We can either treat this as a feature branch, or try to merge parts of it at a time until the UI side is fully ready.
Here's some demos I uploaded on Mastodon a long time back (not much has changed though):
We can either treat this as a feature branch, or try to merge parts of it at a time until the UI side is fully ready.
I think the latter would be better in the long run, mostly to try and avoid as many merge conflicts as possible. That said, it might make more sense to make this a feature branch
I think the latter would be better in the long run, mostly to try and avoid as many merge conflicts as possible. That said, it might make more sense to make this a feature branch
I tend to agree, ok let's go with that strategy. Thanks for providing the demos, will take a look and get back to you - but I agree, seems like a good stepping stone to include this in 3.6.2 since it's mostly backend to what the user sees for now.
Looked at the demos, veyr nice. Something I definitely will need to noodle on - these fill a similar, but not exactly the same, space as the current day "Sync materials" which are made to exist alongside the asset pack. I think we should find a way to unify these (likely taking yours as a base, but then integrating into other operators similar to how sync materials is today).
Not sure if there was meant to be audio in your recordings, but at the end of the pbr one you were waving your cursor around the water. What is your thought on finding a way to mark a material to work for specific blocks/materials, vs working as the template for all of them? I could imagine we can create some kind of tags so you can optionally specify a given vivy material is to be used for specific things. e.g. maybe a user wants to use one layout for all "fire" blocks, another layout for all grass/leaves, but then the default MCprep for everything else.
And thirdly, I'm also contemplating whether this is a good time to make these things work nicely together in the asset browser. If we are already marking a material template, maybe we should register them as an asset as well?? We could potentially even do some fancy post-material import things like detect if you dropped a vivy template onto a material slot that had a pre-existing world import material, and go in after to make unique and swap in the correct images (there's a PR for creating python hooks after asset browser drops via Greg Zaal that would need to be completed first)
What is your thought on finding a way to mark a material to work for specific blocks/materials, vs working as the template for all of them? I could imagine we can create some kind of tags so you can optionally specify a given vivy material is to be used for specific things. e.g. maybe a user wants to use one layout for all "fire" blocks, another layout for all grass/leaves, but then the default MCprep for everything else.
Vivy actually does support such a feature, referred to as refinements (as in refining a material for a specific subset of blocks). These are based on the existing MCprep block categories (like emissive, glossy, etc). I had plans as well for specific blocks, but never got around to doing it. I think I've showcased refinements in the above demos but if not, I could put one together.
And thirdly, I'm also contemplating whether this is a good time to make these things work nicely together in the asset browser. If we are already marking a material template, maybe we should register them as an asset as well?? We could potentially even do some fancy post-material import things like detect if you dropped a vivy template onto a material slot that had a pre-existing world import material, and go in after to make unique and swap in the correct images (there's a PR for creating python hooks after asset browser drops via Greg Zaal that would need to be completed first)
That would be interesting, but there are a few things that might make this a bit of a challenge:
- Vivy materials also require a corresponding JSON file, which introduces some extra logic in both applying and exporting in a library
- If we do implement this, I would love to get this working on all parts of MCprep, like blocks and rigs, which means we need to get Vivy working in those areas as well
As an aside, should Vivy be the "official" name of this feature, or just a codename? The name might be a little confusing to users when we do eventually introduce this (it's a pretty obscure reference to a light novel I was reading at the time :sweat_smile:)
Also, the code is ready for review, not sure if I mentioned that earlier
Alright, since it seems like Vivy builds for the most part without errors, I'll move Vivy from a build-time option to an experimental feature (which I believe would make Vivy the first experimental feature in MCprep)
To avoid conflicts, I propose we merge this initially, and then make features such as the simplified UI and ability for user-defined paths separate PRs. That way, this doesn't become a long-winded PR.
@TheDuckCow This PR is ready for initial review
So a slight change in UI philosophy: although it was proposed to make the Vivy UI act closer to sync materials, I feel that it would be redundant (why have both when they act the same). So to simplify the UI, I've decided that for the time being, to remove refinements from the UI layer (though they exist internally for compatibility reasons).
This simplifies the UI in a way I think would be good for users to get into:
The same will be true for config stuff; the config editor (which will be a UIList for simplicity's sake) won't expose refinement settings
Basic concept of the Vivy config editor. This is without refinements, and I haven't yet implemented the ability to apply changes, but I think this basic idea should work for an experimental feature.
Alright basic config editing. This is in the same location as the Vivy node tools
https://github.com/user-attachments/assets/7a7896fb-2bee-465f-a199-c70f42bdd920
I've now implemented basic custom path support. For now, this will only be one file, since multiple files would require some more in-depth work with regards to importing materials
Some improvements to make it more consistent with existing parts of MCprep
This is similar to the resource pack, where the default is defined in preferences, but it can be overridden on a per-scene basis.
Going to try and see if I can get this in a proper state for review by the end of this week. What's left is the following:
- [x] Resolve the issue where materials are not sourced properly
- [x] Resolve issues with texture swap. Vivy's implementation of texture swap is currently extremely inconsistent with texture swap; some texture packs work, some don't, and sometimes a texture pack will work one time and fail the next time
- [ ] Further UI improvements, such as:
- [x] Implement refinements in the UI (I know I initially said I wouldn't implement them, but with the reworked UI, I think it's in a state where it makes sense to implement them now)
- [ ] Add the ability to specify a resource pack in the prep materials dialog
- [ ] Expose regular prep functions as a fallback
- [ ] Add documentation on use
If not at the end of this week, then ideally I would like to try and get this in a nice state for review by the end of this year, or even merged if possible (we got a little extra leeway since this is an opt-in experimental feature). Integration with spawners would be a nice feature, although this PR is already pretty dragged out.
I've implemented refinements in the UI now, although mappings are not yet updated (so the UI won't show that a material is a refinement of X for instance)
Testing the resource pack inconsistencies at the moment. Here's the texture packs I have tested with and their passing status:
- [x] Vanilla PBR 1-2-0
- [x] HardTop PiXXL Accurate 64x v0.4
- [x] Faithful 32x July 2024 Pre-release with PBR extension
These packs are definitely outdated a bit, but that's what I currently have locally. Will test some more based on suggestions.
So weirdly it seems to be that the errors occur if swap textures has been called once. This is likely due to fallbacks that occur the first time interfering with later calls
Subsequent uses of Vivy's texture swap has been fixed, albeit with a band-aid solution. Since a lot of the code feels rough, I'm going to spend some time simplifying it as much as possible
Ok thanks @StandingPadAnimations - if you want, consider whether you want to split this up into several PRs or keep this one single one here. We could always create a feature branch. At some point, when it's ready, you and I should sit down and do a live review so I can make sure I grasp all of the current state of it and how it's working. Just let me know (via ping and/or request review)
Ok thanks @StandingPadAnimations - if you want, consider whether you want to split this up into several PRs or keep this one single one here. We could always create a feature branch.
The plan is to have several PRs for Vivy, with this one primarily focusing on the initial upstreaming (getting major bugs ironed out + cleaning up the code to meet existing standards). I think it should be fine to merge this into dev since right now, Vivy is an opt-in feature (taking advantage of the experimental option MCprep has)
At some point, when it's ready, you and I should sit down and do a live review so I can make sure I grasp all of the current state of it and how it's working. Just let me know (via ping and/or request review)
Sure thing!
Pushed refactoring changes and pulled in the latest updates to dev. @TheDuckCow I think this is ready for a live review
I'm just installing the branch to prepare myself at least a little bit more for tomorrow, I notice a startup registration error - should probably just skip if we are in that state (didn't read too much further into it yet though, just flagging it) - restrict data typically is happening during startup but can also occur when accessing data from threads. In this case, seems to just be during the startup registration process if Blender is still working on registering (even if MCprep's own registration is still in progress, other addons might still be in progress - something I've run into recently on another project).
Traceback (most recent call last):
File "/Applications/Blender 4.4/blender.app/Contents/Resources/4.4/scripts/modules/addon_utils.py", line 515, in enable
mod.register()
File "/Users/patrickcrawford/Library/Application Support/Blender/4.4/scripts/addons/MCprep_addon/__init__.py", line 65, in register
load_modules.register(bl_info)
File "/Users/patrickcrawford/Library/Application Support/Blender/4.4/scripts/addons/MCprep_addon/load_modules.py", line 192, in register
mod.register()
File "/Users/patrickcrawford/Library/Application Support/Blender/4.4/scripts/addons/MCprep_addon/mcprep_ui.py", line 2132, in register
path = Path(bpy.path.abspath(addon_prefs.exp_vivy_file_path))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Applications/Blender 4.4/blender.app/Contents/Resources/4.4/scripts/modules/bpy/path.py", line 73, in abspath
_os.path.dirname(_bpy.data.filepath)
^^^^^^^^^^^^^^^^^^
AttributeError: '_RestrictData' object has no attribute 'filepath'
Also when trying to press "Edit vivy material library" I do run into this error, even after trying to save a file adjacent to the current one with that name. Hopefully we can run through it live tomorrow, patching as needed. We can also talk about this workflow tomorrow, the best way to suggest creating this and where it could be loaded from.