Page MenuHome

Volumes: new Volume Displace modifier
ClosedPublic

Authored by Jacques Lucke (JacquesLucke) on Oct 1 2020, 4:17 PM.
Tags
None
Tokens
"Love" token, awarded by gilberto_rodrigues."Love" token, awarded by shader."Love" token, awarded by slumber."Love" token, awarded by SavMartin."Love" token, awarded by Shimoon."Love" token, awarded by julperado."Love" token, awarded by lopoIsaac."Love" token, awarded by simonthommes."Love" token, awarded by Slowwkidd."Love" token, awarded by Bit."Love" token, awarded by kioku."Love" token, awarded by brecht."Love" token, awarded by Rusculleda.

Details

Summary

This modifier uses a 3D (noise) texture to displace a volume.

Todos:

  • Decide if the displacement strategy is actually correct. See below.
  • Support all grid types.
  • Expose more settings to control the texture mapping.

There are multiple displacement strategies that could work, I can think of two main approaches.

  1. Compute a velocity grid around the volume based on the texture. Then use advection to modify the original grid.
  2. In each cell within a certain distance of the active cells, compute an offset based on the texture. Then sample the original grid at current position + offset and assign the value to the current cell.

Both approaches have different use cases, so we might need both eventually anyway. In the current implementation, I use the second strategy, because it is simpler and has better performance (I guess).

Ref T73201.

Diff Detail

Repository
rB Blender
Branch
volume-displace-modifier (branched from master)
Build Status
Buildable 10585
Build 10585: arc lint + arc unit

Event Timeline

Jacques Lucke (JacquesLucke) requested review of this revision.Oct 1 2020, 4:17 PM
Jacques Lucke (JacquesLucke) created this revision.

We could indeed support both, they should have their own uses.

Advection seems especially important if you need to preserve overall density, as part of a simulation or for some other reason. But it's probably more expensive than necessary for cases where it's not important.

Seriously, seeing Blender Internal textures for displacement in this new stuff is depressing.

  • support displacing more grid type
  • support different texture mapping modes

Seriously, seeing Blender Internal textures for displacement in this new stuff is depressing.

I know what you mean. Unfortunately, we don't have a good alternative in Blender yet. We will be able to control the displacement differently once we can access this functionality with nodes.

I think it is fine when the initial version does not have an Advection option. I'm not sure when this would be useful in the current modifier stack.

Currently, only very few of the builtin textures have a color output (only "clouds"?). In the current implementation I use the rgb texture values as xyz displacement offsets. On grayscale textures this leads to stretching along the (1, 1, 1) axis.
Should I evaluate the texture three times at different coordinates for each grid cell to fix this? Or is this a limitation that is fine for now?

Jacques Lucke (JacquesLucke) retitled this revision from Volumes: new Volume Displace modifier (WIP) to Volumes: new Volume Displace modifier.Oct 5 2020, 4:28 PM

only very few of the builtin textures have a color output (only "clouds"?).

I have to correct myself, voronoi also has some color modes. So it works fine as well.

  • Merge branch 'master' into volume-displace-modifier
  • cleanup

I tested the patch, nice work!

I think it would be good to have control over the mid-level per dimension.
Also, next to the RGB as XYZ displacement type, it would be nice to have builtin directional displacement as an option. You can hack this with a color ramp on the texture, but then the mid-level is definitely missing.

Is the fact that the volume domain is not adaptive to the actual displacement texture, but expands depending on the strength in all directions an unavoidable limitation? Would be nice for viewport performance to have less voxels.

Of course, with the current limitation of only being able to use the old texture system makes it quite limited for now anyways, unfortunately.
Would be incredible to be able to drive the displacement texture and modifier strength with a node-system in the future!

But it's already to super fun and pretty useful!
I found no major issues with the current functionality.

Only one thing that did not behave as I expected is that when the volume object is parented to the mesh, and the texture mapping set to object, moving the mesh object (and thus the child volume) did not affect the texture space of the displacement (see beginning of the previous video). But that might be intended behavior (?).
With the regular mesh displacement parenting the object has no influence on the texture space used.

Jacques Lucke (JacquesLucke) planned changes to this revision.Oct 7 2020, 2:05 PM

Thanks for testing it.

I think it would be good to have control over the mid-level per dimension.

Will add that.

Is the fact that the volume domain is not adaptive to the actual displacement texture, but expands depending on the strength in all directions an unavoidable limitation? Would be nice for viewport performance to have less voxels.

The issue is that the modifier does not know how the texture looks like without evaluating it at all points within a certain distance of the original volume. I already added a "prune" step that removes unnecessarily stored voxels in the end.
There could be an additional "Max Displacement" input that can limit the number of voxels where the texture is evaluated. This could be useful when the texture only contains relatively small values, but can also be used when to prevent cutting of the volume, when the texture values are large.
There might be better solutions to this problem, that I'm not aware of though..

Would be incredible to be able to drive the displacement texture and modifier strength with a node-system in the future!

Indeed! :D

Only one thing that did not behave as I expected is that when the volume object is parented to the mesh,

Hope I understand that correctly. Will push a related change in a moment.

  • change object texture mapping
  • Merge branch 'master' into volume-displace-modifier

The overall implementation looks good.

