Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorKévin Dietrich <kevin.dietrich@mailoo.org>2022-04-19 17:28:14 +0300
committerKévin Dietrich <kevin.dietrich@mailoo.org>2022-04-19 18:07:53 +0300
commit2890c11cd7b008c3c261b6aa833c826c85cac504 (patch)
tree5bc3432767fc6dd260e6fec18bd1817766572abd /source
parent56cfd60d432bf387c21bf5bde08fece044fac99c (diff)
Cycles: add support for volume motion blur
This adds support for rendering motion blur for volumes, using their velocity field. This works for fluid simulations and imported VDB volumes. For the latter, the name of the velocity field can be set per volume object, with automatic detection of velocity fields that are split into 3 scalar grids. A new parameter is also added to scale velocity for more artistic control. Like for Alembic and USD caches, a parameter to set the unit of time in which the velocity vectors are expressed is also added. For Blender gas simulations, the velocity unit should always be in seconds, so this is only exposed for volume objects which may come from external OpenVDB files. These parameters are available under the `Render` panels for the fluid domain and the volume object data properties respectively. Credits: kernel advection code from Tangent Animation's Blackbird based on earlier work by Geraldine Chua Differential Revision: https://developer.blender.org/D14629
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_volume.h5
-rw-r--r--source/blender/blenkernel/intern/fluid.c3
-rw-r--r--source/blender/blenkernel/intern/volume.cc62
-rw-r--r--source/blender/makesdna/DNA_fluid_defaults.h1
-rw-r--r--source/blender/makesdna/DNA_fluid_types.h5
-rw-r--r--source/blender/makesdna/DNA_volume_defaults.h3
-rw-r--r--source/blender/makesdna/DNA_volume_types.h17
-rw-r--r--source/blender/makesrna/RNA_enum_items.h2
-rw-r--r--source/blender/makesrna/intern/rna_cachefile.c14
-rw-r--r--source/blender/makesrna/intern/rna_fluid.c6
-rw-r--r--source/blender/makesrna/intern/rna_volume.c59
11 files changed, 168 insertions, 9 deletions
diff --git a/source/blender/blenkernel/BKE_volume.h b/source/blender/blenkernel/BKE_volume.h
index 77f01e7919d..8791469360a 100644
--- a/source/blender/blenkernel/BKE_volume.h
+++ b/source/blender/blenkernel/BKE_volume.h
@@ -77,6 +77,11 @@ const VolumeGrid *BKE_volume_grid_active_get_for_read(const struct Volume *volum
/* Tries to find a grid with the given name. Make sure that the volume has been loaded. */
const VolumeGrid *BKE_volume_grid_find_for_read(const struct Volume *volume, const char *name);
+/* Tries to set the name of the velocity field. If no such grid exists with the given base name,
+ * this will try common postfixes in order to detect velocity fields split into multiple grids.
+ * Return false if neither finding with the base name nor with the postfixes succeeded. */
+bool BKE_volume_set_velocity_grid_by_name(struct Volume *volume, const char *base_name);
+
/* Grid
*
* By default only grid metadata is loaded, for access to the tree and voxels
diff --git a/source/blender/blenkernel/intern/fluid.c b/source/blender/blenkernel/intern/fluid.c
index 81e73b6cf2c..efb33294efd 100644
--- a/source/blender/blenkernel/intern/fluid.c
+++ b/source/blender/blenkernel/intern/fluid.c
@@ -5071,6 +5071,9 @@ void BKE_fluid_modifier_copy(const struct FluidModifierData *fmd,
tfds->openvdb_compression = fds->openvdb_compression;
tfds->clipping = fds->clipping;
tfds->openvdb_data_depth = fds->openvdb_data_depth;
+
+ /* Render options. */
+ tfds->velocity_scale = fds->velocity_scale;
}
else if (tfmd->flow) {
FluidFlowSettings *tffs = tfmd->flow;
diff --git a/source/blender/blenkernel/intern/volume.cc b/source/blender/blenkernel/intern/volume.cc
index 0c131863edd..307466d7dc9 100644
--- a/source/blender/blenkernel/intern/volume.cc
+++ b/source/blender/blenkernel/intern/volume.cc
@@ -60,6 +60,7 @@ using blender::float3;
using blender::float4x4;
using blender::IndexRange;
using blender::StringRef;
+using blender::StringRefNull;
#ifdef WITH_OPENVDB
# include <atomic>
@@ -517,6 +518,8 @@ static void volume_init_data(ID *id)
MEMCPY_STRUCT_AFTER(volume, DNA_struct_default_get(Volume), id);
BKE_volume_init_grids(volume);
+
+ BLI_strncpy(volume->velocity_grid, "velocity", sizeof(volume->velocity_grid));
}
static void volume_copy_data(Main *UNUSED(bmain),
@@ -794,6 +797,57 @@ bool BKE_volume_is_loaded(const Volume *volume)
#endif
}
+bool BKE_volume_set_velocity_grid_by_name(Volume *volume, const char *base_name)
+{
+ const StringRefNull ref_base_name = base_name;
+
+ if (BKE_volume_grid_find_for_read(volume, base_name)) {
+ BLI_strncpy(volume->velocity_grid, base_name, sizeof(volume->velocity_grid));
+ volume->runtime.velocity_x_grid[0] = '\0';
+ volume->runtime.velocity_y_grid[0] = '\0';
+ volume->runtime.velocity_z_grid[0] = '\0';
+ return true;
+ }
+
+ /* It could be that the velocity grid is split in multiple grids, try with known postfixes. */
+ const StringRefNull postfixes[][3] = {{"x", "y", "z"}, {".x", ".y", ".z"}, {"_x", "_y", "_z"}};
+
+ for (const StringRefNull *postfix : postfixes) {
+ bool found = true;
+ for (int i = 0; i < 3; i++) {
+ std::string post_fixed_name = ref_base_name + postfix[i];
+ if (!BKE_volume_grid_find_for_read(volume, post_fixed_name.c_str())) {
+ found = false;
+ break;
+ }
+ }
+
+ if (!found) {
+ continue;
+ }
+
+ /* Save the base name as well. */
+ BLI_strncpy(volume->velocity_grid, base_name, sizeof(volume->velocity_grid));
+ BLI_strncpy(volume->runtime.velocity_x_grid,
+ (ref_base_name + postfix[0]).c_str(),
+ sizeof(volume->runtime.velocity_x_grid));
+ BLI_strncpy(volume->runtime.velocity_y_grid,
+ (ref_base_name + postfix[1]).c_str(),
+ sizeof(volume->runtime.velocity_y_grid));
+ BLI_strncpy(volume->runtime.velocity_z_grid,
+ (ref_base_name + postfix[2]).c_str(),
+ sizeof(volume->runtime.velocity_z_grid));
+ return true;
+ }
+
+ /* Reset to avoid potential issues. */
+ volume->velocity_grid[0] = '\0';
+ volume->runtime.velocity_x_grid[0] = '\0';
+ volume->runtime.velocity_y_grid[0] = '\0';
+ volume->runtime.velocity_z_grid[0] = '\0';
+ return false;
+}
+
bool BKE_volume_load(const Volume *volume, const Main *bmain)
{
#ifdef WITH_OPENVDB
@@ -857,6 +911,14 @@ bool BKE_volume_load(const Volume *volume, const Main *bmain)
}
}
+ /* Try to detect the velocity grid. */
+ const char *common_velocity_names[] = {"velocity", "vel", "v"};
+ for (const char *common_velocity_name : common_velocity_names) {
+ if (BKE_volume_set_velocity_grid_by_name(const_cast<Volume *>(volume), common_velocity_name)) {
+ break;
+ }
+ }
+
BLI_strncpy(grids.filepath, filepath, FILE_MAX);
return grids.error_msg.empty();
diff --git a/source/blender/makesdna/DNA_fluid_defaults.h b/source/blender/makesdna/DNA_fluid_defaults.h
index fd48585792f..90a91c6c995 100644
--- a/source/blender/makesdna/DNA_fluid_defaults.h
+++ b/source/blender/makesdna/DNA_fluid_defaults.h
@@ -187,6 +187,7 @@
.cache_comp = SM_CACHE_LIGHT, \
.cache_high_comp = SM_CACHE_LIGHT, \
.cache_file_format = 0, \
+ .velocity_scale = 1.0f, \
}
/** \} */
diff --git a/source/blender/makesdna/DNA_fluid_types.h b/source/blender/makesdna/DNA_fluid_types.h
index 11780d99af8..5a1636879bb 100644
--- a/source/blender/makesdna/DNA_fluid_types.h
+++ b/source/blender/makesdna/DNA_fluid_types.h
@@ -670,7 +670,10 @@ typedef struct FluidDomainSettings {
char interp_method;
char gridlines_color_field; /* Simulation field used to color map onto gridlines. */
char gridlines_cell_filter;
- char _pad10[7]; /* Unused. */
+ char _pad10[3]; /* Unused. */
+
+ /* Velocity factor for motion blur rendering. */
+ float velocity_scale;
/* OpenVDB cache options. */
int openvdb_compression;
diff --git a/source/blender/makesdna/DNA_volume_defaults.h b/source/blender/makesdna/DNA_volume_defaults.h
index 2025d664d40..ee98f0ea4fd 100644
--- a/source/blender/makesdna/DNA_volume_defaults.h
+++ b/source/blender/makesdna/DNA_volume_defaults.h
@@ -36,7 +36,8 @@
.frame_duration = 0, \
.display = _DNA_DEFAULT_VolumeDisplay, \
.render = _DNA_DEFAULT_VolumeRender, \
- }
+ .velocity_scale = 1.0f, \
+}
/** \} */
diff --git a/source/blender/makesdna/DNA_volume_types.h b/source/blender/makesdna/DNA_volume_types.h
index f2f53bc910f..a2e558aa790 100644
--- a/source/blender/makesdna/DNA_volume_types.h
+++ b/source/blender/makesdna/DNA_volume_types.h
@@ -24,6 +24,11 @@ typedef struct Volume_Runtime {
/** Default simplify level for volume grids loaded from files. */
int default_simplify_level;
+
+ /* Names for scalar grids which would need to be merged to recompose the velocity grid. */
+ char velocity_x_grid[64];
+ char velocity_y_grid[64];
+ char velocity_z_grid[64];
} Volume_Runtime;
typedef struct VolumeDisplay {
@@ -75,6 +80,18 @@ typedef struct Volume {
VolumeRender render;
VolumeDisplay display;
+ /* Velocity field name. */
+ char velocity_grid[64];
+
+ char _pad3[3];
+
+ /* Unit of time the velocity vectors are expressed in.
+ * This uses the same enumeration values as #CacheFile.velocity_unit. */
+ char velocity_unit;
+
+ /* Factor for velocity vector for artistic control. */
+ float velocity_scale;
+
/* Draw Cache */
void *batch_cache;
diff --git a/source/blender/makesrna/RNA_enum_items.h b/source/blender/makesrna/RNA_enum_items.h
index 6e2c898d691..6539d636697 100644
--- a/source/blender/makesrna/RNA_enum_items.h
+++ b/source/blender/makesrna/RNA_enum_items.h
@@ -212,6 +212,8 @@ DEF_ENUM(rna_enum_subdivision_boundary_smooth_items)
DEF_ENUM(rna_enum_transform_orientation_items)
+DEF_ENUM(rna_enum_velocity_unit_items)
+
/* Not available to RNA pre-processing (`makesrna`).
* Defined in editors for example. */
#ifndef RNA_MAKESRNA
diff --git a/source/blender/makesrna/intern/rna_cachefile.c b/source/blender/makesrna/intern/rna_cachefile.c
index 62b08ebb281..c8b154b9b04 100644
--- a/source/blender/makesrna/intern/rna_cachefile.c
+++ b/source/blender/makesrna/intern/rna_cachefile.c
@@ -14,6 +14,12 @@
#include "rna_internal.h"
+const EnumPropertyItem rna_enum_velocity_unit_items[] = {
+ {CACHEFILE_VELOCITY_UNIT_SECOND, "SECOND", 0, "Second", ""},
+ {CACHEFILE_VELOCITY_UNIT_FRAME, "FRAME", 0, "Frame", ""},
+ {0, NULL, 0, NULL, NULL},
+};
+
#ifdef RNA_RUNTIME
# include "BLI_math.h"
@@ -350,15 +356,9 @@ static void rna_def_cachefile(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_CacheFile_update");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- static const EnumPropertyItem velocity_unit_items[] = {
- {CACHEFILE_VELOCITY_UNIT_SECOND, "SECOND", 0, "Second", ""},
- {CACHEFILE_VELOCITY_UNIT_FRAME, "FRAME", 0, "Frame", ""},
- {0, NULL, 0, NULL, NULL},
- };
-
prop = RNA_def_property(srna, "velocity_unit", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "velocity_unit");
- RNA_def_property_enum_items(prop, velocity_unit_items);
+ RNA_def_property_enum_items(prop, rna_enum_velocity_unit_items);
RNA_def_property_ui_text(
prop,
"Velocity Unit",
diff --git a/source/blender/makesrna/intern/rna_fluid.c b/source/blender/makesrna/intern/rna_fluid.c
index dab3cd68d4c..e0ec146a248 100644
--- a/source/blender/makesrna/intern/rna_fluid.c
+++ b/source/blender/makesrna/intern/rna_fluid.c
@@ -2644,6 +2644,12 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna)
RNA_def_property_enum_items(prop, gridlines_cell_filter_items);
RNA_def_property_ui_text(prop, "Cell Type", "Cell type to be highlighted");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
+
+ prop = RNA_def_property(srna, "velocity_scale", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "velocity_scale");
+ RNA_def_property_range(prop, 0.0f, FLT_MAX);
+ RNA_def_property_ui_text(prop, "Velocity Scale", "Factor to control the amount of motion blur");
+ RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Fluid_update");
}
static void rna_def_fluid_flow_settings(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_volume.c b/source/blender/makesrna/intern/rna_volume.c
index 5b323629a80..12cb35b239d 100644
--- a/source/blender/makesrna/intern/rna_volume.c
+++ b/source/blender/makesrna/intern/rna_volume.c
@@ -78,6 +78,15 @@ static void rna_Volume_update_is_sequence(Main *bmain, Scene *scene, PointerRNA
DEG_relations_tag_update(bmain);
}
+static void rna_Volume_velocity_grid_set(PointerRNA *ptr, const char *value)
+{
+ Volume *volume = (Volume *)ptr->data;
+ if (!BKE_volume_set_velocity_grid_by_name(volume, value)) {
+ WM_reportf(RPT_ERROR, "Could not find grid with name %s", value);
+ }
+ WM_main_add_notifier(NC_GEOM | ND_DATA, volume);
+}
+
/* Grid */
static void rna_VolumeGrid_name_get(PointerRNA *ptr, char *value)
@@ -248,6 +257,7 @@ static void rna_def_volume_grid(BlenderRNA *brna)
RNA_def_property_string_funcs(
prop, "rna_VolumeGrid_name_get", "rna_VolumeGrid_name_length", NULL);
RNA_def_property_ui_text(prop, "Name", "Volume grid name");
+ RNA_def_struct_name_property(srna, prop);
prop = RNA_def_property(srna, "data_type", PROP_ENUM, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
@@ -619,6 +629,55 @@ static void rna_def_volume(BlenderRNA *brna)
RNA_def_property_struct_type(prop, "VolumeRender");
RNA_def_property_ui_text(prop, "Render", "Volume render settings for 3D viewport");
+ /* Velocity. */
+ prop = RNA_def_property(srna, "velocity_grid", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "velocity_grid");
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_Volume_velocity_grid_set");
+ RNA_def_property_ui_text(
+ prop,
+ "Velocity Grid",
+ "Name of the velocity field, or the base name if the velocity is split into multiple grids");
+
+ prop = RNA_def_property(srna, "velocity_unit", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "velocity_unit");
+ RNA_def_property_enum_items(prop, rna_enum_velocity_unit_items);
+ RNA_def_property_ui_text(
+ prop,
+ "Velocity Unit",
+ "Define how the velocity vectors are interpreted with regard to time, 'frame' means "
+ "the delta time is 1 frame, 'second' means the delta time is 1 / FPS");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+
+ prop = RNA_def_property(srna, "velocity_scale", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "velocity_scale");
+ RNA_def_property_range(prop, 0.0f, FLT_MAX);
+ RNA_def_property_ui_text(prop, "Velocity Scale", "Factor to control the amount of motion blur");
+
+ /* Scalar grids for velocity. */
+ prop = RNA_def_property(srna, "velocity_x_grid", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "runtime.velocity_x_grid");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop,
+ "Velocity X Grid",
+ "Name of the grid for the X axis component of the velocity field if it "
+ "was split into multiple grids");
+
+ prop = RNA_def_property(srna, "velocity_y_grid", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "runtime.velocity_y_grid");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop,
+ "Velocity Y Grid",
+ "Name of the grid for the Y axis component of the velocity field if it "
+ "was split into multiple grids");
+
+ prop = RNA_def_property(srna, "velocity_z_grid", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "runtime.velocity_z_grid");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop,
+ "Velocity Z Grid",
+ "Name of the grid for the Z axis component of the velocity field if it "
+ "was split into multiple grids");
+
/* Common */
rna_def_animdata_common(srna);
}