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/kernel
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/kernel')
-rw-r--r--intern/cycles/kernel/geom/geom_object.h11
-rw-r--r--intern/cycles/kernel/kernel_path.h8
-rw-r--r--intern/cycles/kernel/kernel_path_branched.h6
-rw-r--r--intern/cycles/kernel/kernel_textures.h1
-rw-r--r--intern/cycles/kernel/kernel_types.h10
-rw-r--r--intern/cycles/kernel/kernel_volume.h51
-rw-r--r--intern/cycles/kernel/split/kernel_do_volume.h8
7 files changed, 61 insertions, 34 deletions
diff --git a/intern/cycles/kernel/geom/geom_object.h b/intern/cycles/kernel/geom/geom_object.h
index ac2ddf575ca..c6d02ed9702 100644
--- a/intern/cycles/kernel/geom/geom_object.h
+++ b/intern/cycles/kernel/geom/geom_object.h
@@ -320,6 +320,17 @@ ccl_device_inline uint object_patch_map_offset(KernelGlobals *kg, int object)
return kernel_tex_fetch(__objects, object).patch_map_offset;
}
+/* Volume step size */
+
+ccl_device_inline float object_volume_step_size(KernelGlobals *kg, int object)
+{
+ if (object == OBJECT_NONE) {
+ return kernel_data.background.volume_step_size;
+ }
+
+ return kernel_tex_fetch(__object_volume_step, object);
+}
+
/* Pass ID for shader */
ccl_device int shader_pass_id(KernelGlobals *kg, const ShaderData *sd)
diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h
index 74377f2c069..db35303e3f1 100644
--- a/intern/cycles/kernel/kernel_path.h
+++ b/intern/cycles/kernel/kernel_path.h
@@ -171,19 +171,19 @@ ccl_device_forceinline VolumeIntegrateResult kernel_path_volume(KernelGlobals *k
Ray volume_ray = *ray;
volume_ray.t = (hit) ? isect->t : FLT_MAX;
- bool heterogeneous = volume_stack_is_heterogeneous(kg, state->volume_stack);
+ float step_size = volume_stack_step_size(kg, state->volume_stack);
# ifdef __VOLUME_DECOUPLED__
int sampling_method = volume_stack_sampling_method(kg, state->volume_stack);
bool direct = (state->flag & PATH_RAY_CAMERA) != 0;
- bool decoupled = kernel_volume_use_decoupled(kg, heterogeneous, direct, sampling_method);
+ bool decoupled = kernel_volume_use_decoupled(kg, step_size, direct, sampling_method);
if (decoupled) {
/* cache steps along volume for repeated sampling */
VolumeSegment volume_segment;
shader_setup_from_volume(kg, sd, &volume_ray);
- kernel_volume_decoupled_record(kg, state, &volume_ray, sd, &volume_segment, heterogeneous);
+ kernel_volume_decoupled_record(kg, state, &volume_ray, sd, &volume_segment, step_size);
volume_segment.sampling_method = sampling_method;
@@ -229,7 +229,7 @@ ccl_device_forceinline VolumeIntegrateResult kernel_path_volume(KernelGlobals *k
{
/* integrate along volume segment with distance sampling */
VolumeIntegrateResult result = kernel_volume_integrate(
- kg, state, sd, &volume_ray, L, throughput, heterogeneous);
+ kg, state, sd, &volume_ray, L, throughput, step_size);
# ifdef __VOLUME_SCATTER__
if (result == VOLUME_PATH_SCATTERED) {
diff --git a/intern/cycles/kernel/kernel_path_branched.h b/intern/cycles/kernel/kernel_path_branched.h
index 0d5781fe3d1..337c4fb1d10 100644
--- a/intern/cycles/kernel/kernel_path_branched.h
+++ b/intern/cycles/kernel/kernel_path_branched.h
@@ -91,7 +91,7 @@ ccl_device_forceinline void kernel_branched_path_volume(KernelGlobals *kg,
Ray volume_ray = *ray;
volume_ray.t = (hit) ? isect->t : FLT_MAX;
- bool heterogeneous = volume_stack_is_heterogeneous(kg, state->volume_stack);
+ float step_size = volume_stack_step_size(kg, state->volume_stack);
# ifdef __VOLUME_DECOUPLED__
/* decoupled ray marching only supported on CPU */
@@ -100,7 +100,7 @@ ccl_device_forceinline void kernel_branched_path_volume(KernelGlobals *kg,
VolumeSegment volume_segment;
shader_setup_from_volume(kg, sd, &volume_ray);
- kernel_volume_decoupled_record(kg, state, &volume_ray, sd, &volume_segment, heterogeneous);
+ kernel_volume_decoupled_record(kg, state, &volume_ray, sd, &volume_segment, step_size);
/* direct light sampling */
if (volume_segment.closure_flag & SD_SCATTER) {
@@ -171,7 +171,7 @@ ccl_device_forceinline void kernel_branched_path_volume(KernelGlobals *kg,
path_state_branch(&ps, j, num_samples);
VolumeIntegrateResult result = kernel_volume_integrate(
- kg, &ps, sd, &volume_ray, L, &tp, heterogeneous);
+ kg, &ps, sd, &volume_ray, L, &tp, step_size);
# ifdef __VOLUME_SCATTER__
if (result == VOLUME_PATH_SCATTERED) {
diff --git a/intern/cycles/kernel/kernel_textures.h b/intern/cycles/kernel/kernel_textures.h
index 1cae34348c9..c8e01677d09 100644
--- a/intern/cycles/kernel/kernel_textures.h
+++ b/intern/cycles/kernel/kernel_textures.h
@@ -35,6 +35,7 @@ KERNEL_TEX(KernelObject, __objects)
KERNEL_TEX(Transform, __object_motion_pass)
KERNEL_TEX(DecomposedTransform, __object_motion)
KERNEL_TEX(uint, __object_flag)
+KERNEL_TEX(float, __object_volume_step)
/* cameras */
KERNEL_TEX(DecomposedTransform, __camera_motion)
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index c5be93e2cda..6a0e74efc91 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -887,13 +887,13 @@ enum ShaderDataFlag {
SD_HAS_DISPLACEMENT = (1 << 26),
/* Has constant emission (value stored in __shaders) */
SD_HAS_CONSTANT_EMISSION = (1 << 27),
- /* Needs to access attributes */
- SD_NEED_ATTRIBUTES = (1 << 28),
+ /* Needs to access attributes for volume rendering */
+ SD_NEED_VOLUME_ATTRIBUTES = (1 << 28),
SD_SHADER_FLAGS = (SD_USE_MIS | SD_HAS_TRANSPARENT_SHADOW | SD_HAS_VOLUME | SD_HAS_ONLY_VOLUME |
SD_HETEROGENEOUS_VOLUME | SD_HAS_BSSRDF_BUMP | SD_VOLUME_EQUIANGULAR |
SD_VOLUME_MIS | SD_VOLUME_CUBIC | SD_HAS_BUMP | SD_HAS_DISPLACEMENT |
- SD_HAS_CONSTANT_EMISSION | SD_NEED_ATTRIBUTES)
+ SD_HAS_CONSTANT_EMISSION | SD_NEED_VOLUME_ATTRIBUTES)
};
/* Object flags. */
@@ -1275,6 +1275,7 @@ typedef struct KernelBackground {
/* only shader index */
int surface_shader;
int volume_shader;
+ float volume_step_size;
int transparent;
float transparent_roughness_squared_threshold;
@@ -1282,7 +1283,6 @@ typedef struct KernelBackground {
float ao_factor;
float ao_distance;
float ao_bounces_factor;
- float ao_pad;
} KernelBackground;
static_assert_align(KernelBackground, 16);
@@ -1355,7 +1355,7 @@ typedef struct KernelIntegrator {
/* volume render */
int use_volumes;
int volume_max_steps;
- float volume_step_size;
+ float volume_step_rate;
int volume_samples;
int start_sample;
diff --git a/intern/cycles/kernel/kernel_volume.h b/intern/cycles/kernel/kernel_volume.h
index f443bb88463..035fcdbc8e1 100644
--- a/intern/cycles/kernel/kernel_volume.h
+++ b/intern/cycles/kernel/kernel_volume.h
@@ -101,15 +101,19 @@ ccl_device float kernel_volume_channel_get(float3 value, int channel)
#ifdef __VOLUME__
-ccl_device bool volume_stack_is_heterogeneous(KernelGlobals *kg, ccl_addr_space VolumeStack *stack)
+ccl_device float volume_stack_step_size(KernelGlobals *kg, ccl_addr_space VolumeStack *stack)
{
+ float step_size = FLT_MAX;
+
for (int i = 0; stack[i].shader != SHADER_NONE; i++) {
int shader_flag = kernel_tex_fetch(__shaders, (stack[i].shader & SHADER_MASK)).flags;
+ bool heterogeneous = false;
+
if (shader_flag & SD_HETEROGENEOUS_VOLUME) {
- return true;
+ heterogeneous = true;
}
- else if (shader_flag & SD_NEED_ATTRIBUTES) {
+ else if (shader_flag & SD_NEED_VOLUME_ATTRIBUTES) {
/* We want to render world or objects without any volume grids
* as homogeneous, but can only verify this at run-time since other
* heterogeneous volume objects may be using the same shader. */
@@ -117,13 +121,19 @@ ccl_device bool volume_stack_is_heterogeneous(KernelGlobals *kg, ccl_addr_space
if (object != OBJECT_NONE) {
int object_flag = kernel_tex_fetch(__object_flag, object);
if (object_flag & SD_OBJECT_HAS_VOLUME_ATTRIBUTES) {
- return true;
+ heterogeneous = true;
}
}
}
+
+ if (heterogeneous) {
+ float object_step_size = object_volume_step_size(kg, stack[i].object);
+ object_step_size *= kernel_data.integrator.volume_step_rate;
+ step_size = fminf(object_step_size, step_size);
+ }
}
- return false;
+ return step_size;
}
ccl_device int volume_stack_sampling_method(KernelGlobals *kg, VolumeStack *stack)
@@ -158,12 +168,13 @@ ccl_device int volume_stack_sampling_method(KernelGlobals *kg, VolumeStack *stac
ccl_device_inline void kernel_volume_step_init(KernelGlobals *kg,
ccl_addr_space PathState *state,
+ const float object_step_size,
float t,
float *step_size,
float *step_offset)
{
const int max_steps = kernel_data.integrator.volume_max_steps;
- float step = min(kernel_data.integrator.volume_step_size, t);
+ float step = min(object_step_size, t);
/* compute exact steps in advance for malloc */
if (t > max_steps * step) {
@@ -199,7 +210,8 @@ ccl_device void kernel_volume_shadow_heterogeneous(KernelGlobals *kg,
ccl_addr_space PathState *state,
Ray *ray,
ShaderData *sd,
- float3 *throughput)
+ float3 *throughput,
+ const float object_step_size)
{
float3 tp = *throughput;
const float tp_eps = 1e-6f; /* todo: this is likely not the right value */
@@ -207,7 +219,7 @@ ccl_device void kernel_volume_shadow_heterogeneous(KernelGlobals *kg,
/* prepare for stepping */
int max_steps = kernel_data.integrator.volume_max_steps;
float step_offset, step_size;
- kernel_volume_step_init(kg, state, ray->t, &step_size, &step_offset);
+ kernel_volume_step_init(kg, state, object_step_size, ray->t, &step_size, &step_offset);
/* compute extinction at the start */
float t = 0.0f;
@@ -264,8 +276,9 @@ ccl_device_noinline void kernel_volume_shadow(KernelGlobals *kg,
{
shader_setup_from_volume(kg, shadow_sd, ray);
- if (volume_stack_is_heterogeneous(kg, state->volume_stack))
- kernel_volume_shadow_heterogeneous(kg, state, ray, shadow_sd, throughput);
+ float step_size = volume_stack_step_size(kg, state->volume_stack);
+ if (step_size != FLT_MAX)
+ kernel_volume_shadow_heterogeneous(kg, state, ray, shadow_sd, throughput, step_size);
else
kernel_volume_shadow_homogeneous(kg, state, ray, shadow_sd, throughput);
}
@@ -533,7 +546,8 @@ kernel_volume_integrate_heterogeneous_distance(KernelGlobals *kg,
Ray *ray,
ShaderData *sd,
PathRadiance *L,
- ccl_addr_space float3 *throughput)
+ ccl_addr_space float3 *throughput,
+ const float object_step_size)
{
float3 tp = *throughput;
const float tp_eps = 1e-6f; /* todo: this is likely not the right value */
@@ -541,7 +555,7 @@ kernel_volume_integrate_heterogeneous_distance(KernelGlobals *kg,
/* prepare for stepping */
int max_steps = kernel_data.integrator.volume_max_steps;
float step_offset, step_size;
- kernel_volume_step_init(kg, state, ray->t, &step_size, &step_offset);
+ kernel_volume_step_init(kg, state, object_step_size, ray->t, &step_size, &step_offset);
/* compute coefficients at the start */
float t = 0.0f;
@@ -679,12 +693,13 @@ kernel_volume_integrate(KernelGlobals *kg,
Ray *ray,
PathRadiance *L,
ccl_addr_space float3 *throughput,
- bool heterogeneous)
+ float step_size)
{
shader_setup_from_volume(kg, sd, ray);
- if (heterogeneous)
- return kernel_volume_integrate_heterogeneous_distance(kg, state, ray, sd, L, throughput);
+ if (step_size != FLT_MAX)
+ return kernel_volume_integrate_heterogeneous_distance(
+ kg, state, ray, sd, L, throughput, step_size);
else
return kernel_volume_integrate_homogeneous(kg, state, ray, sd, L, throughput, true);
}
@@ -735,7 +750,7 @@ ccl_device void kernel_volume_decoupled_record(KernelGlobals *kg,
Ray *ray,
ShaderData *sd,
VolumeSegment *segment,
- bool heterogeneous)
+ const float object_step_size)
{
const float tp_eps = 1e-6f; /* todo: this is likely not the right value */
@@ -743,9 +758,9 @@ ccl_device void kernel_volume_decoupled_record(KernelGlobals *kg,
int max_steps;
float step_size, step_offset;
- if (heterogeneous) {
+ if (object_step_size != FLT_MAX) {
max_steps = kernel_data.integrator.volume_max_steps;
- kernel_volume_step_init(kg, state, ray->t, &step_size, &step_offset);
+ kernel_volume_step_init(kg, state, object_step_size, ray->t, &step_size, &step_offset);
# ifdef __KERNEL_CPU__
/* NOTE: For the branched path tracing it's possible to have direct
diff --git a/intern/cycles/kernel/split/kernel_do_volume.h b/intern/cycles/kernel/split/kernel_do_volume.h
index 45b839db05f..b24699ec39c 100644
--- a/intern/cycles/kernel/split/kernel_do_volume.h
+++ b/intern/cycles/kernel/split/kernel_do_volume.h
@@ -44,7 +44,7 @@ ccl_device_noinline bool kernel_split_branched_path_volume_indirect_light_iter(K
branched_state->isect.t :
FLT_MAX;
- bool heterogeneous = volume_stack_is_heterogeneous(kg, branched_state->path_state.volume_stack);
+ float step_size = volume_stack_step_size(kg, branched_state->path_state.volume_stack);
for (int j = branched_state->next_sample; j < num_samples; j++) {
ccl_global PathState *ps = &kernel_split_state.path_state[ray_index];
@@ -61,7 +61,7 @@ ccl_device_noinline bool kernel_split_branched_path_volume_indirect_light_iter(K
/* integrate along volume segment with distance sampling */
VolumeIntegrateResult result = kernel_volume_integrate(
- kg, ps, sd, &volume_ray, L, tp, heterogeneous);
+ kg, ps, sd, &volume_ray, L, tp, step_size);
# ifdef __VOLUME_SCATTER__
if (result == VOLUME_PATH_SCATTERED) {
@@ -164,12 +164,12 @@ ccl_device void kernel_do_volume(KernelGlobals *kg)
if (!kernel_data.integrator.branched ||
IS_FLAG(ray_state, ray_index, RAY_BRANCHED_INDIRECT)) {
# endif /* __BRANCHED_PATH__ */
- bool heterogeneous = volume_stack_is_heterogeneous(kg, state->volume_stack);
+ float step_size = volume_stack_step_size(kg, state->volume_stack);
{
/* integrate along volume segment with distance sampling */
VolumeIntegrateResult result = kernel_volume_integrate(
- kg, state, sd, &volume_ray, L, throughput, heterogeneous);
+ kg, state, sd, &volume_ray, L, throughput, step_size);
# ifdef __VOLUME_SCATTER__
if (result == VOLUME_PATH_SCATTERED) {