Currently, only very few of the builtin textures have a color output (only "clouds"?). In the current implementation I use the rgb texture values as xyz displacement offsets. On grayscale textures this leads to stretching along the (1, 1, 1) axis.
Should I evaluate the texture three times at different coordinates for each grid cell to fix this? Or is this a limitation that is fine for now?

I think it's an acceptable limitation for now.

We could compute a gradient of the volume grid, and use that as a normal for displacement. But I'm not sure how well it would work, also in terms of temporal stability for animation.

Is the fact that the volume domain is not adaptive to the actual displacement texture, but expands depending on the strength in all directions an unavoidable limitation? Would be nice for viewport performance to have less voxels.

The issue is that the modifier does not know how the texture looks like without evaluating it at all points within a certain distance of the original volume. I already added a "prune" step that removes unnecessarily stored voxels in the end.
There could be an additional "Max Displacement" input that can limit the number of voxels where the texture is evaluated. This could be useful when the texture only contains relatively small values, but can also be used when to prevent cutting of the volume, when the texture values are large.
There might be better solutions to this problem, that I'm not aware of though..

I also don't immediately have a good solution for this. A max displacement option seems reasonable, that kind of things also exists in renderers. It's hard to automatically determine bounds of texture values, and it also helps keep memory usage more predictable.

This revision is now accepted and ready to land.Oct 7 2020, 2:21 PM

Also from testing, it may be good to have a parameter to prune away any voxels below a given density limit?

Looking at @Simon Thommes (simonthommes)'s video, the bounding boxes seems quite a bit larger than the actual volume at least, not sure if that's very small density values or something else.

  • add mid level per dimension
  • add texture sample radius
  • improve pruning

During dilation, many tiles/voxels became active.
Normal pruning would collaps active voxels/tiles with similar/same value, but would not remove them.
Turns out, I have to deactivate some voxels/tiles in a separate step, so that pruning actually removes them.

Simon Thommes (simonthommes) requested changes to this revision.Oct 7 2020, 4:27 PM

The issue is that the modifier does not know how the texture looks like without evaluating it at all points within a certain distance of the original volume. I already added a "prune" step that removes unnecessarily stored voxels in the end.
There could be an additional "Max Displacement" input that can limit the number of voxels where the texture is evaluated. This could be useful when the texture only contains relatively small values, but can also be used when to prevent cutting of the volume, when the texture values are large.
There might be better solutions to this problem, that I'm not aware of though..

Makes sense, thanks for the explanation!

I tested the changes. Generally looking good, thanks!

The object texture mapping now behaves as expected.
The pruning with slider is very useful.

There are two issues with the midlevel as far as I can see:

  1. It seems to interfere with the pruning, which does not consider the midlevel as an offset.


  1. It should effectively offset the resulting volume as a whole. Right now it seems offset before sampling the texture (?) (see comparison of behavior with mesh displacement)

Oh, and now that I look at it again, isn't the direction of the whole displacement invers?

This revision now requires changes to proceed.Oct 7 2020, 4:27 PM

It seems to interfere with the pruning, which does not consider the midlevel as an offset.

I'm not sure it should. The mid level is supposed to specify the "middle" of the texture. Generally, it should not be used to move the entire volume into a certain direction away from the original volume. Better move the original volume or the result then (which is much more efficient).

Oh, and now that I look at it again, isn't the direction of the whole displacement invers?

Can you provide the test file please?

It seems to interfere with the pruning, which does not consider the midlevel as an offset.

I'm not sure it should. The mid level is supposed to specify the "middle" of the texture. Generally, it should not be used to move the entire volume into a certain direction away from the original volume. Better move the original volume or the result then (which is much more efficient).

Good point!

Oh, and now that I look at it again, isn't the direction of the whole displacement invers?

Can you provide the test file please?

Sure, sorry!

Oh, and now that I look at it again, isn't the direction of the whole displacement invers?

Inverting the direction is trivial, but I'm not sure if that would make it move correct. This volume displacement algorithm just works quite differently from the mesh displacement modifier.
The mesh modifier computes the displacement at every vertex and then moves the vertex in that direction.
The volume modifier computes the displacement/offset in every voxel, and then does a lookup at the computed offset. This is inverse by nature. It works the same in a shader node tree.
This video shows the same behavior in shader nodes. When you increase the x offset, the texture moves to the left.

A "volume advection mode" would work more similar to the mesh displace modifier. It would move the grid in the direction of the displacement. That is planned for later.

Ah, okay.
Yes, I do understand the difference in the math behind it. It is just not very intuitive to have the modifier for mesh with the same name behave in a fundamentally different way.
Couldn't a similar behavior to the mesh displacement be approximated, maybe by inverting the offset direction and considering the mid level and strength before sampling the texture then?

But I understand the problem now. If that is something that is planned, then maybe it is just a matter of communicating that the behavior is different from mesh displacement.

Missed the latest conversation when I accepted.

The volume modifier computes the displacement/offset in every voxel, and then does a lookup at the computed offset. This is inverse by nature. It works the same in a shader node tree.

Maybe we should simply invert the offset value? It's indeed inverse in the algorithm, but this is kind of exposing an implementation detail. I think it would make sense if volume advection displaces in the same direction once that is implemented.

  • invert displace direction
This revision is now accepted and ready to land.Oct 7 2020, 5:51 PM
This revision was automatically updated to reflect the committed changes.