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:
-rw-r--r--intern/cycles/blender/addon/properties.py13
-rw-r--r--intern/cycles/blender/addon/ui.py8
-rw-r--r--intern/cycles/blender/blender_shader.cpp41
-rw-r--r--intern/cycles/integrator/path_trace_work_gpu.cpp2
-rw-r--r--intern/cycles/kernel/integrator/integrator_shade_surface.h31
-rw-r--r--intern/cycles/kernel/integrator/integrator_shadow_state_template.h5
-rw-r--r--intern/cycles/kernel/kernel_accumulate.h8
-rw-r--r--intern/cycles/kernel/kernel_shader.h11
-rw-r--r--intern/cycles/kernel/kernel_types.h8
-rw-r--r--intern/cycles/render/film.cpp4
-rw-r--r--intern/cycles/render/integrator.cpp13
-rw-r--r--intern/cycles/render/integrator.h3
-rw-r--r--intern/cycles/render/scene.cpp1
-rw-r--r--source/blender/makesrna/intern/rna_world.c1
14 files changed, 119 insertions, 30 deletions
diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py
index 2a51e0be2a4..0f92238015d 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -125,6 +125,11 @@ enum_texture_limit = (
('8192', "8192", "Limit texture size to 8192 pixels", 7),
)
+enum_fast_gi_method = (
+ ('REPLACE', "Replace", "Replace global illumination with ambient occlusion after a specified number of bounces"),
+ ('ADD', "Add", "Add ambient occlusion to diffuse surfaces"),
+)
+
# NOTE: Identifiers are expected to be an upper case version of identifiers from `Pass::get_type_enum()`
enum_view3d_shading_render_pass = (
('', "General", ""),
@@ -724,6 +729,14 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
description="Approximate diffuse indirect light with background tinted ambient occlusion. This provides fast alternative to full global illumination, for interactive viewport rendering or final renders with reduced quality",
default=False,
)
+
+ fast_gi_method: EnumProperty(
+ name="Fast GI Method",
+ default='REPLACE',
+ description="Fast GI approximation method",
+ items=enum_fast_gi_method
+ )
+
ao_bounces: IntProperty(
name="AO Bounces",
default=1,
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index 0ed2dd24f2e..facf1b08676 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -465,8 +465,7 @@ class CYCLES_RENDER_PT_light_paths_fast_gi(CyclesButtonsPanel, Panel):
layout.active = cscene.use_fast_gi
col = layout.column(align=True)
- col.prop(cscene, "ao_bounces", text="Viewport Bounces")
- col.prop(cscene, "ao_bounces_render", text="Render Bounces")
+ col.prop(cscene, "fast_gi_method", text="Method")
if world:
light = world.light_settings
@@ -474,6 +473,11 @@ class CYCLES_RENDER_PT_light_paths_fast_gi(CyclesButtonsPanel, Panel):
col.prop(light, "ao_factor", text="AO Factor")
col.prop(light, "distance", text="AO Distance")
+ if cscene.fast_gi_method == 'REPLACE':
+ col = layout.column(align=True)
+ col.prop(cscene, "ao_bounces", text="Viewport Bounces")
+ col.prop(cscene, "ao_bounces_render", text="Render Bounces")
+
class CYCLES_RENDER_PT_motion_blur(CyclesButtonsPanel, Panel):
bl_label = "Motion Blur"
diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp
index db5eadeed56..25e7ec71577 100644
--- a/intern/cycles/blender/blender_shader.cpp
+++ b/intern/cycles/blender/blender_shader.cpp
@@ -1375,6 +1375,7 @@ void BlenderSync::sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d,
{
Background *background = scene->background;
Integrator *integrator = scene->integrator;
+ PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
BL::World b_world = b_scene.world();
@@ -1466,14 +1467,8 @@ void BlenderSync::sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d,
graph->connect(background->output("Background"), out->input("Surface"));
}
+ /* Visibility */
if (b_world) {
- /* AO */
- BL::WorldLighting b_light = b_world.light_settings();
-
- integrator->set_ao_factor(b_light.ao_factor());
- integrator->set_ao_distance(b_light.distance());
-
- /* visibility */
PointerRNA cvisibility = RNA_pointer_get(&b_world.ptr, "cycles_visibility");
uint visibility = 0;
@@ -1485,16 +1480,38 @@ void BlenderSync::sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d,
background->set_visibility(visibility);
}
- else {
- integrator->set_ao_factor(1.0f);
- integrator->set_ao_distance(10.0f);
- }
shader->set_graph(graph);
shader->tag_update(scene);
}
- PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
+ /* Fast GI */
+ if (b_world) {
+ BL::WorldLighting b_light = b_world.light_settings();
+ enum { FAST_GI_METHOD_REPLACE = 0, FAST_GI_METHOD_ADD = 1, FAST_GI_METHOD_NUM };
+
+ const bool use_fast_gi = get_boolean(cscene, "use_fast_gi");
+ if (use_fast_gi) {
+ const int fast_gi_method = get_enum(
+ cscene, "fast_gi_method", FAST_GI_METHOD_NUM, FAST_GI_METHOD_REPLACE);
+ integrator->set_ao_factor((fast_gi_method == FAST_GI_METHOD_REPLACE) ? b_light.ao_factor() :
+ 0.0f);
+ integrator->set_ao_additive_factor(
+ (fast_gi_method == FAST_GI_METHOD_ADD) ? b_light.ao_factor() : 0.0f);
+ }
+ else {
+ integrator->set_ao_factor(0.0f);
+ integrator->set_ao_additive_factor(0.0f);
+ }
+
+ integrator->set_ao_distance(b_light.distance());
+ }
+ else {
+ integrator->set_ao_factor(0.0f);
+ integrator->set_ao_additive_factor(0.0f);
+ integrator->set_ao_distance(10.0f);
+ }
+
background->set_transparent(b_scene.render().film_transparent());
if (background->get_transparent()) {
diff --git a/intern/cycles/integrator/path_trace_work_gpu.cpp b/intern/cycles/integrator/path_trace_work_gpu.cpp
index 36f275e1075..605c1efca0f 100644
--- a/intern/cycles/integrator/path_trace_work_gpu.cpp
+++ b/intern/cycles/integrator/path_trace_work_gpu.cpp
@@ -1082,7 +1082,7 @@ bool PathTraceWorkGPU::kernel_creates_shadow_paths(DeviceKernel kernel)
bool PathTraceWorkGPU::kernel_creates_ao_paths(DeviceKernel kernel)
{
- return (device_scene_->data.film.pass_ao != PASS_UNUSED) &&
+ return (device_scene_->data.kernel_features & KERNEL_FEATURE_AO) &&
(kernel == DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE ||
kernel == DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE_RAYTRACE);
}
diff --git a/intern/cycles/kernel/integrator/integrator_shade_surface.h b/intern/cycles/kernel/integrator/integrator_shade_surface.h
index 3724b05c6b0..2a0bf4a3046 100644
--- a/intern/cycles/kernel/integrator/integrator_shade_surface.h
+++ b/intern/cycles/kernel/integrator/integrator_shade_surface.h
@@ -325,17 +325,25 @@ ccl_device_forceinline bool integrate_surface_volume_only_bounce(IntegratorState
#endif
#if defined(__AO__)
-ccl_device_forceinline void integrate_surface_ao_pass(
- KernelGlobals kg,
- IntegratorState state,
- ccl_private const ShaderData *ccl_restrict sd,
- ccl_private const RNGState *ccl_restrict rng_state,
- ccl_global float *ccl_restrict render_buffer)
+ccl_device_forceinline void integrate_surface_ao(KernelGlobals kg,
+ IntegratorState state,
+ ccl_private const ShaderData *ccl_restrict sd,
+ ccl_private const RNGState *ccl_restrict
+ rng_state,
+ ccl_global float *ccl_restrict render_buffer)
{
+ if (!(kernel_data.kernel_features & KERNEL_FEATURE_AO_ADDITIVE) &&
+ !(INTEGRATOR_STATE(state, path, flag) & PATH_RAY_CAMERA)) {
+ return;
+ }
+
float bsdf_u, bsdf_v;
path_state_rng_2D(kg, rng_state, PRNG_BSDF_U, &bsdf_u, &bsdf_v);
- const float3 ao_N = shader_bsdf_ao_normal(kg, sd);
+ float3 ao_N;
+ const float3 ao_weight = shader_bsdf_ao(
+ kg, sd, kernel_data.integrator.ao_additive_factor, &ao_N);
+
float3 ao_D;
float ao_pdf;
sample_cos_hemisphere(ao_N, bsdf_u, bsdf_v, &ao_D, &ao_pdf);
@@ -379,6 +387,10 @@ ccl_device_forceinline void integrate_surface_ao_pass(
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, bounce) = bounce;
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, transparent_bounce) = transparent_bounce;
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, throughput) = throughput;
+
+ if (kernel_data.kernel_features & KERNEL_FEATURE_AO_ADDITIVE) {
+ INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, unshadowed_throughput) = ao_weight;
+ }
}
#endif /* defined(__AO__) */
@@ -487,10 +499,9 @@ ccl_device bool integrate_surface(KernelGlobals kg,
#if defined(__AO__)
/* Ambient occlusion pass. */
- if ((kernel_data.film.pass_ao != PASS_UNUSED) &&
- (INTEGRATOR_STATE(state, path, flag) & PATH_RAY_CAMERA)) {
+ if (kernel_data.kernel_features & KERNEL_FEATURE_AO) {
PROFILING_EVENT(PROFILING_SHADE_SURFACE_AO);
- integrate_surface_ao_pass(kg, state, &sd, &rng_state, render_buffer);
+ integrate_surface_ao(kg, state, &sd, &rng_state, render_buffer);
}
#endif
diff --git a/intern/cycles/kernel/integrator/integrator_shadow_state_template.h b/intern/cycles/kernel/integrator/integrator_shadow_state_template.h
index bc35b644ee1..1fbadde2642 100644
--- a/intern/cycles/kernel/integrator/integrator_shadow_state_template.h
+++ b/intern/cycles/kernel/integrator/integrator_shadow_state_template.h
@@ -42,7 +42,10 @@ KERNEL_STRUCT_MEMBER(shadow_path, uint32_t, flag, KERNEL_FEATURE_PATH_TRACING)
/* Throughput. */
KERNEL_STRUCT_MEMBER(shadow_path, float3, throughput, KERNEL_FEATURE_PATH_TRACING)
/* Throughput for shadow pass. */
-KERNEL_STRUCT_MEMBER(shadow_path, float3, unshadowed_throughput, KERNEL_FEATURE_SHADOW_PASS)
+KERNEL_STRUCT_MEMBER(shadow_path,
+ float3,
+ unshadowed_throughput,
+ KERNEL_FEATURE_SHADOW_PASS | KERNEL_FEATURE_AO_ADDITIVE)
/* Ratio of throughput to distinguish diffuse and glossy render passes. */
KERNEL_STRUCT_MEMBER(shadow_path, float3, diffuse_glossy_ratio, KERNEL_FEATURE_LIGHT_PASSES)
/* Number of intersections found by ray-tracing. */
diff --git a/intern/cycles/kernel/kernel_accumulate.h b/intern/cycles/kernel/kernel_accumulate.h
index 54492bef974..c494cb4e189 100644
--- a/intern/cycles/kernel/kernel_accumulate.h
+++ b/intern/cycles/kernel/kernel_accumulate.h
@@ -410,7 +410,13 @@ ccl_device_inline void kernel_accum_light(KernelGlobals kg,
/* Ambient occlusion. */
if (path_flag & PATH_RAY_SHADOW_FOR_AO) {
- kernel_write_pass_float3(buffer + kernel_data.film.pass_ao, contribution);
+ if ((kernel_data.kernel_features & KERNEL_FEATURE_AO_PASS) && (path_flag & PATH_RAY_CAMERA)) {
+ kernel_write_pass_float3(buffer + kernel_data.film.pass_ao, contribution);
+ }
+ if (kernel_data.kernel_features & KERNEL_FEATURE_AO_ADDITIVE) {
+ const float3 ao_weight = INTEGRATOR_STATE(state, shadow_path, unshadowed_throughput);
+ kernel_accum_combined_pass(kg, path_flag, sample, contribution * ao_weight, buffer);
+ }
return;
}
diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h
index d25191b72cf..22db6d0124e 100644
--- a/intern/cycles/kernel/kernel_shader.h
+++ b/intern/cycles/kernel/kernel_shader.h
@@ -457,19 +457,26 @@ ccl_device float3 shader_bsdf_average_normal(KernelGlobals kg, ccl_private const
return (is_zero(N)) ? sd->N : normalize(N);
}
-ccl_device float3 shader_bsdf_ao_normal(KernelGlobals kg, ccl_private const ShaderData *sd)
+ccl_device float3 shader_bsdf_ao(KernelGlobals kg,
+ ccl_private const ShaderData *sd,
+ const float ao_factor,
+ ccl_private float3 *N_)
{
+ float3 eval = zero_float3();
float3 N = zero_float3();
for (int i = 0; i < sd->num_closure; i++) {
ccl_private const ShaderClosure *sc = &sd->closure[i];
+
if (CLOSURE_IS_BSDF_DIFFUSE(sc->type)) {
ccl_private const DiffuseBsdf *bsdf = (ccl_private const DiffuseBsdf *)sc;
+ eval += sc->weight * ao_factor;
N += bsdf->N * fabsf(average(sc->weight));
}
}
- return (is_zero(N)) ? sd->N : normalize(N);
+ *N_ = (is_zero(N)) ? sd->N : normalize(N);
+ return eval;
}
#ifdef __SUBSURFACE__
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index df6b6b5be20..94c27a1fca5 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -1147,6 +1147,7 @@ typedef struct KernelIntegrator {
int ao_bounces;
float ao_bounces_distance;
float ao_bounces_factor;
+ float ao_additive_factor;
/* transparent */
int transparent_min_bounce;
@@ -1179,7 +1180,7 @@ typedef struct KernelIntegrator {
int has_shadow_catcher;
/* padding */
- int pad1, pad2;
+ int pad1;
} KernelIntegrator;
static_assert_align(KernelIntegrator, 16);
@@ -1561,6 +1562,11 @@ enum KernelFeatureFlag : unsigned int {
/* Shadow render pass. */
KERNEL_FEATURE_SHADOW_PASS = (1U << 24U),
+
+ /* AO. */
+ KERNEL_FEATURE_AO_PASS = (1U << 25U),
+ KERNEL_FEATURE_AO_ADDITIVE = (1U << 26U),
+ KERNEL_FEATURE_AO = (KERNEL_FEATURE_AO_PASS | KERNEL_FEATURE_AO_ADDITIVE),
};
/* Shader node feature mask, to specialize shader evaluation for kernels. */
diff --git a/intern/cycles/render/film.cpp b/intern/cycles/render/film.cpp
index 1f7882ea91e..bd18c777eb5 100644
--- a/intern/cycles/render/film.cpp
+++ b/intern/cycles/render/film.cpp
@@ -680,6 +680,10 @@ uint Film::get_kernel_features(const Scene *scene) const
kernel_features |= KERNEL_FEATURE_SHADOW_PASS;
}
}
+
+ if (pass_type == PASS_AO) {
+ kernel_features |= KERNEL_FEATURE_AO_PASS;
+ }
}
return kernel_features;
diff --git a/intern/cycles/render/integrator.cpp b/intern/cycles/render/integrator.cpp
index d74d14242bb..16d9fc60fd3 100644
--- a/intern/cycles/render/integrator.cpp
+++ b/intern/cycles/render/integrator.cpp
@@ -55,6 +55,7 @@ NODE_DEFINE(Integrator)
SOCKET_INT(ao_bounces, "AO Bounces", 0);
SOCKET_FLOAT(ao_factor, "AO Factor", 0.0f);
SOCKET_FLOAT(ao_distance, "AO Distance", FLT_MAX);
+ SOCKET_FLOAT(ao_additive_factor, "AO Additive Factor", 0.0f);
SOCKET_INT(volume_max_steps, "Volume Max Steps", 1024);
SOCKET_FLOAT(volume_step_rate, "Volume Step Rate", 1.0f);
@@ -159,6 +160,7 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene
kintegrator->ao_bounces = ao_bounces;
kintegrator->ao_bounces_distance = ao_distance;
kintegrator->ao_bounces_factor = ao_factor;
+ kintegrator->ao_additive_factor = ao_additive_factor;
/* Transparent Shadows
* We only need to enable transparent shadows, if we actually have
@@ -268,6 +270,17 @@ void Integrator::tag_update(Scene *scene, uint32_t flag)
}
}
+uint Integrator::get_kernel_features(const Scene *scene) const
+{
+ uint kernel_features = 0;
+
+ if (ao_additive_factor != 0.0f) {
+ kernel_features |= KERNEL_FEATURE_AO_ADDITIVE;
+ }
+
+ return kernel_features;
+}
+
AdaptiveSampling Integrator::get_adaptive_sampling() const
{
AdaptiveSampling adaptive_sampling;
diff --git a/intern/cycles/render/integrator.h b/intern/cycles/render/integrator.h
index 5ad419e02ca..91efc25e51e 100644
--- a/intern/cycles/render/integrator.h
+++ b/intern/cycles/render/integrator.h
@@ -47,6 +47,7 @@ class Integrator : public Node {
NODE_SOCKET_API(int, ao_bounces)
NODE_SOCKET_API(float, ao_factor)
NODE_SOCKET_API(float, ao_distance)
+ NODE_SOCKET_API(float, ao_additive_factor)
NODE_SOCKET_API(int, volume_max_steps)
NODE_SOCKET_API(float, volume_step_rate)
@@ -101,6 +102,8 @@ class Integrator : public Node {
void tag_update(Scene *scene, uint32_t flag);
+ uint get_kernel_features(const Scene *scene) const;
+
AdaptiveSampling get_adaptive_sampling() const;
DenoiseParams get_denoise_params() const;
};
diff --git a/intern/cycles/render/scene.cpp b/intern/cycles/render/scene.cpp
index 7c5e1a86f5e..669f5abf7d6 100644
--- a/intern/cycles/render/scene.cpp
+++ b/intern/cycles/render/scene.cpp
@@ -522,6 +522,7 @@ void Scene::update_kernel_features()
}
kernel_features |= film->get_kernel_features(this);
+ kernel_features |= integrator->get_kernel_features(this);
dscene.data.kernel_features = kernel_features;
diff --git a/source/blender/makesrna/intern/rna_world.c b/source/blender/makesrna/intern/rna_world.c
index 826e6d21c36..68f11d71de2 100644
--- a/source/blender/makesrna/intern/rna_world.c
+++ b/source/blender/makesrna/intern/rna_world.c
@@ -128,6 +128,7 @@ static void rna_def_lighting(BlenderRNA *brna)
prop = RNA_def_property(srna, "distance", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "aodist");
+ RNA_def_property_range(prop, 0, FLT_MAX);
RNA_def_property_ui_text(
prop, "Distance", "Length of rays, defines how far away other faces give occlusion effect");
RNA_def_property_update(prop, 0, "rna_World_update");