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
diff options
context:
space:
mode:
authorBrecht Van Lommel <brecht>2020-03-07 16:38:52 +0300
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2020-03-18 13:23:05 +0300
commit1162ba206dd7792414d3ae716877ba1383de8dab (patch)
tree3b243a7c33dfbbc6414e96a4df6b37ddc47531cd /intern/cycles/render
parent9d20f170c7c07ac38e86130de591ae98e9c0cf80 (diff)
Cycles: change volume step size controls, auto adjust based on voxel size
By default it will now set the step size to the voxel size for smoke and volume objects, and 1/10th the bounding box for procedural volume shaders. New settings are: * Scene render/preview step rate: to globally adjust detail and performance * Material step rate: multiplied with auto detected per-object step size * World step size: distance to steo for world shader Differential Revision: https://developer.blender.org/D1777
Diffstat (limited to 'intern/cycles/render')
-rw-r--r--intern/cycles/render/background.cpp4
-rw-r--r--intern/cycles/render/background.h2
-rw-r--r--intern/cycles/render/integrator.cpp4
-rw-r--r--intern/cycles/render/integrator.h2
-rw-r--r--intern/cycles/render/object.cpp71
-rw-r--r--intern/cycles/render/object.h3
-rw-r--r--intern/cycles/render/osl.cpp8
-rw-r--r--intern/cycles/render/scene.cpp1
-rw-r--r--intern/cycles/render/scene.h1
-rw-r--r--intern/cycles/render/shader.cpp18
-rw-r--r--intern/cycles/render/shader.h4
-rw-r--r--intern/cycles/render/svm.cpp8
12 files changed, 106 insertions, 20 deletions
diff --git a/intern/cycles/render/background.cpp b/intern/cycles/render/background.cpp
index 6553ca735e4..5a61ead2c54 100644
--- a/intern/cycles/render/background.cpp
+++ b/intern/cycles/render/background.cpp
@@ -43,6 +43,8 @@ NODE_DEFINE(Background)
SOCKET_BOOLEAN(transparent_glass, "Transparent Glass", false);
SOCKET_FLOAT(transparent_roughness_threshold, "Transparent Roughness Threshold", 0.0f);
+ SOCKET_FLOAT(volume_step_size, "Volume Step Size", 0.1f);
+
SOCKET_NODE(shader, "Shader", &Shader::node_type);
return type;
@@ -91,6 +93,8 @@ void Background::device_update(Device *device, DeviceScene *dscene, Scene *scene
else
kbackground->volume_shader = SHADER_NONE;
+ kbackground->volume_step_size = volume_step_size * scene->integrator->volume_step_rate;
+
/* No background node, make world shader invisible to all rays, to skip evaluation in kernel. */
if (bg_shader->graph->nodes.size() <= 1) {
kbackground->surface_shader |= SHADER_EXCLUDE_ANY;
diff --git a/intern/cycles/render/background.h b/intern/cycles/render/background.h
index fb27430f9a3..c2ca1f75179 100644
--- a/intern/cycles/render/background.h
+++ b/intern/cycles/render/background.h
@@ -45,6 +45,8 @@ class Background : public Node {
bool transparent_glass;
float transparent_roughness_threshold;
+ float volume_step_size;
+
bool need_update;
Background();
diff --git a/intern/cycles/render/integrator.cpp b/intern/cycles/render/integrator.cpp
index ee1aa5988bf..d856f7a300f 100644
--- a/intern/cycles/render/integrator.cpp
+++ b/intern/cycles/render/integrator.cpp
@@ -50,7 +50,7 @@ NODE_DEFINE(Integrator)
SOCKET_INT(ao_bounces, "AO Bounces", 0);
SOCKET_INT(volume_max_steps, "Volume Max Steps", 1024);
- SOCKET_FLOAT(volume_step_size, "Volume Step Size", 0.1f);
+ SOCKET_FLOAT(volume_step_rate, "Volume Step Rate", 1.0f);
SOCKET_BOOLEAN(caustics_reflective, "Reflective Caustics", true);
SOCKET_BOOLEAN(caustics_refractive, "Refractive Caustics", true);
@@ -143,7 +143,7 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene
}
kintegrator->volume_max_steps = volume_max_steps;
- kintegrator->volume_step_size = volume_step_size;
+ kintegrator->volume_step_rate = volume_step_rate;
kintegrator->caustics_reflective = caustics_reflective;
kintegrator->caustics_refractive = caustics_refractive;
diff --git a/intern/cycles/render/integrator.h b/intern/cycles/render/integrator.h
index 9930e907aea..9804caebe6e 100644
--- a/intern/cycles/render/integrator.h
+++ b/intern/cycles/render/integrator.h
@@ -45,7 +45,7 @@ class Integrator : public Node {
int ao_bounces;
int volume_max_steps;
- float volume_step_size;
+ float volume_step_rate;
bool caustics_reflective;
bool caustics_refractive;
diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp
index 4987b6089d7..c84007823d2 100644
--- a/intern/cycles/render/object.cpp
+++ b/intern/cycles/render/object.cpp
@@ -17,6 +17,7 @@
#include "render/camera.h"
#include "device/device.h"
#include "render/hair.h"
+#include "render/integrator.h"
#include "render/light.h"
#include "render/mesh.h"
#include "render/curves.h"
@@ -65,6 +66,7 @@ struct UpdateObjectTransformState {
KernelObject *objects;
Transform *object_motion_pass;
DecomposedTransform *object_motion;
+ float *object_volume_step;
/* Flags which will be synchronized to Integrator. */
bool have_motion;
@@ -266,6 +268,65 @@ uint Object::visibility_for_tracing() const
return trace_visibility;
}
+float Object::compute_volume_step_size() const
+{
+ if (!geometry->has_volume) {
+ return FLT_MAX;
+ }
+
+ /* Compute step rate from shaders. */
+ float step_rate = FLT_MAX;
+
+ foreach (Shader *shader, geometry->used_shaders) {
+ if (shader->has_volume) {
+ if ((shader->heterogeneous_volume && shader->has_volume_spatial_varying) ||
+ (shader->has_volume_attribute_dependency)) {
+ step_rate = fminf(shader->volume_step_rate, step_rate);
+ }
+ }
+ }
+
+ if (step_rate == FLT_MAX) {
+ return FLT_MAX;
+ }
+
+ /* Compute step size from voxel grids. */
+ float step_size = FLT_MAX;
+
+ foreach (Attribute &attr, geometry->attributes.attributes) {
+ if (attr.element == ATTR_ELEMENT_VOXEL) {
+ ImageHandle &handle = attr.data_voxel();
+ const ImageMetaData &metadata = handle.metadata();
+ if (metadata.width == 0 || metadata.height == 0 || metadata.depth == 0) {
+ continue;
+ }
+
+ /* Step size is transformed from voxel to world space. */
+ Transform voxel_tfm = tfm;
+ if (metadata.use_transform_3d) {
+ voxel_tfm = tfm * transform_inverse(metadata.transform_3d);
+ }
+
+ float3 size = make_float3(
+ 1.0f / metadata.width, 1.0f / metadata.height, 1.0f / metadata.depth);
+ float voxel_step_size = min3(fabs(transform_direction(&voxel_tfm, size)));
+
+ if (voxel_step_size > 0.0f) {
+ step_size = fminf(voxel_step_size, step_size);
+ }
+ }
+ }
+
+ if (step_size == FLT_MAX) {
+ /* Fall back to 1/10th of bounds for procedural volumes. */
+ step_size = 0.1f * average(bounds.size());
+ }
+
+ step_size *= step_rate;
+
+ return step_size;
+}
+
int Object::get_device_index() const
{
return index;
@@ -451,6 +512,7 @@ void ObjectManager::device_update_object_transform(UpdateObjectTransformState *s
flag |= SD_OBJECT_HOLDOUT_MASK;
}
state->object_flag[ob->index] = flag;
+ state->object_volume_step[ob->index] = FLT_MAX;
/* Have curves. */
if (geom->type == Geometry::HAIR) {
@@ -504,6 +566,7 @@ void ObjectManager::device_update_transforms(DeviceScene *dscene, Scene *scene,
state.objects = dscene->objects.alloc(scene->objects.size());
state.object_flag = dscene->object_flag.alloc(scene->objects.size());
+ state.object_volume_step = dscene->object_volume_step.alloc(scene->objects.size());
state.object_motion = NULL;
state.object_motion_pass = NULL;
@@ -624,6 +687,7 @@ void ObjectManager::device_update_flags(
/* Object info flag. */
uint *object_flag = dscene->object_flag.data();
+ float *object_volume_step = dscene->object_volume_step.data();
/* Object volume intersection. */
vector<Object *> volume_objects;
@@ -634,6 +698,10 @@ void ObjectManager::device_update_flags(
volume_objects.push_back(object);
}
has_volume_objects = true;
+ object_volume_step[object->index] = object->compute_volume_step_size();
+ }
+ else {
+ object_volume_step[object->index] = FLT_MAX;
}
}
@@ -651,6 +719,7 @@ void ObjectManager::device_update_flags(
else {
object_flag[object->index] &= ~(SD_OBJECT_HAS_VOLUME | SD_OBJECT_HAS_VOLUME_ATTRIBUTES);
}
+
if (object->is_shadow_catcher) {
object_flag[object->index] |= SD_OBJECT_SHADOW_CATCHER;
}
@@ -679,6 +748,7 @@ void ObjectManager::device_update_flags(
/* Copy object flag. */
dscene->object_flag.copy_to_device();
+ dscene->object_volume_step.copy_to_device();
}
void ObjectManager::device_update_mesh_offsets(Device *, DeviceScene *dscene, Scene *scene)
@@ -725,6 +795,7 @@ void ObjectManager::device_free(Device *, DeviceScene *dscene)
dscene->object_motion_pass.free();
dscene->object_motion.free();
dscene->object_flag.free();
+ dscene->object_volume_step.free();
}
void ObjectManager::apply_static_transforms(DeviceScene *dscene, Scene *scene, Progress &progress)
diff --git a/intern/cycles/render/object.h b/intern/cycles/render/object.h
index 7bd3edf769b..2c2870cd0f2 100644
--- a/intern/cycles/render/object.h
+++ b/intern/cycles/render/object.h
@@ -97,6 +97,9 @@ class Object : public Node {
/* Returns the index that is used in the kernel for this object. */
int get_device_index() const;
+ /* Compute step size from attributes, shaders, transforms. */
+ float compute_volume_step_size() const;
+
protected:
/* Specifies the position of the object in scene->objects and
* in the device vectors. Gets set in device_update. */
diff --git a/intern/cycles/render/osl.cpp b/intern/cycles/render/osl.cpp
index d17d7270cd5..74eb61e2dff 100644
--- a/intern/cycles/render/osl.cpp
+++ b/intern/cycles/render/osl.cpp
@@ -760,16 +760,14 @@ void OSLCompiler::add(ShaderNode *node, const char *name, bool isfilepath)
else if (current_type == SHADER_TYPE_VOLUME) {
if (node->has_spatial_varying())
current_shader->has_volume_spatial_varying = true;
+ if (node->has_attribute_dependency())
+ current_shader->has_volume_attribute_dependency = true;
}
if (node->has_object_dependency()) {
current_shader->has_object_dependency = true;
}
- if (node->has_attribute_dependency()) {
- current_shader->has_attribute_dependency = true;
- }
-
if (node->has_integrator_dependency()) {
current_shader->has_integrator_dependency = true;
}
@@ -1143,8 +1141,8 @@ void OSLCompiler::compile(OSLGlobals *og, Shader *shader)
shader->has_displacement = false;
shader->has_surface_spatial_varying = false;
shader->has_volume_spatial_varying = false;
+ shader->has_volume_attribute_dependency = false;
shader->has_object_dependency = false;
- shader->has_attribute_dependency = false;
shader->has_integrator_dependency = false;
/* generate surface shader */
diff --git a/intern/cycles/render/scene.cpp b/intern/cycles/render/scene.cpp
index 76f62fd6690..77c66779c20 100644
--- a/intern/cycles/render/scene.cpp
+++ b/intern/cycles/render/scene.cpp
@@ -63,6 +63,7 @@ DeviceScene::DeviceScene(Device *device)
object_motion_pass(device, "__object_motion_pass", MEM_GLOBAL),
object_motion(device, "__object_motion", MEM_GLOBAL),
object_flag(device, "__object_flag", MEM_GLOBAL),
+ object_volume_step(device, "__object_volume_step", MEM_GLOBAL),
camera_motion(device, "__camera_motion", MEM_GLOBAL),
attributes_map(device, "__attributes_map", MEM_GLOBAL),
attributes_float(device, "__attributes_float", MEM_GLOBAL),
diff --git a/intern/cycles/render/scene.h b/intern/cycles/render/scene.h
index d2570138b53..6b10a901d7b 100644
--- a/intern/cycles/render/scene.h
+++ b/intern/cycles/render/scene.h
@@ -91,6 +91,7 @@ class DeviceScene {
device_vector<Transform> object_motion_pass;
device_vector<DecomposedTransform> object_motion;
device_vector<uint> object_flag;
+ device_vector<float> object_volume_step;
/* cameras */
device_vector<DecomposedTransform> camera_motion;
diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp
index cc6eb2e5e7f..747fc58f81a 100644
--- a/intern/cycles/render/shader.cpp
+++ b/intern/cycles/render/shader.cpp
@@ -178,6 +178,8 @@ NODE_DEFINE(Shader)
volume_interpolation_method_enum,
VOLUME_INTERPOLATION_LINEAR);
+ SOCKET_FLOAT(volume_step_rate, "Volume Step Rate", 1.0f);
+
static NodeEnum displacement_method_enum;
displacement_method_enum.insert("bump", DISPLACE_BUMP);
displacement_method_enum.insert("true", DISPLACE_TRUE);
@@ -203,10 +205,11 @@ Shader::Shader() : Node(node_type)
has_bssrdf_bump = false;
has_surface_spatial_varying = false;
has_volume_spatial_varying = false;
+ has_volume_attribute_dependency = false;
has_object_dependency = false;
- has_attribute_dependency = false;
has_integrator_dependency = false;
has_volume_connected = false;
+ prev_volume_step_rate = 0.0f;
displacement_method = DISPLACE_BUMP;
@@ -353,9 +356,10 @@ void Shader::tag_update(Scene *scene)
scene->geometry_manager->need_update = true;
}
- if (has_volume != prev_has_volume) {
+ if (has_volume != prev_has_volume || volume_step_rate != prev_volume_step_rate) {
scene->geometry_manager->need_flags_update = true;
scene->object_manager->need_flags_update = true;
+ prev_volume_step_rate = volume_step_rate;
}
}
@@ -533,10 +537,12 @@ void ShaderManager::device_update_common(Device *device,
/* in this case we can assume transparent surface */
if (shader->has_volume_connected && !shader->has_surface)
flag |= SD_HAS_ONLY_VOLUME;
- if (shader->heterogeneous_volume && shader->has_volume_spatial_varying)
- flag |= SD_HETEROGENEOUS_VOLUME;
- if (shader->has_attribute_dependency)
- flag |= SD_NEED_ATTRIBUTES;
+ if (shader->has_volume) {
+ if (shader->heterogeneous_volume && shader->has_volume_spatial_varying)
+ flag |= SD_HETEROGENEOUS_VOLUME;
+ }
+ if (shader->has_volume_attribute_dependency)
+ flag |= SD_NEED_VOLUME_ATTRIBUTES;
if (shader->has_bssrdf_bump)
flag |= SD_HAS_BSSRDF_BUMP;
if (device->info.has_volume_decoupled) {
diff --git a/intern/cycles/render/shader.h b/intern/cycles/render/shader.h
index 5a5b42de994..1509150228f 100644
--- a/intern/cycles/render/shader.h
+++ b/intern/cycles/render/shader.h
@@ -92,6 +92,8 @@ class Shader : public Node {
bool heterogeneous_volume;
VolumeSampling volume_sampling_method;
int volume_interpolation_method;
+ float volume_step_rate;
+ float prev_volume_step_rate;
/* synchronization */
bool need_update;
@@ -118,8 +120,8 @@ class Shader : public Node {
bool has_bssrdf_bump;
bool has_surface_spatial_varying;
bool has_volume_spatial_varying;
+ bool has_volume_attribute_dependency;
bool has_object_dependency;
- bool has_attribute_dependency;
bool has_integrator_dependency;
/* displacement */
diff --git a/intern/cycles/render/svm.cpp b/intern/cycles/render/svm.cpp
index 2946614a3b7..c4218f7df1e 100644
--- a/intern/cycles/render/svm.cpp
+++ b/intern/cycles/render/svm.cpp
@@ -444,16 +444,14 @@ void SVMCompiler::generate_node(ShaderNode *node, ShaderNodeSet &done)
else if (current_type == SHADER_TYPE_VOLUME) {
if (node->has_spatial_varying())
current_shader->has_volume_spatial_varying = true;
+ if (node->has_attribute_dependency())
+ current_shader->has_volume_attribute_dependency = true;
}
if (node->has_object_dependency()) {
current_shader->has_object_dependency = true;
}
- if (node->has_attribute_dependency()) {
- current_shader->has_attribute_dependency = true;
- }
-
if (node->has_integrator_dependency()) {
current_shader->has_integrator_dependency = true;
}
@@ -864,8 +862,8 @@ void SVMCompiler::compile(Shader *shader, array<int4> &svm_nodes, int index, Sum
shader->has_displacement = false;
shader->has_surface_spatial_varying = false;
shader->has_volume_spatial_varying = false;
+ shader->has_volume_attribute_dependency = false;
shader->has_object_dependency = false;
- shader->has_attribute_dependency = false;
shader->has_integrator_dependency = false;
/* generate bump shader */