Geometry Nodes Volume Features Implementation #103248
Labels
No Label
Interest
Alembic
Interest
Animation & Rigging
Interest
Asset System
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
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
Viewport & EEVEE
Interest
Virtual Reality
Interest
Vulkan
Interest
Wayland
Interest
Workbench
Interest: X11
Legacy
Asset Browser Project
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
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
Module
Viewport & EEVEE
Platform
FreeBSD
Platform
Linux
Platform
macOS
Platform
Windows
Severity
High
Severity
Low
Severity
Normal
Severity
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
12 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: blender/blender#103248
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "%!s()"
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?
Status: In planning phase
Team
Commissioner: @HooglyBoogly
Project leader:
?
Project members: @erik85
Description
Big picture: Address the large opportunities for procedural volumes while fitting into geometry nodes design, especially using existing openVDB tools
Use cases:
Design:
Engineer plan:
Work plan
Milestone 1 - Very basic SDF volume nodes
Expose SDF volumes as a basic data type, provide a few fundamental nodes for future development
Milestone 2 - Basic support for fields as references to grids
Allow referring to grids with the named attribute node, but not any modification
AttributeFieldInput
) should work for volumes too, referencing grids by nameAttributeFieldInput
input. Any other field can be rejected for now. It just looks up the grid by nameMilestone 3 - Grids as anonymous attributes
Creation of and references to grids without a name, to allow referencing them with node links
AttributeFieldInput
for now.Milestone 4 - Evaluating fields on grids
Support basic volume advection
VolumeGridFieldContext
that can provide the position field at each voxel (by index for now, so voxels probably have to be flattened)Milestone 5 - Changing grid values with fields
Milestone 6 - More advanced volume nodes
More advanced use cases building on the fundamentals above
Relevant links
Changed status from 'Needs Triage' to: 'Confirmed'
Geometry Nodes Volume Features Overviewto Geometry Nodes Volume Features Implementationmaybe a dumb question, but will the openvdb csg oprations be part of this? (csgDifference/csgIntersection etc)
Dang, csg on milestone 6? yikes
I was hoping to see it on miilestone 1 tbh, since it's one of the most useful things of openvdb.
Anyways, waiting for milestone 6 then
The design for the volume boolean node is a bit complex here, it's one sore spot in the design currently.
It's complex because the volume might contain multiple grids, both named and anonymous.
It's not clear how they should be matched together when you want to run a union on two of those volumes, for example.
I'm open to suggestions there, maybe there is some way to simplify it, or maybe it isn't necessary to support more than one grid.
We have a similar problem in the join geometry node, where you can't explicitly decide how to join specific anonymous attributes together.
This is a very cool idea, it will be great to have SDF support :)
Charlie Jolly's patch had some cool node ideas for working with SDFs https://developer.blender.org/D6464
Maybe I will try to replicate some of them later
Are there plans to include heightfields like the flat plane volumes for terrain generation?
This task is more about 3D volumes. I'm sure a similar approach might be helpful for heighmaps too (though there is the design question of how different they are from images), but that use case doesn't fit so well here.
You might like to keep an eye on the progress of this Blender SDF modeling add-on. It might offer some inspiration for your implementation.
Iliya Katushenock referenced this issue2023-04-23 12:17:09 +02:00
We should have a way to share the TreePtr between grids. Grids themselves are basically attributes, but right now we don't seem to have much flexibility for creating multiple attributes sharing the same topology (tree).
With other geometry types we'd capture attributes on a given geometry, which defines the underlying topology. But since Volumes have multiple grids and trees it's not clear how to specify which tree gets used. Maybe nodes that store grid attributes could have a "copy from" attribute input that defines the tree, although that doesn't seem great either. Or should capturing on a Volume create the grid for all its trees, treating them as joined geometry?
Another topic that will become important for fluid sim is staggered grids. These are an optimization for velocity grids that are frequently used with divergence and gradient operators. The vectors on the grid are interpreted with a different half-cell offset for each component. This avoids interpolation losses when converting between pressure and velocity fields. Matthias Mueller has a nice overview.
Staggered grids in OpenVDB have their own class. We should have an option to create a vector grid as a staggered grid class. This does not have an immediate effect on low level code, but it allows algorithms to chose appropriate samplers etc. The sample volume node should also take this into account and use
StaggeredBoxSampler
vsBoxSampler
and so on based on sampling type.This is such a great feature to see coming on line. From my perspective, it doesn't need much to become a 1.0 feature set. some basic functional primitives (sphere, cylinder, cube, curve), non-uniform scale, falloff and a node to convert the shader shape to triangle soup. The rest is candy for later.
Hi, if my understanding is correct. Would I be able to import quantized data. And then use that data to set the individual voxel values in the grid?
Presently, I create each VDB file and save to disk. If I could just load the data into blender and create the volume within geometry nodes that would save a lot of hard disk space.
Hi, I think with this design the store named attribute node would let you set the value of each voxel by index. Though I'm not certain about that. I'm not sure how fast it would be though.
Isn't that done in parallel? How are index assignments handle in Geometry nodes, say for example, on points?
@TheJeran I think, problem in implicit volume conversion of volume to other one. This requered to project indices from one volume topology on other one to make indexing possible.
Volumes are very different than points-- the values aren't stored in a single array. That's what makes them fast. So calculating indices is avoided when possible.
I'm also interested in loading quantized data (as for example Multi-pages TIFFs files, or sequences of images, or UDIMS, etc...)
Maybe just importing them and specifying 3D coordinates for the bounding box corners could be enough to fill the volume data grid by interpolating the source files ?
And if the resolution of the input images matches the resolution of the voxel grid, then we get a 1:1 display of the data.
Accessing the voxel grid by 3D coordinates instead of indices may be more convenient, and it's always possible to use a simple 1D <-> 3D conversion to find the index for a given 3D position or the opposite. (https://coderwall.com/p/fzni3g/bidirectional-translation-between-1d-and-3d-arrays)
I've started an experimental branch (#110044, heavily WIP!) to make volume attributes work. The grid attributes use a specialized
VArrayImpl
to access the grid values. Currently only the simple index-based get/set are fully implemented. For efficient read/write of grid data the optimized bulk-access methods with spans and index masks need to be implemented, amortizing the cost of looping over leaf node buffers.Would it be possible to sample volumes?
At the moment (for another unrelated task) I am doing particle surfing with simulation nodes. Currently what I do is spawn the 3D array I am surfing on as vertices with a vector attribute. Then I sample the nearest vertex for each particle and update their positions based on that value. Unfortunately there is no interpolation. If I could sample a volume like they do with 3D textures in Unity. That would be super dope.
I've been implementing a couple of the tasks outlined in Milestones 3 and 4 over the last few weeks:
Now i can do stuff like this:
As you can see, there are some hoops to jump through to handle cases of undefined topology: Each grid has its own topology (active voxels), in contrast to array-based fields where each array has the same size based on the geometry context and domain. When combining multiple grids the result will usually be a topology union of all inputs.
Some grids are defined as abstract spatial functions, for example the
position
attribute returns the center of each voxel. These virtual grids don't have a finite topology, so when capturing them alone the result will just be an empty grid. That's the reason i'm first constructing a volume cube and then using thedensity
attribute: it forces the resulting topology to match the cube even though the position field has no topology of its own. A nicer solution to this problem needs to be found, like using a default topology from the volume context. Of course this default topology also needs to be somehow specified first.Point Data Grids
I'd also like to discuss how point clouds and grids can interact. OpenVDB has a dedicated grid type for point cloud storage, which could help a lot with performance. There are two variants (link):
PointIndexGrid
is a simple integer grid, storing offsets into a sorted point cloud. Each slice of the point cloud indicated by the grid contains particles within a cell.PointDataGrid
stores the entire point data set, including attributes. This data structure has many advantages, such as ease of use (no need to keep the point cloud around), data compression, and floating point accuracy mitigation (storing positions relative to a cell in fixed-point format).Integrating point data grids into the existing geometry nodes concepts is challenging. It represents a complex data type that would require a new socket type and is quite opaque. There would need to be special nodes for reading and writing attributes, and for converting a point data grid to and from a regular point cloud.
A better design would be to treat an OpenVDB
PointDataGrid
as just another form of storage for a point cloud. ThePointCloud
data structure would optionally (!) store a point data grid, either alongside or instead of plainCustomData
arrays. Grid storage could be enabled by users or by certain algorithms (spatial sampling, fluid sim, etc.) and can be disabled at any time.On the UX level there would be no immediate changes, the point cloud continues to be treated as normal geometry. A couple of simple utility nodes to enable/disable grid storage and get the current storage mode could be added if needed.
One use of grid storage would be for simulations:
With an internal grid storage for the point cloud it would be much easier to fit into existing paradigms. The point cloud geometry can be stored as a simulation zone item and efficiently simulate fluid motion over time. Serialization can convert to a conventional point cloud, or could serialize
PointDataGrid
directly (TBD).I've been considering another way to integrate
PointDataGrid
into geometry nodes concepts. Instead of storing a point cloud in two different ways, we can store the data grid representation in theVolume
component and expose particle data through thePOINT
domain. This avoids difficult questions of cell size, ownership, and data duplication inPointCloud
. A key difference between point data grids and regular data grids would be that we only store one point data grid per volume. Joining multiple volumes would merge the point sets and their attributes, following the same behavior as a regular point cloud.In addition to
Points to Volume
andPoints to SDF Volume
there would be aPoints to Data Grid
node. This will store particle data in the volume component as aPointDataGrid
instead of rasterizing straight into a fog or SDF grid. The spreadsheet will show the point data under the point domain.Point data can be rasterized into a grid using different methods (see
rasterize***
methods here). For fluid simulation purposes we want to generate a velocity grid using trilinear rasterization. This can be the default mode when adapting from the point domain to the voxel domain, which means we can simply connect a named attribute to the fluid solver and it will generate a velocity grid from the point data grid. This might not be transparent enough, perhaps some node along the lines of "evaluate on domain" could be added to make this more explicit.After rasterizing the velocity grid and then solving the pressure field (making incompressible fluid) particle advection is applied to the point data grid. We don't want to convert back and forth into a point cloud all the time, so the point data grid remains the main simulation geometry.
The simulation output can finally be converted back into something renderable. We can just extract the point data as a point cloud again. Or we can generate a mesh from the point data, which may involve rasterizing to a different grid resolution.
The volume changes look great! I think it would make sense to start splitting the branch into smaller changes and move thing to main.
I wouldn't really consider these "virtual grids" as attributes. Volumes shouldn't have a
position
attribute. The position is just a field input, it doesn't have to go through the attribute system. The point of that is to clarify the design of attributes as data stored on geometry.Regarding the point grid storage, I'd prefer to discuss that elsewhere. For design simplicity, I think point clouds should remain part of the point cloud component. The use cases are related, especially for something like a flip solver, but design-wise it's much simpler, since it's basically just a performance thing.
Just noting that these were removed again, see
5bc82b5b7c
Why is removed ?