Geometry Nodes Overhaul (Creating a Push Modifier)

Issue #923 closed
Midnight Arrow created an issue

Previously I opened several enhancement requests (#862, #869, #871) about the potential of geometry nodes to replicate Daz functionality. But since geonodes are so new and different, I decided to open this all-encompassing enhancement request to explain to the uninitiated what they are and how they can benefit the Diffeomorphic exporter. To demonstrate this, I will show how to create a Daz feature in Blender.

Geometry nodes are intended to replace the fixed-pipeline modifier stack. They use a node-based nonlinear workflow to replicate how modifiers change a mesh. Currently they're implimented on the modifier stack and can be toggled, rearranged, and animated just like any other modifier, but I think when it’s sufficiently mature the modifier system will be removed entirely.

For starters here is a simple recipe to replicate the push modifier from Daz Studio.

When you add a geonodes modifier to an object it is created with an input and an output, like a shader group. The geometry input is the raw data -- the mesh as it appears in edit mode. The green line running to the end is a nonlinear version of the modifier stack; each node you run it through will procedurally adjust it. Then you feed the end result into the group output and that’s the mesh you get in your viewport.

The Set Position node allows you to move a mesh’s individual vertices. When it's evaluated, Blender loops through every vertex in the mesh and performs an operation on it. In this case we’ve hooked up the “Normal” node to the offset socket. Any of the input nodes like Index, Normal, Position, etc. will tell Blender to use whatever the value is for that element while it’s being evaluated. So as the Set Position node loops through the mesh, it will take the normal of the vertex in its edit mode position as its input. Here we use a vector math node to multiply the normal vector by a scalar we feed in from the modifier stack, offsetting the vertex’s position from its edit mode location along the vertex normal.

For increased power geometry nodes uses attributes. Attributes are like vertex groups, but better. A vertex group only lets you associate one type of data (a float) with one type of element (a vertex) but the attribute system is fully genericized. You can associate any kind of data with any kind of element and perform math operations on them. Blender will eventually unify the disparate datatypes into one all-purpose attribute system. Here's a chart comparing some existing datatypes with their element/type equivalent:

Vertex Group: Vertex → Float

Vertex Colors: Vertex → RGB

Shape Keys: Vertex → Vector

UV Seam/Mark Sharp: Edge → Boolean

Edge Crease/Edge Bevel: Edge → Float

Material Index: Face → Integer

UVs: Face Corner → Vector

By clicking the little spreadsheet icon on a geonodes modifier, you can change the scalar input into an attribute field. You can then type in the name of an attribute (such as a vertex group you created) and use that as an input during evaluation. For this example I made a vertex group and used that to control the offset. As you can see, the per-vertex weight is correctly associated with a vertex normal during evaluation, replicating the push modifier weight map feature available in Daz Studio.

You can create your own attributes in their tab in the Object Data properties or through the Blender API. By declaring one you can use it to store attributes and pass them between geonodes modifiers, even between different objects, in a completely procedural and nondestructive way.

Another application of this is the eye moisture bug that causes graphical issues with eyes due to the geometry intersecting. Rather than scale the geometry up during import you can use the procedure described above to scale it nondestructively with a selection set limited to the eyeballs' indices.

Needless to say this is just the tip of the iceberg. Blender has hundreds of geometry nodes allowing complex operations such as raycasting, geometry proximity, joining and deleting geometry, which have many applications for geografts, morph transferring, smoothing operations, converting dFormers, etc. I understand that maintaining backwards compatibility with 2.9x is a priority, but I also believe a strong geonodes-based workflow will get the importer closer to parity with Daz Studio itself.

Please let me know if you have any questions or would like more information. I have successfully been using geometry nodes in my workflow for months now, and I find them much more robust than the modifier stack.

Comments (9)

  1. Luke Graybill

    I don’t have much to add here other than a heartfelt thank you for exploring this. Geometry nodes are massively exciting to me, and I’ve also been using them for a little bit now, although only on static meshes so far. The geometry nodes system is so incredibly powerful. The prospect of using it to improve possibilities with this addon is tantalizing.

  2. Alessandro Padovani

    imho

    I like #869 because it could be a nice way to simplify geografts if it works. But for performance and compatibility reasons in general I’d avoid to use geometry nodes unless they do provide a necessary feature that’s not available in any other way. At least for now until geometry nodes get streamlined.

    Then thank you Midnight for pushing with geometry nodes it is useful to have someone doing this.

  3. jeroen b

    Hi Midnight, this is very interesting stuff!

    If at all possible, could you use G-nodes on a character to have a clothing item deform the character instead of this character's JCM’s deforming the clothing item, for instance a robust leather belt for a jeans?

    An example of the G-nodes setup for something like this (if at all possible) would be highly appreciated.

    Thanks for posting this issue!

  4. Midnight Arrow reporter

    @ Luke @ Alessandro @ Jeroen

    Thanks for the encouragement. Geometry nodes really are a game-changer, and I’d like to help future-proof it and expand its capabilites based on what Blender has to offer.

    @ Alessandro

    I make sequential art and visual novels which require me to link one figure into potentially dozens of scene files, so the ability to import and setup a character in one master file and then make scene-specific changes without needing to edit the original file is a necessary feature, at least for my purposes.

    As for performance, since geonodes are a modifier I just toggle their viewport visibility off when I don’t need it to prevent posing lag. As for rendering lag, In the comments to #862 I demonstrated I can successfully create a geoshell based on Aeon Soul’s “Dirt Essentials” and while I didn’t benchmark it I didn’t notice any egregious rendering lag either. The Blender devs are also making speed improvements in geonodes with every new release so it’s much faster than it used to be.

    Finally regarding backwards compatibility I think the optimal solution is for the Diffeomorphic importer to have a separate “Geometry Nodes” section, separate from “Setup” and “Advanced Setup”, which can be disabled based on the Blender version. That way geonode solutions can be tested in isolation without interfering with the proven workflow. As I said I’m in favor of greater modularity, so I would prefer it if there was a button to load a geoshell directly from its Duf file and create a geonode setup, rather than have to do it as an import process. Not only is that more flexible and easier to troubleshoot, as an opt-in people don’t need to use it if they don’t want to.

    @ Jeroen

    Sometimes. It depends on how the belt was made. Many Daz assets are not manifold (they’re missing their back faces) so there’s nothing to test for collision with. If a mesh does have backfaces, here’s a solution I created based on some Youtube tutorials about replicating the shrinkwrap modifier:

    It’s fiddly but it works, though it does tend to break so you need to adjust the raycast settings per pose. I still haven’t fully gotten my head around the Raycast node so there may be a better way. The displacement is also very jagged. Here it is with a Smooth modifier:

    Unfortunately the smooth modifier affects the whole mesh and I couldn’t control it even when I outputted it into a vertex group. The Blender dev threads mention problems converting generic attributes to specific datatypes, but also they’re introducing Grow/Shrink Selection and Smoothing geometry nodes anyway, so a smoothing modifier will be unnecessary. Soon it’ll be trivial to use the “Is Hit” boolean output to create a localized smoothing effect entirely within geometry nodes.

    If a mesh isn’t manifold you’d need to do something complicated like store the belt’s front faces in a vertex group, pass that to the figure, and use their normals to push the skin geometry inward. That’s well beyond my current understanding – and possibly the current functionality of geometry nodes. Although, since you can do arbitrary vector math on vertices, in theory anything is possible.

    I’ve also successfully used the Raycast node technique to create procedural indents in beds and chair cushions. It works very similarly to Daz Studio’s smoothing node, but it’s much more robust since you can chain multiple targets together rather than one fixed target like in Daz. It doesn’t handle corners well without horrible self-intersection, but again that may be my limited understanding or something that can be mitigated with a dedicated smoothing geonode.

  5. jeroen b

    Thanks for your comprehensive answer Midnight, I am going to experiment with this G-nodes setup that you suggested.

  6. jeroen b
      <div class="preview-container wiki-content"><!-- loaded via ajax --></div>
      <div class="mask"></div>
    </div>
    

    </div> </form>

    I stumbled onto this document about G-nodes, perhaps useful.

  7. Log in to comment