Write Blender Nodes to JSON?

Issue #1265 resolved
Midnight Arrow created an issue

Recently I took the effort to finally crack the custom road shader Stonemason uses for Urban Sprawl 3:

However it was very difficult since the Duf file programmatically overwrites the tiling information, so it can’t be seen in either the Uber shader or the Shader Mixer. Stonemason mentioned on the Daz forums he uses 3dsMax, so I think maybe he’s exporting custom MDL files?

Given the utility and versatility of US3, I’d be glad to share my implementation for others to use. But it’s quite complicated, so I wonder if maybe the exporter would benefit from the ability to import and export Blender nodes as JSON? That way I could just dump my node tree, post it here, and Thomas could simply add the JSON file to a dedicated folder included with the exporter. Then the end-user can simply select the shader from a list, load the node group into the material, and plug the image maps into the slots. (Or the alterative is to use the asset browser?) This might also be an effective solution to the problem of having multiple skin shaders in global settings. Rather than hard-code them, simply load them on the fly, like the pose system.

It might also be a way for users to share and swap custom skin shaders, now that the changes to volumetrics have made replicating the Uber shader’s SSS unfeasible.

Comments (18)

  1. Thomas Larsson repo owner

    That sounds like an interesting proposal, and it is probably not very difficult to implement. We must just agree on an exchange format.

  2. Midnight Arrow reporter

    Isn’t JSON an exchange format? I was thinking just a straight dump of the parameters into a .json file would suffice, since afaik bl_idname (which defines the type of node) is just a string.

  3. Thomas Larsson repo owner

    JSON defines the syntax, but it must also be filled with content, like the node input and output default_values and links. But if you give me the json file I will probably figure out how to import it, at least after a few iterations.

  4. Midnight Arrow reporter

    I have no idea how to dump JSON to a file. I was asking if the exporter could have an operator to read and write JSON for node trees, and then we could share the output.

  5. Thomas Larsson repo owner

    Implemented in last commit. There are two buttons in the Advanced > Materials section: Save Material To File and Load Material From File. They don’t handle general node groups but do recognize the ones defined by the plugin.

  6. Midnight Arrow reporter

    I don’t think that’s going to work for Urban Sprawl 3 though. The road shader has four layers blended with masks, but the textures and the masks have different tiling values so there’s a lot of mapping nodes required. It’d need to read and write Blender native nodes, unfortunately.

  7. Thomas Larsson repo owner

    I haven’t tested with mapping nodes, but I don’t see why they shouldn’t work. General nodegroups do not yet work, but unless you use nodegroups there is a fair chance it works already.

  8. Midnight Arrow reporter

    I misunderstood, I thought you meant it only works with the exporter’s node groups like Daz Glossy and Daz Diffuse, not all nodes in general.

    I tested it and it seemed to write the file out okay, however upon trying to load I got the error “Expecting value: line 1982 column 40 (char 92631)”.

    Also I have two issues with the JSON output. First is that VSCodium is giving errors about the bpy_structs used for parenting not being enclosed with double quotes. The second is it uses hardcoded filepaths and that won’t work well for sharing files with others. Maybe instead it should use relative paths to the content directory, or just not load the textures at all? This is mainly about sharing node setups. If for instance we want to share skin shaders, then it would be better not to tie the node setup to a particular set of textures.

  9. Midnight Arrow reporter

    Blend files have a lot of overhead which isn’t really necessary compared to a plaintext JSON file.

  10. Alessandro Padovani

    As for sharing blender files, both the blender and daz folders may be different in different systems. We can use pack/unpack that’s designed to share files. Or we can use absolute paths that will work if both the systems use the default daz library.

    If one user sets custom folders for the daz library then there’s no way for relative or absolute links to work, apart texture searching that’s implemented in commit b7aafc4.

  11. Thomas Larsson repo owner

    I got node groups working tonight, and think that the exchange format may be useful tomorrow after a bit of polishing. However, one should be aware that node setups can probably not be shared across Blender versions. The plugin queries the API about node arguments, inputs and outputs, and that may differ between different Blender versions.

  12. Midnight Arrow reporter

    The way I see it this has two distinct use cases:

    1. Storing complicated shaders (like the Urban Sprawl road shader) in which case we would want the textures.
    2. Storing reusable shaders that are agnostic to textures, such as a custom skin shader used on multiple models.

    So perhaps a better approach would be a two-step procedure? You create the node group with one operator, and then add the materials with another? All nodes optionally take a label for scripting purposes, so the first operator may populate the node tree with empty image nodes (with the onus on the user to name them appropriately) and the second performs a lookup to correlate the images with the image nodes, only if necessary.

  13. Thomas Larsson repo owner

    Now the tools work quite well, I think.

    By default local texture paths are used if possible, as in local relative to the daz root paths. But it could be useful to disable this option if the texture paths are relative to the blend file, using the // syntax. E.g. the Save Local Textures tool makes copies of the textures in the //textures/original folder.

    Making reusable shaders will be difficult, I think. The user must specify which textures to use in some way or the other, and since there are many textures there will be much manual work. We cannot expect that every PA uses the same naming conventions, so I don’t see how to script that.

  14. Alessandro Padovani

    I am not sure to understand what all this is about, apart implementing a custom shader by Stonemason. I mean we can already save materials to the asset browser, the textures have to be included to be shared. Or if the daz library is in the standard path we can use absolute links.

    Personally I leave the textures in the daz library and save my blender scenes with absolute links. This will work fine to share assets if the user keeps the standard daz library path.

  15. Thomas Larsson repo owner

    Now the old textures are kept when new materials are loaded. The idea is that textures are tagged with the iray channel in which they are used. For this to work the original duf files must still be around, both when the materials are saved and loaded, because the plugin looks in the duf file to figure out where the textures are used. If a texture is used by several materials, the tags are different. However, if the texture is used in several places in the same material, e.g. diffuse and translucency, the same tag is used.

    If the Keep Textures option is disabled, the new textures are loaded instead. If the original materials don’t have textures in the appropriate channels, the new textures are also used.

  16. Log in to comment