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:
authorTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>2018-02-08 21:00:20 +0300
committerTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>2018-02-08 21:00:20 +0300
commit3b61d2bb68d96c15e9d00fecea17e0794f613a78 (patch)
treee6c3af4361a8825b4219a1965c1dc2f327a1b4b9
parent74fa84f37f718939474334abe975797462ec8e29 (diff)
parent859379ac487509f3eed96de5c78f934fbd3490d2 (diff)
Merge branch 'master' into blender2.8
Conflicts: intern/cycles/blender/addon/ui.py
-rw-r--r--intern/cycles/blender/addon/ui.py6
-rw-r--r--intern/cycles/kernel/kernel_path.h1
-rw-r--r--intern/cycles/kernel/kernel_path_branched.h25
-rw-r--r--intern/cycles/kernel/kernel_path_state.h2
-rw-r--r--intern/cycles/kernel/kernel_path_subsurface.h4
-rw-r--r--intern/cycles/kernel/kernel_subsurface.h13
-rw-r--r--intern/cycles/kernel/osl/osl_bssrdf.cpp133
-rw-r--r--intern/cycles/kernel/osl/osl_closures.cpp10
-rw-r--r--intern/cycles/kernel/osl/osl_closures.h10
-rw-r--r--intern/cycles/kernel/shaders/node_principled_bsdf.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_subsurface_scattering.osl6
-rw-r--r--intern/cycles/kernel/shaders/stdosl.h5
-rw-r--r--intern/cycles/kernel/split/kernel_split_data_types.h4
-rw-r--r--intern/cycles/kernel/split/kernel_subsurface_scatter.h42
-rw-r--r--source/blender/bmesh/tools/bmesh_bevel.c99
-rw-r--r--tests/python/CMakeLists.txt1
16 files changed, 177 insertions, 186 deletions
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index 13bb0094982..d5f72654c72 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -442,8 +442,10 @@ class CYCLES_RENDER_PT_layer_options(CyclesButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
+ with_freestyle = bpy.app.build_options.freestyle
scene = context.scene
+ rd = scene.render
view_layer = scene.view_layers.active
col = layout.column()
@@ -451,6 +453,10 @@ class CYCLES_RENDER_PT_layer_options(CyclesButtonsPanel, Panel):
col.prop(view_layer, "use_ao", "Use AO")
col.prop(view_layer, "use_solid", "Use Surfaces")
col.prop(view_layer, "use_strand", "Use Hair")
+ if with_freestyle:
+ row = col.row()
+ row.prop(view_layer, "use_freestyle", "Use Freestyle")
+ row.active = rd.use_freestyle
class CYCLES_RENDER_PT_layer_passes(CyclesButtonsPanel, Panel):
diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h
index 1e98bca66ad..afca4575331 100644
--- a/intern/cycles/kernel/kernel_path.h
+++ b/intern/cycles/kernel/kernel_path.h
@@ -504,7 +504,6 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
subsurface_scatter_step(kg,
sd,
state,
- state->flag,
sc,
&lcg_state,
bssrdf_u, bssrdf_v,
diff --git a/intern/cycles/kernel/kernel_path_branched.h b/intern/cycles/kernel/kernel_path_branched.h
index fe2a7d179a4..5f917d509ec 100644
--- a/intern/cycles/kernel/kernel_path_branched.h
+++ b/intern/cycles/kernel/kernel_path_branched.h
@@ -340,9 +340,13 @@ ccl_device void kernel_branched_path_subsurface_scatter(KernelGlobals *kg,
/* do subsurface scatter step with copy of shader data, this will
* replace the BSSRDF with a diffuse BSDF closure */
for(int j = 0; j < num_samples; j++) {
+ PathState hit_state = *state;
+ path_state_branch(&hit_state, j, num_samples);
+ hit_state.rng_hash = bssrdf_rng_hash;
+
LocalIntersection ss_isect;
float bssrdf_u, bssrdf_v;
- path_branched_rng_2D(kg, bssrdf_rng_hash, state, j, num_samples, PRNG_BSDF_U, &bssrdf_u, &bssrdf_v);
+ path_state_rng_2D(kg, &hit_state, PRNG_BSDF_U, &bssrdf_u, &bssrdf_v);
int num_hits = subsurface_scatter_multi_intersect(kg,
&ss_isect,
sd,
@@ -350,6 +354,9 @@ ccl_device void kernel_branched_path_subsurface_scatter(KernelGlobals *kg,
&lcg_state,
bssrdf_u, bssrdf_v,
true);
+
+ hit_state.rng_offset += PRNG_BOUNCE_NUM;
+
#ifdef __VOLUME__
Ray volume_ray = *ray;
bool need_update_volume_stack =
@@ -364,14 +371,8 @@ ccl_device void kernel_branched_path_subsurface_scatter(KernelGlobals *kg,
&ss_isect,
hit,
&bssrdf_sd,
- state,
- state->flag,
- sc,
- true);
-
- PathState hit_state = *state;
-
- path_state_branch(&hit_state, j, num_samples);
+ &hit_state,
+ sc);
#ifdef __VOLUME__
if(need_update_volume_stack) {
@@ -380,6 +381,10 @@ ccl_device void kernel_branched_path_subsurface_scatter(KernelGlobals *kg,
volume_ray.D = normalize_len(P - volume_ray.P,
&volume_ray.t);
+ for(int k = 0; k < VOLUME_STACK_SIZE; k++) {
+ hit_state.volume_stack[k] = state->volume_stack[k];
+ }
+
kernel_volume_stack_update_for_subsurface(
kg,
emission_sd,
@@ -392,7 +397,7 @@ ccl_device void kernel_branched_path_subsurface_scatter(KernelGlobals *kg,
/* direct light */
if(kernel_data.integrator.use_direct_light) {
int all = (kernel_data.integrator.sample_all_lights_direct) ||
- (state->flag & PATH_RAY_SHADOW_CATCHER);
+ (hit_state.flag & PATH_RAY_SHADOW_CATCHER);
kernel_branched_path_surface_connect_light(
kg,
&bssrdf_sd,
diff --git a/intern/cycles/kernel/kernel_path_state.h b/intern/cycles/kernel/kernel_path_state.h
index 2ae866bb051..a16c20cbee6 100644
--- a/intern/cycles/kernel/kernel_path_state.h
+++ b/intern/cycles/kernel/kernel_path_state.h
@@ -231,8 +231,6 @@ ccl_device_inline void path_state_branch(ccl_addr_space PathState *state,
int branch,
int num_branches)
{
- state->rng_offset += PRNG_BOUNCE_NUM;
-
if(num_branches > 1) {
/* Path is splitting into a branch, adjust so that each branch
* still gets a unique sample from the same sequence. */
diff --git a/intern/cycles/kernel/kernel_path_subsurface.h b/intern/cycles/kernel/kernel_path_subsurface.h
index c29b41e4222..a48bde6443e 100644
--- a/intern/cycles/kernel/kernel_path_subsurface.h
+++ b/intern/cycles/kernel/kernel_path_subsurface.h
@@ -71,9 +71,7 @@ bool kernel_path_subsurface_scatter(
hit,
sd,
state,
- state->flag,
- sc,
- false);
+ sc);
kernel_path_surface_connect_light(kg, sd, emission_sd, *throughput, state, L);
diff --git a/intern/cycles/kernel/kernel_subsurface.h b/intern/cycles/kernel/kernel_subsurface.h
index 582a20704d3..f4759b26191 100644
--- a/intern/cycles/kernel/kernel_subsurface.h
+++ b/intern/cycles/kernel/kernel_subsurface.h
@@ -135,7 +135,6 @@ ccl_device float3 subsurface_color_pow(float3 color, float exponent)
ccl_device void subsurface_color_bump_blur(KernelGlobals *kg,
ShaderData *sd,
ccl_addr_space PathState *state,
- int state_flag,
float3 *eval,
float3 *N)
{
@@ -148,7 +147,7 @@ ccl_device void subsurface_color_bump_blur(KernelGlobals *kg,
if(bump || texture_blur > 0.0f) {
/* average color and normal at incoming point */
- shader_eval_surface(kg, sd, state, state_flag, kernel_data.integrator.max_closures);
+ shader_eval_surface(kg, sd, state, state->flag, kernel_data.integrator.max_closures);
float3 in_color = shader_bssrdf_sum(sd, (bump)? N: NULL, NULL);
/* we simply divide out the average color and multiply with the average
@@ -311,9 +310,7 @@ ccl_device_noinline void subsurface_scatter_multi_setup(
int hit,
ShaderData *sd,
ccl_addr_space PathState *state,
- int state_flag,
- const ShaderClosure *sc,
- bool all)
+ const ShaderClosure *sc)
{
#ifdef __SPLIT_KERNEL__
Ray ray_object = ss_isect->ray;
@@ -333,7 +330,7 @@ ccl_device_noinline void subsurface_scatter_multi_setup(
/* Optionally blur colors and bump mapping. */
float3 weight = ss_isect->weight[hit];
float3 N = sd->N;
- subsurface_color_bump_blur(kg, sd, state, state_flag, &weight, &N);
+ subsurface_color_bump_blur(kg, sd, state, &weight, &N);
/* Setup diffuse BSDF. */
subsurface_scatter_setup_diffuse_bsdf(kg, sd, sc, weight, true, N);
@@ -341,7 +338,7 @@ ccl_device_noinline void subsurface_scatter_multi_setup(
/* subsurface scattering step, from a point on the surface to another nearby point on the same object */
ccl_device void subsurface_scatter_step(KernelGlobals *kg, ShaderData *sd, ccl_addr_space PathState *state,
- int state_flag, const ShaderClosure *sc, uint *lcg_state, float disk_u, float disk_v, bool all)
+ const ShaderClosure *sc, uint *lcg_state, float disk_u, float disk_v, bool all)
{
float3 eval = make_float3(0.0f, 0.0f, 0.0f);
@@ -430,7 +427,7 @@ ccl_device void subsurface_scatter_step(KernelGlobals *kg, ShaderData *sd, ccl_a
/* optionally blur colors and bump mapping */
float3 N = sd->N;
- subsurface_color_bump_blur(kg, sd, state, state_flag, &eval, &N);
+ subsurface_color_bump_blur(kg, sd, state, &eval, &N);
/* setup diffuse bsdf */
subsurface_scatter_setup_diffuse_bsdf(kg, sd, sc, eval, (ss_isect.num_hits > 0), N);
diff --git a/intern/cycles/kernel/osl/osl_bssrdf.cpp b/intern/cycles/kernel/osl/osl_bssrdf.cpp
index 3e7905f26df..db6426f60e5 100644
--- a/intern/cycles/kernel/osl/osl_bssrdf.cpp
+++ b/intern/cycles/kernel/osl/osl_bssrdf.cpp
@@ -48,9 +48,38 @@ CCL_NAMESPACE_BEGIN
using namespace OSL;
+static ustring u_cubic("cubic");
+static ustring u_gaussian("gaussian");
+static ustring u_burley("burley");
+static ustring u_principled("principled");
+
class CBSSRDFClosure : public CClosurePrimitive {
public:
Bssrdf params;
+ ustring method;
+
+ CBSSRDFClosure()
+ {
+ params.texture_blur = 0.0f;
+ params.sharpness = 0.0f;
+ params.roughness = 0.0f;
+ }
+
+ void setup(ShaderData *sd, int path_flag, float3 weight)
+ {
+ if (method == u_cubic) {
+ alloc(sd, path_flag, weight, CLOSURE_BSSRDF_CUBIC_ID);
+ }
+ else if (method == u_gaussian) {
+ alloc(sd, path_flag, weight, CLOSURE_BSSRDF_GAUSSIAN_ID);
+ }
+ else if (method == u_burley) {
+ alloc(sd, path_flag, weight, CLOSURE_BSSRDF_BURLEY_ID);
+ }
+ else if (method == u_principled) {
+ alloc(sd, path_flag, weight, CLOSURE_BSSRDF_PRINCIPLED_ID);
+ }
+ }
void alloc(ShaderData *sd, int path_flag, float3 weight, ClosureType type)
{
@@ -76,105 +105,23 @@ public:
}
};
-/* Cubic */
-
-class CubicBSSRDFClosure : public CBSSRDFClosure {
-public:
- void setup(ShaderData *sd, int path_flag, float3 weight)
- {
- alloc(sd, path_flag, weight, CLOSURE_BSSRDF_CUBIC_ID);
- }
-};
-
-ClosureParam *closure_bssrdf_cubic_params()
-{
- static ClosureParam params[] = {
- CLOSURE_FLOAT3_PARAM(CubicBSSRDFClosure, params.N),
- CLOSURE_FLOAT3_PARAM(CubicBSSRDFClosure, params.radius),
- CLOSURE_FLOAT_PARAM(CubicBSSRDFClosure, params.texture_blur),
- CLOSURE_FLOAT_PARAM(CubicBSSRDFClosure, params.sharpness),
- CLOSURE_STRING_KEYPARAM(CubicBSSRDFClosure, label, "label"),
- CLOSURE_FINISH_PARAM(CubicBSSRDFClosure)
- };
- return params;
-}
-
-CCLOSURE_PREPARE(closure_bssrdf_cubic_prepare, CubicBSSRDFClosure)
-
-/* Gaussian */
-
-class GaussianBSSRDFClosure : public CBSSRDFClosure {
-public:
- void setup(ShaderData *sd, int path_flag, float3 weight)
- {
- alloc(sd, path_flag, weight, CLOSURE_BSSRDF_GAUSSIAN_ID);
- }
-};
-
-ClosureParam *closure_bssrdf_gaussian_params()
-{
- static ClosureParam params[] = {
- CLOSURE_FLOAT3_PARAM(GaussianBSSRDFClosure, params.N),
- CLOSURE_FLOAT3_PARAM(GaussianBSSRDFClosure, params.radius),
- CLOSURE_FLOAT_PARAM(GaussianBSSRDFClosure, params.texture_blur),
- CLOSURE_STRING_KEYPARAM(GaussianBSSRDFClosure, label, "label"),
- CLOSURE_FINISH_PARAM(GaussianBSSRDFClosure)
- };
- return params;
-}
-
-CCLOSURE_PREPARE(closure_bssrdf_gaussian_prepare, GaussianBSSRDFClosure)
-
-/* Burley */
-
-class BurleyBSSRDFClosure : public CBSSRDFClosure {
-public:
- void setup(ShaderData *sd, int path_flag, float3 weight)
- {
- alloc(sd, path_flag, weight, CLOSURE_BSSRDF_BURLEY_ID);
- }
-};
-
-ClosureParam *closure_bssrdf_burley_params()
-{
- static ClosureParam params[] = {
- CLOSURE_FLOAT3_PARAM(BurleyBSSRDFClosure, params.N),
- CLOSURE_FLOAT3_PARAM(BurleyBSSRDFClosure, params.radius),
- CLOSURE_FLOAT_PARAM(BurleyBSSRDFClosure, params.texture_blur),
- CLOSURE_FLOAT3_PARAM(BurleyBSSRDFClosure, params.albedo),
- CLOSURE_STRING_KEYPARAM(BurleyBSSRDFClosure, label, "label"),
- CLOSURE_FINISH_PARAM(BurleyBSSRDFClosure)
- };
- return params;
-}
-
-CCLOSURE_PREPARE(closure_bssrdf_burley_prepare, BurleyBSSRDFClosure)
-
-/* Disney principled */
-
-class PrincipledBSSRDFClosure : public CBSSRDFClosure {
-public:
- void setup(ShaderData *sd, int path_flag, float3 weight)
- {
- alloc(sd, path_flag, weight, CLOSURE_BSSRDF_PRINCIPLED_ID);
- }
-};
-
-ClosureParam *closure_bssrdf_principled_params()
+ClosureParam *closure_bssrdf_params()
{
static ClosureParam params[] = {
- CLOSURE_FLOAT3_PARAM(PrincipledBSSRDFClosure, params.N),
- CLOSURE_FLOAT3_PARAM(PrincipledBSSRDFClosure, params.radius),
- CLOSURE_FLOAT_PARAM(PrincipledBSSRDFClosure, params.texture_blur),
- CLOSURE_FLOAT3_PARAM(PrincipledBSSRDFClosure, params.albedo),
- CLOSURE_FLOAT_PARAM(PrincipledBSSRDFClosure, params.roughness),
- CLOSURE_STRING_KEYPARAM(PrincipledBSSRDFClosure, label, "label"),
- CLOSURE_FINISH_PARAM(PrincipledBSSRDFClosure)
+ CLOSURE_STRING_PARAM(CBSSRDFClosure, method),
+ CLOSURE_FLOAT3_PARAM(CBSSRDFClosure, params.N),
+ CLOSURE_FLOAT3_PARAM(CBSSRDFClosure, params.radius),
+ CLOSURE_FLOAT3_PARAM(CBSSRDFClosure, params.albedo),
+ CLOSURE_FLOAT_KEYPARAM(CBSSRDFClosure, params.texture_blur, "texture_blur"),
+ CLOSURE_FLOAT_KEYPARAM(CBSSRDFClosure, params.sharpness, "sharpness"),
+ CLOSURE_FLOAT_KEYPARAM(CBSSRDFClosure, params.roughness, "roughness"),
+ CLOSURE_STRING_KEYPARAM(CBSSRDFClosure, label, "label"),
+ CLOSURE_FINISH_PARAM(CBSSRDFClosure)
};
return params;
}
-CCLOSURE_PREPARE(closure_bssrdf_principled_prepare, PrincipledBSSRDFClosure)
+CCLOSURE_PREPARE(closure_bssrdf_prepare, CBSSRDFClosure)
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/osl/osl_closures.cpp b/intern/cycles/kernel/osl/osl_closures.cpp
index 8acab1ab558..d0c357580fd 100644
--- a/intern/cycles/kernel/osl/osl_closures.cpp
+++ b/intern/cycles/kernel/osl/osl_closures.cpp
@@ -316,14 +316,8 @@ void OSLShader::register_closures(OSLShadingSystem *ss_)
closure_bsdf_diffuse_ramp_params(), closure_bsdf_diffuse_ramp_prepare);
register_closure(ss, "phong_ramp", id++,
closure_bsdf_phong_ramp_params(), closure_bsdf_phong_ramp_prepare);
- register_closure(ss, "bssrdf_cubic", id++,
- closure_bssrdf_cubic_params(), closure_bssrdf_cubic_prepare);
- register_closure(ss, "bssrdf_gaussian", id++,
- closure_bssrdf_gaussian_params(), closure_bssrdf_gaussian_prepare);
- register_closure(ss, "bssrdf_burley", id++,
- closure_bssrdf_burley_params(), closure_bssrdf_burley_prepare);
- register_closure(ss, "bssrdf_principled", id++,
- closure_bssrdf_principled_params(), closure_bssrdf_principled_prepare);
+ register_closure(ss, "bssrdf", id++,
+ closure_bssrdf_params(), closure_bssrdf_prepare);
register_closure(ss, "hair_reflection", id++,
bsdf_hair_reflection_params(), bsdf_hair_reflection_prepare);
diff --git a/intern/cycles/kernel/osl/osl_closures.h b/intern/cycles/kernel/osl/osl_closures.h
index 38943b77656..dca7e74f154 100644
--- a/intern/cycles/kernel/osl/osl_closures.h
+++ b/intern/cycles/kernel/osl/osl_closures.h
@@ -49,10 +49,7 @@ OSL::ClosureParam *closure_ambient_occlusion_params();
OSL::ClosureParam *closure_bsdf_diffuse_ramp_params();
OSL::ClosureParam *closure_bsdf_phong_ramp_params();
OSL::ClosureParam *closure_bsdf_transparent_params();
-OSL::ClosureParam *closure_bssrdf_cubic_params();
-OSL::ClosureParam *closure_bssrdf_gaussian_params();
-OSL::ClosureParam *closure_bssrdf_burley_params();
-OSL::ClosureParam *closure_bssrdf_principled_params();
+OSL::ClosureParam *closure_bssrdf_params();
OSL::ClosureParam *closure_absorption_params();
OSL::ClosureParam *closure_henyey_greenstein_params();
OSL::ClosureParam *closure_bsdf_microfacet_multi_ggx_params();
@@ -72,10 +69,7 @@ void closure_ambient_occlusion_prepare(OSL::RendererServices *, int id, void *da
void closure_bsdf_diffuse_ramp_prepare(OSL::RendererServices *, int id, void *data);
void closure_bsdf_phong_ramp_prepare(OSL::RendererServices *, int id, void *data);
void closure_bsdf_transparent_prepare(OSL::RendererServices *, int id, void *data);
-void closure_bssrdf_cubic_prepare(OSL::RendererServices *, int id, void *data);
-void closure_bssrdf_gaussian_prepare(OSL::RendererServices *, int id, void *data);
-void closure_bssrdf_burley_prepare(OSL::RendererServices *, int id, void *data);
-void closure_bssrdf_principled_prepare(OSL::RendererServices *, int id, void *data);
+void closure_bssrdf_prepare(OSL::RendererServices *, int id, void *data);
void closure_absorption_prepare(OSL::RendererServices *, int id, void *data);
void closure_henyey_greenstein_prepare(OSL::RendererServices *, int id, void *data);
void closure_bsdf_microfacet_multi_ggx_prepare(OSL::RendererServices *, int id, void *data);
diff --git a/intern/cycles/kernel/shaders/node_principled_bsdf.osl b/intern/cycles/kernel/shaders/node_principled_bsdf.osl
index 6870d479af3..0e31dcedee4 100644
--- a/intern/cycles/kernel/shaders/node_principled_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_principled_bsdf.osl
@@ -58,7 +58,7 @@ shader node_principled_bsdf(
if (diffuse_weight > 1e-5) {
if (Subsurface > 1e-5) {
color mixed_ss_base_color = SubsurfaceColor * Subsurface + BaseColor * (1.0 - Subsurface);
- BSDF = mixed_ss_base_color * bssrdf_principled(Normal, Subsurface * SubsurfaceRadius, 0.0, SubsurfaceColor, Roughness);
+ BSDF = mixed_ss_base_color * bssrdf("principled", Normal, Subsurface * SubsurfaceRadius, SubsurfaceColor, "roughness", Roughness);
} else {
BSDF = BaseColor * principled_diffuse(Normal, Roughness);
}
diff --git a/intern/cycles/kernel/shaders/node_subsurface_scattering.osl b/intern/cycles/kernel/shaders/node_subsurface_scattering.osl
index 5ba8f34021d..c9983fcd5dd 100644
--- a/intern/cycles/kernel/shaders/node_subsurface_scattering.osl
+++ b/intern/cycles/kernel/shaders/node_subsurface_scattering.osl
@@ -27,10 +27,10 @@ shader node_subsurface_scattering(
output closure color BSSRDF = 0)
{
if (falloff == "gaussian")
- BSSRDF = Color * bssrdf_gaussian(Normal, Scale * Radius, TextureBlur);
+ BSSRDF = Color * bssrdf("gaussian", Normal, Scale * Radius, Color, "texture_blur", TextureBlur);
else if (falloff == "cubic")
- BSSRDF = Color * bssrdf_cubic(Normal, Scale * Radius, TextureBlur, Sharpness);
+ BSSRDF = Color * bssrdf("cubic", Normal, Scale * Radius, Color, "texture_blur", TextureBlur, "sharpness", Sharpness);
else
- BSSRDF = Color * bssrdf_burley(Normal, Scale * Radius, TextureBlur, Color);
+ BSSRDF = Color * bssrdf("burley", Normal, Scale * Radius, Color, "texture_blur", TextureBlur);
}
diff --git a/intern/cycles/kernel/shaders/stdosl.h b/intern/cycles/kernel/shaders/stdosl.h
index c91d2918687..091ade4a60d 100644
--- a/intern/cycles/kernel/shaders/stdosl.h
+++ b/intern/cycles/kernel/shaders/stdosl.h
@@ -549,10 +549,7 @@ closure color principled_sheen(normal N) BUILTIN;
closure color principled_clearcoat(normal N, float clearcoat, float clearcoat_roughness) BUILTIN;
// BSSRDF
-closure color bssrdf_cubic(normal N, vector radius, float texture_blur, float sharpness) BUILTIN;
-closure color bssrdf_gaussian(normal N, vector radius, float texture_blur) BUILTIN;
-closure color bssrdf_burley(normal N, vector radius, float texture_blur, color albedo) BUILTIN;
-closure color bssrdf_principled(normal N, vector radius, float texture_blur, color subsurface_color, float roughness) BUILTIN;
+closure color bssrdf(string method, normal N, vector radius, color albedo) BUILTIN;
// Hair
closure color hair_reflection(normal N, float roughnessu, float roughnessv, vector T, float offset) BUILTIN;
diff --git a/intern/cycles/kernel/split/kernel_split_data_types.h b/intern/cycles/kernel/split/kernel_split_data_types.h
index 5f40fdc9240..56194d9f857 100644
--- a/intern/cycles/kernel/split/kernel_split_data_types.h
+++ b/intern/cycles/kernel/split/kernel_split_data_types.h
@@ -67,10 +67,6 @@ typedef ccl_global struct SplitBranchedState {
uint lcg_state;
LocalIntersection ss_isect;
-
-# ifdef __VOLUME__
- VolumeStack volume_stack[VOLUME_STACK_SIZE];
-# endif /* __VOLUME__ */
#endif /*__SUBSURFACE__ */
int shared_sample_count; /* number of branched samples shared with other threads */
diff --git a/intern/cycles/kernel/split/kernel_subsurface_scatter.h b/intern/cycles/kernel/split/kernel_subsurface_scatter.h
index 38dd1dc5654..f902d000918 100644
--- a/intern/cycles/kernel/split/kernel_subsurface_scatter.h
+++ b/intern/cycles/kernel/split/kernel_subsurface_scatter.h
@@ -61,11 +61,16 @@ ccl_device_noinline bool kernel_split_branched_path_subsurface_indirect_light_it
/* do subsurface scatter step with copy of shader data, this will
* replace the BSSRDF with a diffuse BSDF closure */
for(int j = branched_state->ss_next_sample; j < num_samples; j++) {
+ ccl_global PathState *hit_state = &kernel_split_state.path_state[ray_index];
+ *hit_state = branched_state->path_state;
+ hit_state->rng_hash = bssrdf_rng_hash;
+ path_state_branch(hit_state, j, num_samples);
+
ccl_global LocalIntersection *ss_isect = &branched_state->ss_isect;
float bssrdf_u, bssrdf_v;
path_branched_rng_2D(kg,
bssrdf_rng_hash,
- &branched_state->path_state,
+ hit_state,
j,
num_samples,
PRNG_BSDF_U,
@@ -89,6 +94,8 @@ ccl_device_noinline bool kernel_split_branched_path_subsurface_indirect_light_it
*ss_isect = ss_isect_private;
}
+ hit_state->rng_offset += PRNG_BOUNCE_NUM;
+
#ifdef __VOLUME__
Ray volume_ray = branched_state->ray;
bool need_update_volume_stack =
@@ -107,38 +114,24 @@ ccl_device_noinline bool kernel_split_branched_path_subsurface_indirect_light_it
&ss_isect_private,
hit,
bssrdf_sd,
- &branched_state->path_state,
- branched_state->path_state.flag,
- sc,
- true);
+ hit_state,
+ sc);
*ss_isect = ss_isect_private;
- ccl_global PathState *hit_state = &kernel_split_state.path_state[ray_index];
- *hit_state = branched_state->path_state;
-
- path_state_branch(hit_state, j, num_samples);
-
#ifdef __VOLUME__
if(need_update_volume_stack) {
/* Setup ray from previous surface point to the new one. */
float3 P = ray_offset(bssrdf_sd->P, -bssrdf_sd->Ng);
volume_ray.D = normalize_len(P - volume_ray.P, &volume_ray.t);
- /* this next part is expensive as it does scene intersection so only do once */
- if(branched_state->next_closure == 0 && branched_state->next_sample == 0) {
- for(int k = 0; k < VOLUME_STACK_SIZE; k++) {
- branched_state->volume_stack[k] = hit_state->volume_stack[k];
- }
-
- kernel_volume_stack_update_for_subsurface(kg,
- emission_sd,
- &volume_ray,
- branched_state->volume_stack);
- }
-
for(int k = 0; k < VOLUME_STACK_SIZE; k++) {
- hit_state->volume_stack[k] = branched_state->volume_stack[k];
+ hit_state->volume_stack[k] = branched_state->path_state.volume_stack[k];
}
+
+ kernel_volume_stack_update_for_subsurface(kg,
+ emission_sd,
+ &volume_ray,
+ hit_state->volume_stack);
}
#endif /* __VOLUME__ */
@@ -147,7 +140,7 @@ ccl_device_noinline bool kernel_split_branched_path_subsurface_indirect_light_it
/* direct light */
if(kernel_data.integrator.use_direct_light) {
int all = (kernel_data.integrator.sample_all_lights_direct) ||
- (branched_state->path_state.flag & PATH_RAY_SHADOW_CATCHER);
+ (hit_state->flag & PATH_RAY_SHADOW_CATCHER);
kernel_branched_path_surface_connect_light(kg,
bssrdf_sd,
emission_sd,
@@ -264,7 +257,6 @@ ccl_device void kernel_subsurface_scatter(KernelGlobals *kg)
subsurface_scatter_step(kg,
sd,
state,
- state->flag,
sc,
&lcg_state,
bssrdf_u, bssrdf_v,
diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c
index e89f54349f7..beee9065ece 100644
--- a/source/blender/bmesh/tools/bmesh_bevel.c
+++ b/source/blender/bmesh/tools/bmesh_bevel.c
@@ -1879,7 +1879,7 @@ static void build_boundary(BevelParams *bp, BevVert *bv, bool construct)
}
}
-#if 0
+#ifdef DEBUG_ADJUST
static void print_adjust_stats(BoundVert *vstart)
{
BoundVert *v;
@@ -1921,21 +1921,25 @@ static void print_adjust_stats(BoundVert *vstart)
if (v->adjchain != NULL) {
eright = v->efirst;
eleft = v->adjchain->elast;
- delta = fabs(eright->offset_r - eright->offset_r_spec);
+ delta = eright->offset_r - eright->offset_r_spec;
delta_pct = 100.0 * delta / eright->offset_r_spec;
- printf("e%d r(%f) vs r spec(%f): abs(delta)=%f, delta_pct=%f\n",
+ printf("e%d r(%f) vs r spec(%f): delta=%f, delta_pct=%f\n",
BM_elem_index_get(eright->e), eright->offset_r, eright->offset_r_spec, delta, delta_pct);
spec_residual2 += delta * delta;
+ delta = fabs(delta);
+ delta_pct = fabs(delta_pct);
if (delta > max_spec_r)
max_spec_r = delta;
if (delta_pct > max_spec_r_pct)
max_spec_r_pct = delta_pct;
- delta = fabs(eleft->offset_l - eleft->offset_l_spec);
+ delta = eleft->offset_l - eleft->offset_l_spec;
delta_pct = 100.0 * delta / eright->offset_l_spec;
- printf("e%d l(%f) vs l spec(%f): abs(delta)=%f, delta_pct=%f\n",
+ printf("e%d l(%f) vs l spec(%f): delta=%f, delta_pct=%f\n",
BM_elem_index_get(eright->e), eleft->offset_l, eleft->offset_l_spec, delta, delta_pct);
spec_residual2 += delta * delta;
+ delta = fabs(delta);
+ delta_pct = fabs(delta_pct);
if (delta > max_spec_r)
max_spec_r = delta;
if (delta_pct > max_spec_r_pct)
@@ -1951,6 +1955,15 @@ static void print_adjust_stats(BoundVert *vstart)
}
#endif
+#ifdef FAST_ADJUST_CODE
+/* This code uses a direct solution to the adjustment problem for chains and certain cycles.
+ * It is a two-step approach: first solve for the exact solution of the 'match widths' constraints
+ * using the one degree of freedom that allows for expressing all other widths in terms of that.
+ * And then minimize the spec-matching constraints using the derivative of the least squares
+ * residual in terms of that one degree of freedom.
+ * Unfortunately, the results are in some cases worse than the general least squares solution
+ * for the combined (with weights) problem, so this code is not used.
+ * But keep it here for a while in case peformance issues demand that it be used sometimes. */
static bool adjust_the_cycle_or_chain_fast(BoundVert *vstart, int np, bool iscycle)
{
BoundVert *v;
@@ -2027,6 +2040,7 @@ static bool adjust_the_cycle_or_chain_fast(BoundVert *vstart, int np, bool iscyc
MEM_freeN(g_prod);
return true;
}
+#endif
/* Adjust the offsets for a single cycle or chain.
* For chains and some cycles, a fast solution exists.
@@ -2038,22 +2052,35 @@ static bool adjust_the_cycle_or_chain_fast(BoundVert *vstart, int np, bool iscyc
static void adjust_the_cycle_or_chain(BoundVert *vstart, bool iscycle)
{
BoundVert *v;
- EdgeHalf *eleft, *eright;
+ EdgeHalf *eleft, *eright, *enextleft;
LinearSolver *solver;
double weight, val;
int i, np, nrows, row;
np = 0;
+#ifdef DEBUG_ADJUST
+ printf("\nadjust the %s (with eigen)\n", iscycle ? "cycle" : "chain");
+#endif
v = vstart;
do {
+#ifdef DEBUG_ADJUST
+ eleft = v->elast;
+ eright = v->efirst;
+ printf(" (left=e%d, right=e%d)", BM_elem_index_get(eleft->e), BM_elem_index_get(eright->e));
+#endif
np++;
v = v->adjchain;
} while (v && v != vstart);
+#ifdef DEBUG_ADJUST
+ printf(" -> %d parms\n", np);
+#endif
+#ifdef FAST_ADJUST_CODE
if (adjust_the_cycle_or_chain_fast(vstart, np, iscycle))
return;
+#endif
- nrows = iscycle ? 2 * np : 2 * np - 1;
+ nrows = iscycle ? 3 * np : 3 * np - 3;
solver = EIG_linear_least_squares_solver_new(nrows, np, 1);
@@ -2062,9 +2089,15 @@ static void adjust_the_cycle_or_chain(BoundVert *vstart, bool iscycle)
weight = BEVEL_MATCH_SPEC_WEIGHT; /* sqrt of factor to weight down importance of spec match */
do {
/* except at end of chain, v's indep variable is offset_r of v->efirst */
- if (iscycle || v->adjchain != NULL) {
+ if (iscycle || i < np - 1) {
eright = v->efirst;
eleft = v->elast;
+ enextleft = v->adjchain->elast;
+#ifdef DEBUG_ADJUST
+ printf("p%d: e%d->offset_r = %f\n", i, BM_elem_index_get(eright->e), eright->offset_r);
+ if (iscycle || v != vstart)
+ printf(" dependent: e%d->offset_l = %f * p%d\n", BM_elem_index_get(eleft->e), v->sinratio, i);
+#endif
/* residue i: width difference between eright and eleft of next */
EIG_linear_solver_matrix_add(solver, i, i, 1.0);
@@ -2073,53 +2106,87 @@ static void adjust_the_cycle_or_chain(BoundVert *vstart, bool iscycle)
EIG_linear_solver_matrix_add(solver, i > 0 ? i - 1 : np - 1, i, -v->sinratio);
}
else {
- if (i > 0)
+ if (i > 0) {
EIG_linear_solver_matrix_add(solver, i - 1, i, -v->sinratio);
+ }
}
- /* residue np + i (if cycle) else np - 1 + i:
+ /* residue np + 2*i (if cycle) else np - 1 + 2*i:
* right offset for parm i matches its spec; weighted */
- row = iscycle ? np + i : np - 1 + i;
+ row = iscycle ? np + 2 * i : np - 1 + 2 * i;
EIG_linear_solver_matrix_add(solver, row, i, weight);
EIG_linear_solver_right_hand_side_add(solver, 0, row, weight * eright->offset_r);
+#ifdef DEBUG_ADJUST
+ printf("b[%d]=%f * %f, for e%d->offset_r\n", row, weight, eright->offset_r, BM_elem_index_get(eright->e));
+#endif
+
+ /* residue np + 2*i + 1 (if cycle) else np - 1 + 2*i + 1:
+ * left offset for parm i matches its spec; weighted */
+ row = row + 1;
+ EIG_linear_solver_matrix_add(solver, row, (i == np - 1) ? 0 : i + 1, weight * v->adjchain->sinratio);
+ EIG_linear_solver_right_hand_side_add(solver, 0, row, weight * enextleft->offset_l);
+#ifdef DEBUG_ADJUST
+ printf("b[%d]=%f * %f, for e%d->offset_l\n", row, weight, enextleft->offset_l,
+ BM_elem_index_get(enextleft->e));
+#endif
}
else {
/* not a cycle, and last of chain */
eleft = v->elast;
+#ifdef DEBUG_ADJUST
+ printf("p%d: e%d->offset_l = %f\n", i, BM_elem_index_get(eleft->e), eleft->offset_l);
+#endif
/* second part of residue i for last i */
EIG_linear_solver_matrix_add(solver, i - 1, i, -1.0);
- /* residue 2 * np -2 : last spec match residue is for left offset of final parm */
- row = 2 * np - 2;
- EIG_linear_solver_matrix_add(solver, row, i, weight);
- EIG_linear_solver_right_hand_side_add(solver, 0, row, weight * eleft->offset_l);
}
i++;
v = v->adjchain;
} while (v && v != vstart);
EIG_linear_solver_solve(solver);
+#ifdef DEBUG_ADJUST
+ /* Note: this print only works after solve, but by that time b has been cleared */
+ EIG_linear_solver_print_matrix(solver);
+ printf("\nSolution:\n");
+ for (i = 0; i < np; i++)
+ printf("p%d = %f\n", i, EIG_linear_solver_variable_get(solver, 0, i));
+#endif
/* Use the solution to set new widths */
v = vstart;
i = 0;
do {
val = EIG_linear_solver_variable_get(solver, 0, i);
- if (iscycle || v->adjchain != NULL) {
+ if (iscycle || i < np - 1) {
eright = v->efirst;
eleft = v->elast;
eright->offset_r = (float)val;
+#ifdef DEBUG_ADJUST
+ printf("e%d->offset_r = %f\n", BM_elem_index_get(eright->e), eright->offset_r);
+#endif
if (iscycle || v != vstart) {
eleft->offset_l = (float)(v->sinratio * val);
+#ifdef DEBUG_ADJUST
+ printf("e%d->offset_l = %f\n", BM_elem_index_get(eleft->e), eleft->offset_l);
+#endif
}
}
else {
/* not a cycle, and last of chain */
eleft = v->elast;
eleft->offset_l = (float)val;
+#ifdef DEBUG_ADJUST
+ printf("e%d->offset_l = %f\n", BM_elem_index_get(eleft->e), eleft->offset_l);
+#endif
}
i++;
v = v->adjchain;
} while (v && v != vstart);
+#ifdef DEBUG_ADJUST
+ print_adjust_stats(vstart);
+ EIG_linear_solver_print_matrix(solver);
+#endif
+
EIG_linear_solver_delete(solver);
}
diff --git a/tests/python/CMakeLists.txt b/tests/python/CMakeLists.txt
index 9f1de64c2e9..537a3e3a07e 100644
--- a/tests/python/CMakeLists.txt
+++ b/tests/python/CMakeLists.txt
@@ -547,6 +547,7 @@ if(WITH_CYCLES)
add_cycles_render_test(shader)
add_cycles_render_test(shader_tangent)
add_cycles_render_test(shadow_catcher)
+ add_cycles_render_test(sss)
add_cycles_render_test(texture_space)
add_cycles_render_test(volume)
else()